X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FFlowProgrammerService.java;h=e2fa8d5f1e4f89e0980da755c340d4585a78c379;hb=edf5bfcee83c750853253ccfd991ba7000f5f65b;hp=88b75b196dcec8f370a6119130d21f3578aa89ab;hpb=d9490279e1ed8cc23c5e4ed0366f8ce93313fc51;p=controller.git diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java index 88b75b196d..e2fa8d5f1e 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java @@ -36,6 +36,7 @@ import org.opendaylight.controller.sal.flowprogrammer.Flow; import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService; import org.opendaylight.controller.sal.match.Match; import org.opendaylight.controller.sal.match.MatchType; +import org.opendaylight.controller.sal.utils.EtherTypes; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.NodeCreator; @@ -225,6 +226,11 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, action, "Invalid node type")); } + Status status = validateFlow(flow); + if (!status.isSuccess()) { + return status; + } + if (controller != null) { ISwitch sw = controller.getSwitch((Long) node.getID()); if (sw != null) { @@ -256,12 +262,52 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, "Internal plugin error")); } + /* + * Method which runs openflow 1.0 specific validation on the requested flow + * This validation is needed because the openflow switch will silently accept + * the request and install only the applicable match fields + */ + private Status validateFlow(Flow flow) { + Match m = flow.getMatch(); + boolean isIPEthertypeSet = m.isPresent(MatchType.DL_TYPE) + && (m.getField(MatchType.DL_TYPE).getValue().equals(EtherTypes.IPv4.shortValue()) || m + .getField(MatchType.DL_TYPE).getValue().equals(EtherTypes.IPv6.shortValue())); + + // network address check + if ((m.isPresent(MatchType.NW_SRC) || m.isPresent(MatchType.NW_DST)) && !isIPEthertypeSet) { + return new Status(StatusCode.NOTACCEPTABLE, + "The match on network source or destination address cannot be accepted if the match " + + "on proper ethertype is missing"); + } + + // transport protocol check + if (m.isPresent(MatchType.NW_PROTO) && !isIPEthertypeSet) { + return new Status(StatusCode.NOTACCEPTABLE, + "The match on network protocol cannot be accepted if the match on proper ethertype is missing"); + } + + // transport ports check + if ((m.isPresent(MatchType.TP_SRC) || m.isPresent(MatchType.TP_DST)) + && (!isIPEthertypeSet || m.isAny(MatchType.NW_PROTO))) { + return new Status( + StatusCode.NOTACCEPTABLE, + "The match on transport source or destination port cannot be accepted if the match on network protocol and match on IP ethertype are missing"); + } + return new Status(StatusCode.SUCCESS); + } + private Status modifyFlowInternal(Node node, Flow oldFlow, Flow newFlow, long rid) { String action = "modify"; if (!node.getType().equals(NodeIDType.OPENFLOW)) { return new Status(StatusCode.NOTACCEPTABLE, errorString("send", action, "Invalid node type")); } + + Status status = validateFlow(newFlow); + if (!status.isSuccess()) { + return status; + } + if (controller != null) { ISwitch sw = controller.getSwitch((Long) node.getID()); if (sw != null) { @@ -415,7 +461,7 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, */ if (inPort == null || container.equals(GlobalConstants.DEFAULT.toString()) - || this.containerToNc.get(container).contains(inPort)) { + || (containerToNc.containsKey(container) && containerToNc.get(container).contains(inPort))) { notifier.flowRemoved(node, flow); } } @@ -448,7 +494,7 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, for (Map.Entry containerNotifier : flowProgrammerNotifiers .entrySet()) { IFlowProgrammerNotifier notifier = containerNotifier.getValue(); - notifier.flowErrorReported(node, rid, errorMsg); + notifier.flowErrorReported(node, rid, Utils.getOFErrorString(errorMsg)); } }