import java.util.ArrayList;
import java.util.List;
+import org.opendaylight.openflowplugin.openflow.md.OFConstants;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flowflag.FlowFlagReactor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
+import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.clear.actions._case.ClearActions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MeterIdInstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MatchTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Objects;
+
/**
* Utility class for converting a MD-SAL Flow into the OF flow mod
*/
private static final Logger logger = LoggerFactory.getLogger(FlowConvertor.class);
// Default values for when things are null
- private static final BigInteger DEFAULT_COOKIE = BigInteger.ZERO; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final BigInteger DEFAULT_COOKIE_MASK = BigInteger.ZERO; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final TableId DEFAULT_TABLE_ID = new TableId(new Long(0)); // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final Integer DEFAULT_IDLE_TIMEOUT = new Integer(5*60); // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final Integer DEFAULT_HARD_TIMEOUT = new Integer(10*60); // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16); // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final Long DEFAULT_BUFFER_ID = Long.parseLong("ffffffff", 16); // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
+ private static final BigInteger DEFAULT_COOKIE = BigInteger.ZERO;
+ private static final BigInteger DEFAULT_COOKIE_MASK = BigInteger.ZERO;
+ private static final TableId DEFAULT_TABLE_ID = new TableId(0L);
+ private static final Integer DEFAULT_IDLE_TIMEOUT = 5 * 60;
+ private static final Integer DEFAULT_HARD_TIMEOUT = 10 * 60;
+ private static final Integer DEFAULT_PRIORITY = Integer.parseInt("8000", 16);
+ private static final Long DEFAULT_BUFFER_ID = Long.parseLong("ffffffff", 16);
private static final Long OFPP_ANY = Long.parseLong("ffffffff", 16);
- private static final Long DEFAULT_OUT_PORT = OFPP_ANY; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
+ private static final Long DEFAULT_OUT_PORT = OFPP_ANY;
private static final Long OFPG_ANY = Long.parseLong("ffffffff", 16);
- private static final Long DEFAULT_OUT_GROUP = OFPG_ANY; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final boolean DEFAULT_OFPFF_FLOW_REM = true; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final boolean DEFAULT_OFPFF_RESET_COUNTS = false; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false; // TODO: Someone check me, I have no idea if this is a good default - eaw@cisco.com
- private static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
-
- public static FlowModInput toFlowModInput(Flow flow, short version) {
+ private static final Long DEFAULT_OUT_GROUP = OFPG_ANY;
+ /** flow flag: remove */
+ public static final boolean DEFAULT_OFPFF_FLOW_REM = true;
+ /** flow flag: check overlap */
+ public static final boolean DEFAULT_OFPFF_CHECK_OVERLAP = false;
+ /** flow flag: reset counts */
+ public static final boolean DEFAULT_OFPFF_RESET_COUNTS = false;
+ /** flow flag: don't keep track of packet counts */
+ public static final boolean DEFAULT_OFPFF_NO_PKT_COUNTS = false;
+ /** flow flag: don't keep track of byte counts */
+ public static final boolean DEFAULT_OFPFF_NO_BYT_COUNTS = false;
+ /** flow flag: emergency [OFP-1.0] */
+ public static final boolean DEFAULT_OFPFF_EMERGENCY = false;
+ /** OxmMatch type */
+ public static final Class<? extends MatchTypeBase> DEFAULT_MATCH_TYPE = OxmMatchType.class;
+ /** default match entries - empty */
+ public static final List<MatchEntries> DEFAULT_MATCH_ENTRIES = new ArrayList<MatchEntries>();
+
+ public static FlowModInputBuilder toFlowModInput(Flow flow, short version,BigInteger datapathid) {
FlowModInputBuilder flowMod = new FlowModInputBuilder();
- if(flow.getCookie() != null){
- flowMod.setCookie(flow.getCookie());
+ if (flow.getCookie() != null) {
+ flowMod.setCookie(flow.getCookie().getValue());
} else {
flowMod.setCookie(DEFAULT_COOKIE);
}
if (flow.getCookieMask() != null) {
- flowMod.setCookieMask(new BigInteger(flow.getCookieMask().toString()));
+ flowMod.setCookieMask(flow.getCookieMask().getValue());
} else {
flowMod.setCookieMask(DEFAULT_COOKIE_MASK);
}
if (flow instanceof AddFlowInput) {
flowMod.setCommand(FlowModCommand.OFPFCADD);
} else if (flow instanceof RemoveFlowInput) {
- if (flow.isStrict() != null && flow.isStrict()) {
+ if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
flowMod.setCommand(FlowModCommand.OFPFCDELETESTRICT);
} else {
flowMod.setCommand(FlowModCommand.OFPFCDELETE);
}
- } else if (flow instanceof UpdateFlowInput) {
- if (flow.isStrict() != null && flow.isStrict()) {
+ } else if (flow instanceof UpdatedFlow) {
+ if (Objects.firstNonNull(flow.isStrict(), Boolean.FALSE)) {
flowMod.setCommand(FlowModCommand.OFPFCMODIFYSTRICT);
} else {
flowMod.setCommand(FlowModCommand.OFPFCMODIFY);
}
}
- if(flow.getIdleTimeout() != null) {
+ if (flow.getIdleTimeout() != null) {
flowMod.setIdleTimeout(flow.getIdleTimeout());
} else {
flowMod.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
}
- if(flow.getHardTimeout() != null) {
+ if (flow.getHardTimeout() != null) {
flowMod.setHardTimeout(flow.getHardTimeout());
} else {
flowMod.setHardTimeout(DEFAULT_HARD_TIMEOUT);
}
- if(flow.getPriority() != null) {
+ if (flow.getPriority() != null) {
flowMod.setPriority(flow.getPriority());
} else {
flowMod.setPriority(DEFAULT_PRIORITY);
}
- if(flow.getBufferId() != null ) {
+ if (flow.getBufferId() != null) {
flowMod.setBufferId(flow.getBufferId());
} else {
flowMod.setBufferId(DEFAULT_BUFFER_ID);
} else {
flowMod.setOutPort(new PortNumber(DEFAULT_OUT_PORT));
}
- if(flow.getOutGroup() != null) {
+ if (flow.getOutGroup() != null) {
flowMod.setOutGroup(flow.getOutGroup());
} else {
flowMod.setOutGroup(DEFAULT_OUT_GROUP);
}
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags flowModFlags = flow.getFlags();
- org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags ofFlowModFlags = null;
- if (flowModFlags != null) {
- ofFlowModFlags = new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags(
- flowModFlags.isCHECKOVERLAP(), flowModFlags.isNOBYTCOUNTS(), flowModFlags.isNOPKTCOUNTS(),
- flowModFlags.isRESETCOUNTS(), flowModFlags.isSENDFLOWREM());
- } else {
- ofFlowModFlags = new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags(
- DEFAULT_OFPFF_CHECK_OVERLAP,DEFAULT_OFPFF_NO_BYT_COUNTS,DEFAULT_OFPFF_NO_PKT_COUNTS,
- DEFAULT_OFPFF_RESET_COUNTS,DEFAULT_OFPFF_FLOW_REM);
- }
- flowMod.setFlags(ofFlowModFlags);
+
+ // convert and inject flowFlags
+ FlowFlagReactor.getInstance().convert(flow.getFlags(), version, flowMod,datapathid);
- if (flow.getMatch() != null) {
- MatchBuilder matchBuilder = new MatchBuilder();
- matchBuilder.setMatchEntries(MatchConvertor.toMatch(flow.getMatch()));
- matchBuilder.setType(DEFAULT_MATCH_TYPE);
- flowMod.setMatch(matchBuilder.build());
- }
+ // convert and inject match
+ MatchReactor.getInstance().convert(flow.getMatch(), version, flowMod,datapathid);
if (flow.getInstructions() != null) {
- flowMod.setInstructions(toInstructions(flow.getInstructions(), version));
+ flowMod.setInstruction(toInstructions(flow.getInstructions(), version,datapathid));
+ flowMod.setAction(getActions(flow.getInstructions(), version,datapathid));
}
flowMod.setVersion(version);
- return flowMod.build();
+
+ return flowMod;
}
- private static List<Instructions> toInstructions(
+ private static List<Instruction> toInstructions(
org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
- short version) {
- List<Instructions> instructionsList = new ArrayList<>();
+ short version,BigInteger datapathid) {
+ List<Instruction> instructionsList = new ArrayList<>();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
.getInstruction()) {
- InstructionsBuilder instructionBuilder = new InstructionsBuilder();
+ InstructionBuilder instructionBuilder = new InstructionBuilder();
org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
.getInstruction();
- if (curInstruction instanceof GoToTable) {
- GoToTable goToTable = (GoToTable) curInstruction;
+ if (curInstruction instanceof GoToTableCase) {
+ GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
+ GoToTable goToTable = goToTablecase.getGoToTable();
instructionBuilder
.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable.class);
TableIdInstructionBuilder tableBuilder = new TableIdInstructionBuilder();
instructionsList.add(instructionBuilder.build());
}
- else if (curInstruction instanceof WriteMetadata) {
- WriteMetadata writeMetadata = (WriteMetadata) curInstruction;
+ else if (curInstruction instanceof WriteMetadataCase) {
+ WriteMetadataCase writeMetadatacase = (WriteMetadataCase) curInstruction;
+ WriteMetadata writeMetadata = writeMetadatacase.getWriteMetadata();
instructionBuilder
.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata.class);
MetadataInstructionBuilder metadataBuilder = new MetadataInstructionBuilder();
- metadataBuilder.setMetadata(MatchConvertor.convertBigIntegerTo64Bit(writeMetadata.getMetadata()));
+ metadataBuilder.setMetadata(ByteUtil.convertBigIntegerToNBytes(writeMetadata.getMetadata(),
+ OFConstants.SIZE_OF_LONG_IN_BYTES));
metadataBuilder
- .setMetadataMask(MatchConvertor.convertBigIntegerTo64Bit(writeMetadata.getMetadataMask()));
+ .setMetadataMask(ByteUtil.convertBigIntegerToNBytes(writeMetadata.getMetadataMask(),
+ OFConstants.SIZE_OF_LONG_IN_BYTES));
instructionBuilder.addAugmentation(MetadataInstruction.class, metadataBuilder.build());
instructionsList.add(instructionBuilder.build());
}
- else if (curInstruction instanceof WriteActions) {
- WriteActions writeActions = (WriteActions) curInstruction;
+ else if (curInstruction instanceof WriteActionsCase) {
+ WriteActionsCase writeActionscase = (WriteActionsCase) curInstruction;
+ WriteActions writeActions = writeActionscase.getWriteActions();
instructionBuilder
.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions.class);
ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
- actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(writeActions.getAction(),
- version));
+ actionsInstructionBuilder.setAction(ActionConvertor.getActions(writeActions.getAction(),
+ version,datapathid));
instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
instructionsList.add(instructionBuilder.build());
}
- else if (curInstruction instanceof ApplyActions) {
- ApplyActions applyActions = (ApplyActions) curInstruction;
+ else if (curInstruction instanceof ApplyActionsCase) {
+ ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
+ ApplyActions applyActions = applyActionscase.getApplyActions();
instructionBuilder
.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions.class);
ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
- actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(applyActions.getAction(),
- version));
+ actionsInstructionBuilder.setAction(ActionConvertor.getActions(applyActions.getAction(),
+ version,datapathid));
instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
instructionsList.add(instructionBuilder.build());
}
- else if (curInstruction instanceof ClearActions) {
- ClearActions clearActions = (ClearActions) curInstruction;
+ else if (curInstruction instanceof ClearActionsCase) {
+ ClearActionsCase clearActionscase = (ClearActionsCase) curInstruction;
+ ClearActions clearActions = clearActionscase.getClearActions();
instructionBuilder
.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions.class);
- ActionsInstructionBuilder actionsInstructionBuilder = new ActionsInstructionBuilder();
- actionsInstructionBuilder.setActionsList(ActionConvertor.getActionList(clearActions.getAction(),
- version));
- instructionBuilder.addAugmentation(ActionsInstruction.class, actionsInstructionBuilder.build());
instructionsList.add(instructionBuilder.build());
}
- else if (curInstruction instanceof Meter) {
- Meter meter = (Meter) curInstruction;
+ else if (curInstruction instanceof MeterCase) {
+ MeterCase metercase = (MeterCase) curInstruction;
+ Meter meter = metercase.getMeter();
instructionBuilder
.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter.class);
MeterIdInstructionBuilder meterBuilder = new MeterIdInstructionBuilder();
}
return instructionsList;
}
-}
\ No newline at end of file
+
+ private static List<Action> getActions(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions instructions,
+ short version,BigInteger datapathid) {
+
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction instruction : instructions
+ .getInstruction()) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
+ .getInstruction();
+
+ if (curInstruction instanceof ApplyActionsCase) {
+ ApplyActionsCase applyActionscase = (ApplyActionsCase) curInstruction;
+ ApplyActions applyActions = applyActionscase.getApplyActions();
+ return ActionConvertor.getActions(applyActions.getAction(), version,datapathid);
+ }
+
+ }
+ return null;
+ }
+}