From f844efbb0b6fec5c32106a4573e0fb10bb2eedee Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Thu, 5 Dec 2013 01:25:26 -0800 Subject: [PATCH] Adding of specific flow validation in of plugin - An of 1.0 switch silently accepts a flowmod which match does not have proper hierarchy of fields set. It installs the flow discarding the incorrect fields. This would cause inconsistency between flows in hw and flows in sw. The application needs to be notified that the flow would not be accepted as is by the openflow switch. Change-Id: If70a642f2835147856d3517ad82faef3e9bb1e2c Signed-off-by: Alessandro Boch --- .../internal/FlowProgrammerService.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) 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 f26bcf718c..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 @@ -38,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; @@ -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(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) { -- 2.36.6