package net.floodlightcontroller.util; import java.util.Collections; import java.util.List; import net.floodlightcontroller.core.IOFSwitch; import org.projectfloodlight.openflow.protocol.OFFactories; import org.projectfloodlight.openflow.protocol.OFFlowAdd; import org.projectfloodlight.openflow.protocol.OFFlowDelete; import org.projectfloodlight.openflow.protocol.OFFlowDeleteStrict; import org.projectfloodlight.openflow.protocol.OFFlowMod; import org.projectfloodlight.openflow.protocol.OFFlowModify; import org.projectfloodlight.openflow.protocol.OFFlowModifyStrict; import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.protocol.action.OFAction; import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; /** * Convert an OFFlowMod to a specific OFFlowMod-OFFlowModCommand. * These function as setCommand(OFFlowModCommand) methods for an OFFlowMod. * Used initially in the static flow pusher, but will likely find merit elsewhere. * * Other useful FlowMod utility functions and constants are also included. * * @author Ryan Izard <ryan.izard@bigswitch.com, rizard@g.clemson.edu> */ public class FlowModUtils { public static final int INFINITE_TIMEOUT = 0; public static final int PRIORITY_MAX = 32768; public static final int PRIORITY_VERY_HIGH = 28672; public static final int PRIORITY_HIGH = 24576; public static final int PRIORITY_MED_HIGH = 20480; public static final int PRIORITY_MED = 16384; public static final int PRIORITY_MED_LOW = 12288; public static final int PRIORITY_LOW = 8192; public static final int PRIORITY_VERY_LOW = 4096; public static final int PRIORITY_MIN = 0; public static OFFlowAdd toFlowAdd(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowAdd.Builder b = OFFactories.getFactory(version).buildFlowAdd(); if (!(fm instanceof OFFlowDelete) && !(fm instanceof OFFlowDeleteStrict)) { b.setActions(fm.getActions()); } if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } } public static OFFlowDelete toFlowDelete(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowDelete.Builder b = OFFactories.getFactory(version).buildFlowDelete(); /* ignore actions */ if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } } public static OFFlowDeleteStrict toFlowDeleteStrict(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowDeleteStrict.Builder b = OFFactories.getFactory(version).buildFlowDeleteStrict(); /* ignore actions */ if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } } public static OFFlowModify toFlowModify(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowModify.Builder b = OFFactories.getFactory(version).buildFlowModify(); if (!(fm instanceof OFFlowDelete) && !(fm instanceof OFFlowDeleteStrict)) { b.setActions(fm.getActions()); } if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } } public static OFFlowModifyStrict toFlowModifyStrict(OFFlowMod fm) { OFVersion version = fm.getVersion(); OFFlowModifyStrict.Builder b = OFFactories.getFactory(version).buildFlowModifyStrict(); if (!(fm instanceof OFFlowDelete) && !(fm instanceof OFFlowDeleteStrict)) { b.setActions(fm.getActions()); } if (b.getVersion().compareTo(OFVersion.OF_10) == 0) { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) // cookie-mask not supported .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) // instructions not supported .setMatch(fm.getMatch()) // out-group not supported .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) // table-id not supported .setXid(fm.getXid()) .build(); } else { return b.setBufferId(fm.getBufferId()) .setCookie(fm.getCookie()) .setCookieMask(fm.getCookieMask()) // added in OF1.1 .setFlags(fm.getFlags()) .setHardTimeout(fm.getHardTimeout()) .setIdleTimeout(fm.getIdleTimeout()) .setInstructions(fm.getInstructions()) // added in OF1.1 .setMatch(fm.getMatch()) .setOutGroup(fm.getOutGroup()) // added in OF1.1 .setOutPort(fm.getOutPort()) .setPriority(fm.getPriority()) .setTableId(fm.getTableId()) .setXid(fm.getXid()) .build(); } } /** * Sets the actions in fmb according to the sw version. * * @param fmb the FlowMod Builder that is being built * @param actions the actions to set * @param sw the switch that will receive the FlowMod */ public static void setActions(OFFlowMod.Builder fmb, List<OFAction> actions, IOFSwitch sw) { if (sw.getOFFactory().getVersion().compareTo(OFVersion.OF_11) >= 0) { // Instructions are used starting in OF 1.1 fmb.setInstructions(Collections.singletonList((OFInstruction) sw .getOFFactory().instructions().applyActions(actions))); } else { // OF 1.0 only supports actions fmb.setActions(actions); } } }