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=1a67c4c93f1e620eb8b4521124803b6de062696d;hb=bb1a64b9181b790bdabc4a0861e8e49d8d9a8e1e;hp=c55a88cd3f0224cc587bc01e632e742405cc34f1;hpb=d4b6addab23cf24f20cd7969a7f1d800fda2bac1;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 c55a88cd3f..1a67c4c93f 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 @@ -25,6 +25,7 @@ import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageListene import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; import org.opendaylight.controller.sal.connection.IPluginOutConnectionService; import org.opendaylight.controller.sal.core.ContainerFlow; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.Node.NodeIDType; @@ -37,6 +38,7 @@ import org.opendaylight.controller.sal.match.Match; import org.opendaylight.controller.sal.match.MatchType; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.HexEncode; +import org.opendaylight.controller.sal.utils.IPProtocols; import org.opendaylight.controller.sal.utils.NodeCreator; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; @@ -58,7 +60,7 @@ import org.slf4j.LoggerFactory; */ public class FlowProgrammerService implements IPluginInFlowProgrammerService, IMessageListener, IContainerListener, IInventoryShimExternalListener, - CommandProvider { + CommandProvider, IContainerAware { private static final Logger log = LoggerFactory .getLogger(FlowProgrammerService.class); private IController controller; @@ -224,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) { @@ -255,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(IPProtocols.IPV4.byteValue()) || m + .getField(MatchType.DL_TYPE).getValue().equals(IPProtocols.IPV6.byteValue())); + + // 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) { @@ -414,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); } } @@ -447,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)); } } @@ -465,8 +512,6 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, @Override public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType type) { - Set target = null; - switch (type) { case ADDED: if (!containerToNc.containsKey(containerName)) { @@ -477,7 +522,7 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, case CHANGED: break; case REMOVED: - target = containerToNc.get(containerName); + Set target = containerToNc.get(containerName); if (target != null) { target.remove(p); } @@ -800,4 +845,14 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, ci.println("Max num of async messages sent prior to the Barrier message is " + barrierMessagePriorCount); } + + @Override + public void containerCreate(String containerName) { + // do nothing + } + + @Override + public void containerDestroy(String containerName) { + containerToNc.remove(containerName); + } }