From 91d7e02667138a10df0dc5666cf177375f2ff4c4 Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Mon, 24 Feb 2014 18:03:34 -0800 Subject: [PATCH] FlowConfig to only run syntactic validation - The validate function of FlowConfig class should only run syntactic validation The opearational validation like input/output/enqueue port presence, flood action on non default container check, etc. should be run only at installation time. Also this validation should be run for all the flow installation requests either they come from static flow config or from Flow Entry install/modify request coming from other bundles. - With the above change at controller restart, static flow configurations which were valid at controller stop but no longer after reboot (for ex. switch sdn enabled ports have changed) will still show on the Flow GUI as non installed, and their toggling with fail with proper message. Change-Id: I49d97af49d58102e51a3c8c12db915b60bcb6f4b Signed-off-by: Alessandro Boch --- .../forwardingrulesmanager/FlowConfig.java | 148 ++---------------- .../forwardingrulesmanager/frmTest.java | 110 ++++++------- .../internal/ForwardingRulesManager.java | 80 +++++++++- 3 files changed, 148 insertions(+), 190 deletions(-) diff --git a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java index c56eb60a6b..3ad08ca207 100644 --- a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java +++ b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java @@ -8,6 +8,19 @@ package org.opendaylight.controller.forwardingrulesmanager; +import java.io.Serializable; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import org.opendaylight.controller.configuration.ConfigurationObject; import org.opendaylight.controller.sal.action.Action; import org.opendaylight.controller.sal.action.ActionType; @@ -30,38 +43,19 @@ import org.opendaylight.controller.sal.action.SetTpSrc; import org.opendaylight.controller.sal.action.SetVlanId; import org.opendaylight.controller.sal.action.SetVlanPcp; import org.opendaylight.controller.sal.action.SwPath; -import org.opendaylight.controller.sal.core.ContainerFlow; -import org.opendaylight.controller.sal.core.IContainer; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.flowprogrammer.Flow; 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.NetUtils; -import org.opendaylight.controller.sal.utils.NodeConnectorCreator; -import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; -import org.opendaylight.controller.switchmanager.ISwitchManager; -import org.opendaylight.controller.switchmanager.Switch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.io.Serializable; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * Configuration Java Object which represents a flow configuration information * for Forwarding Rules Manager. @@ -608,15 +602,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable { return true; } - public boolean isPortValid(Switch sw, String port) { - if (sw == null) { - log.debug("switch info is not available. Skip checking if port is part of a switch or not."); - return true; - } - NodeConnector nc = NodeConnectorCreator.createNodeConnector(port, sw.getNode()); - return sw.getNodeConnectors().contains(nc); - } - public boolean isVlanIdValid(String vlanId) { int vlan = Integer.decode(vlanId); return ((vlan >= 0) && (vlan < 4096)); @@ -647,45 +632,11 @@ public class FlowConfig extends ConfigurationObject implements Serializable { return (proto != null); } - private Status conflictWithContainerFlow(IContainer container) { - // Return true if it's default container - if (container.getName().equals(GlobalConstants.DEFAULT.toString())) { - return new Status(StatusCode.SUCCESS); - } - - // No container flow = no conflict - List cFlowList = container.getContainerFlows(); - if (((cFlowList == null)) || cFlowList.isEmpty()) { - return new Status(StatusCode.SUCCESS); - } - - // Check against each container's flow - Flow flow = this.getFlow(); - - // Configuration is rejected if it conflicts with _all_ the container - // flows - for (ContainerFlow cFlow : cFlowList) { - if (cFlow.allowsFlow(flow)) { - log.trace("Config is congruent with at least one container flow"); - return new Status(StatusCode.SUCCESS); - } - } - String msg = "Flow Config conflicts with all existing container flows"; - log.trace(msg); - - return new Status(StatusCode.BADREQUEST, msg); - } - - public Status validate(IContainer container) { + public Status validate() { EtherIPType etype = EtherIPType.ANY; EtherIPType ipsrctype = EtherIPType.ANY; EtherIPType ipdsttype = EtherIPType.ANY; - String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container.getName(); - ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, - this); - - Switch sw = null; try { // Flow name cannot be internal flow signature if (!isValidResourceName(name) || isInternalFlow()) { @@ -696,20 +647,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable { return new Status(StatusCode.BADREQUEST, "Node is null"); } - if (switchManager != null) { - for (Switch device : switchManager.getNetworkDevices()) { - if (device.getNode().equals(node)) { - sw = device; - break; - } - } - if (sw == null) { - return new Status(StatusCode.BADREQUEST, String.format("Node %s not found", node)); - } - } else { - log.debug("switchmanager is not set yet"); - } - if (priority != null) { if (Integer.decode(priority) < 0 || (Integer.decode(priority) > 65535)) { return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535", @@ -722,14 +659,8 @@ public class FlowConfig extends ConfigurationObject implements Serializable { Long.decode(cookie); } - if (ingressPort != null) { - if (!isPortValid(sw, ingressPort)) { - String msg = String.format("Ingress port %s is not valid for the Switch", ingressPort); - if (!containerName.equals(GlobalConstants.DEFAULT.toString())) { - msg += " in Container " + containerName; - } - return new Status(StatusCode.BADREQUEST, msg); - } + if (ingressPort != null && ingressPort.isEmpty()) { + return new Status(StatusCode.BADREQUEST, "Invalid ingress port"); } if ((vlanId != null) && !isVlanIdValid(vlanId)) { @@ -832,48 +763,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable { return new Status(StatusCode.BADREQUEST, "Actions value is null or empty"); } for (String actiongrp : actions) { - // check output ports - sstr = Pattern.compile("OUTPUT=(.*)").matcher(actiongrp); - if (sstr.matches()) { - for (String t : sstr.group(1).split(",")) { - if (t != null) { - if (!isPortValid(sw, t)) { - String msg = String.format("Output port %s is not valid for this switch", t); - if (!containerName.equals(GlobalConstants.DEFAULT.toString())) { - msg += " in Container " + containerName; - } - return new Status(StatusCode.BADREQUEST, msg); - } - } - } - continue; - } - // check enqueue - sstr = Pattern.compile("ENQUEUE=(.*)").matcher(actiongrp); - if (sstr.matches()) { - for (String t : sstr.group(1).split(",")) { - if (t != null) { - String port = t.split(":")[0]; - if (!isPortValid(sw, port)) { - String msg = String.format("Output port %d is not valid for this switch", port); - if (!containerName.equals(GlobalConstants.DEFAULT.toString())) { - msg += " in Container " + containerName; - } - return new Status(StatusCode.BADREQUEST, msg); - } - } - } - continue; - } - // Check src IP - sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp); - if (sstr.matches()) { - if (!containerName.equals(GlobalConstants.DEFAULT.toString())) { - return new Status(StatusCode.BADREQUEST, String.format( - "flood is not allowed in container %s", containerName)); - } - continue; - } // Check src IP sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp); if (sstr.matches()) { @@ -965,11 +854,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable { continue; } } - // Check against the container flow - Status status; - if (!containerName.equals(GlobalConstants.DEFAULT.toString()) && !(status = conflictWithContainerFlow(container)).isSuccess()) { - return status; - } } catch (NumberFormatException e) { return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage())); } diff --git a/opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java b/opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java index 48e1f07716..685ccdb7c4 100644 --- a/opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java +++ b/opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java @@ -257,7 +257,7 @@ public class frmTest { FlowConfig flowConfig = new FlowConfig(); Assert.assertFalse(flowConfig.isInternalFlow()); flowConfig.setName("__Internal__"); - Status status = flowConfig.validate(null); + Status status = flowConfig.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("name")); Assert.assertTrue(flowConfig.isInternalFlow()); @@ -509,228 +509,228 @@ public class frmTest { @Test public void testValid() throws UnknownHostException { FlowConfig fc2 = createSampleFlowConfig(); - Assert.assertTrue(fc2.validate(null).isSuccess()); + Assert.assertTrue(fc2.validate().isSuccess()); FlowConfig fc = new FlowConfig(); - Status status = fc.validate(null); + Status status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Invalid name")); fc.setName("Config"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Node is null")); fc.setNode(Node.fromString(Node.NodeIDType.OPENFLOW, "1")); - Assert.assertFalse(fc.validate(null).isSuccess()); + Assert.assertFalse(fc.validate().isSuccess()); List actions = new ArrayList(); fc.setActions(actions); - Assert.assertFalse(fc.validate(null).isSuccess()); + Assert.assertFalse(fc.validate().isSuccess()); actions.add("OUTPUT=2"); fc.setActions(actions); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setPriority("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 65535")); fc.setPriority("100000"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 65535")); fc.setPriority("2000"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setCookie("100"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setIngressPort("100"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setVlanId(("-1")); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 4095")); fc.setVlanId("5000"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 4095")); fc.setVlanId("100"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setVlanPriority("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 7")); fc.setVlanPriority("9"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 7")); fc.setVlanPriority("5"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setEtherType("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Ethernet type")); fc.setEtherType("0xfffff"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Ethernet type")); fc.setEtherType("0x800"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setTosBits("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("IP ToS bits")); fc.setTosBits("65"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("IP ToS bits")); fc.setTosBits("60"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setSrcPort("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Transport source port")); fc.setSrcPort("0xfffff"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Transport source port")); fc.setSrcPort("0"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setSrcPort("0x00ff"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setSrcPort("0xffff"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setDstPort("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Transport destination port")); fc.setDstPort("0xfffff"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Transport destination port")); fc.setDstPort("0"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setDstPort("0x00ff"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setDstPort("0xffff"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setSrcMac("abc"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Ethernet source address")); fc.setSrcMac("00:A0:C9:14:C8:29"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setDstMac("abc"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Ethernet destination address")); fc.setDstMac("00:A0:C9:22:AB:11"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setSrcIp("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("IP source address")); fc.setSrcIp("2001:420:281:1004:407a:57f4:4d15:c355"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Src IP")); fc.setEtherType("0x86dd"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setSrcIp("1.1.1.1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Src IP")); fc.setEtherType("0x800"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setDstIp("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("IP destination address")); fc.setDstIp("2001:420:281:1004:407a:57f4:4d15:c355"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Dst IP")); fc.setEtherType("0x86dd"); fc.setSrcIp("2001:420:281:1004:407a:57f4:4d15:c355"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setDstIp("2.2.2.2"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Dst IP")); fc.setEtherType("0x800"); fc.setSrcIp("1.1.1.1"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setEtherType(null); fc.setSrcIp("2001:420:281:1004:407a:57f4:4d15:c355"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("IP Src Dest Type mismatch")); fc.setSrcIp("1.1.1.1"); fc.setIdleTimeout("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Idle Timeout value")); fc.setIdleTimeout("0xfffff"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Idle Timeout value")); fc.setIdleTimeout("10"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); fc.setHardTimeout("-1"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Hard Timeout value")); fc.setHardTimeout("0xfffff"); - status = fc.validate(null); + status = fc.validate(); Assert.assertFalse(status.isSuccess()); Assert.assertTrue(status.getDescription().contains("Hard Timeout value")); fc.setHardTimeout("10"); - Assert.assertTrue(fc.validate(null).isSuccess()); + Assert.assertTrue(fc.validate().isSuccess()); } diff --git a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java index b94103fb1c..be95bc98d5 100644 --- a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java +++ b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java @@ -50,6 +50,9 @@ import org.opendaylight.controller.forwardingrulesmanager.PortGroupProvider; import org.opendaylight.controller.forwardingrulesmanager.implementation.data.FlowEntryDistributionOrder; import org.opendaylight.controller.sal.action.Action; import org.opendaylight.controller.sal.action.ActionType; +import org.opendaylight.controller.sal.action.Enqueue; +import org.opendaylight.controller.sal.action.Flood; +import org.opendaylight.controller.sal.action.FloodAll; import org.opendaylight.controller.sal.action.Output; import org.opendaylight.controller.sal.connection.ConnectionLocality; import org.opendaylight.controller.sal.core.Config; @@ -243,6 +246,57 @@ public class ForwardingRulesManager implements return null; } + /** + * Checks if the FlowEntry targets are valid for this container + * + * @param flowEntry + * The flow entry to test + * @return a Status object representing the result of the validation + */ + private Status validateEntry(FlowEntry flowEntry) { + // Node presence check + Node node = flowEntry.getNode(); + if (!switchManager.getNodes().contains(node)) { + return new Status(StatusCode.BADREQUEST, String.format("Node %s is not present in this container", node)); + } + + // Ports and actions validation check + Flow flow = flowEntry.getFlow(); + Match match = flow.getMatch(); + if (match.isPresent(MatchType.IN_PORT)) { + NodeConnector inputPort = (NodeConnector)match.getField(MatchType.IN_PORT).getValue(); + if (!switchManager.getNodeConnectors(node).contains(inputPort)) { + String msg = String.format("Ingress port %s is not present on this container", inputPort); + return new Status(StatusCode.BADREQUEST, msg); + } + } + for (Action action : flow.getActions()) { + if (action instanceof Flood && !GlobalConstants.DEFAULT.toString().equals(getContainerName())) { + return new Status(StatusCode.BADREQUEST, String.format("Flood is only allowed in default container")); + } + if (action instanceof FloodAll && !GlobalConstants.DEFAULT.toString().equals(getContainerName())) { + return new Status(StatusCode.BADREQUEST, String.format("FloodAll is only allowed in default container")); + } + if (action instanceof Output) { + Output out = (Output)action; + NodeConnector outputPort = out.getPort(); + if (!switchManager.getNodeConnectors(node).contains(outputPort)) { + String msg = String.format("Output port %s is not present on this container", outputPort); + return new Status(StatusCode.BADREQUEST, msg); + } + } + if (action instanceof Enqueue) { + Enqueue out = (Enqueue)action; + NodeConnector outputPort = out.getPort(); + if (!switchManager.getNodeConnectors(node).contains(outputPort)) { + String msg = String.format("Enqueue port %s is not present on this container", outputPort); + return new Status(StatusCode.BADREQUEST, msg); + } + } + } + return new Status(StatusCode.SUCCESS); + } + /** * Adds a flow entry onto the network node It runs various validity checks * and derive the final container flows merged entries that will be @@ -264,6 +318,15 @@ public class ForwardingRulesManager implements return new Status(StatusCode.NOTACCEPTABLE, INVALID_FLOW_ENTRY); } + // Operational check: input, output and queue ports presence check and + // action validation for this container + Status status = validateEntry(flowEntry); + if (!status.isSuccess()) { + String msg = String.format("%s: %s", INVALID_FLOW_ENTRY, status.getDescription()); + log.warn("{}: {}", msg, flowEntry); + return new Status(StatusCode.NOTACCEPTABLE, msg); + } + /* * Redundant Check: Check if the request is a redundant one from the * same application the flowEntry is equal to an existing one. Given we @@ -422,6 +485,15 @@ public class ForwardingRulesManager implements return new Status(StatusCode.SUCCESS, msg); } + // Operational check: input, output and queue ports presence check and + // action validation for this container + Status status = validateEntry(newFlowEntry); + if (!status.isSuccess()) { + String msg = String.format("Modify: %s: %s", INVALID_FLOW_ENTRY, status.getDescription()); + log.warn("{}: {}", msg, newFlowEntry); + return new Status(StatusCode.NOTACCEPTABLE, msg); + } + /* * Conflict Check: Verify the new entry would not conflict with an * existing one. This is a loose check on the previous original flow @@ -1516,7 +1588,7 @@ public class ForwardingRulesManager implements @Override public Status addStaticFlow(FlowConfig config) { // Configuration object validation - Status status = config.validate(container); + Status status = config.validate(); if (!status.isSuccess()) { log.warn("Invalid Configuration for flow {}. The failure is {}", config, status.getDescription()); String error = "Invalid Configuration (" + status.getDescription() + ")"; @@ -1680,6 +1752,7 @@ public class ForwardingRulesManager implements config.setStatus(StatusCode.SUCCESS.toString()); break; default: + break; } } } @@ -1775,7 +1848,7 @@ public class ForwardingRulesManager implements } // Validity Check - Status status = newFlowConfig.validate(container); + Status status = newFlowConfig.validate(); if (!status.isSuccess()) { String msg = "Invalid Configuration (" + status.getDescription() + ")"; newFlowConfig.setStatus(msg); @@ -1855,7 +1928,7 @@ public class ForwardingRulesManager implements } } if (target != null) { - Status status = target.validate(container); + Status status = target.validate(); if (!status.isSuccess()) { log.warn(status.getDescription()); return status; @@ -2757,6 +2830,7 @@ public class ForwardingRulesManager implements this.reinstallAllFlowEntries(); break; default: + break; } // Update our configuration DB -- 2.36.6