FlowConfig to only run syntactic validation 63/5463/1
authorAlessandro Boch <aboch@cisco.com>
Tue, 25 Feb 2014 02:03:34 +0000 (18:03 -0800)
committerAlessandro Boch <aboch@cisco.com>
Tue, 25 Feb 2014 19:02:14 +0000 (11:02 -0800)
- 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 <aboch@cisco.com>
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java

index c56eb60a6b47d7f4093e56ade0a4d0b1d3262583..3ad08ca207b4a49a125274969f1f07f14d43990e 100644 (file)
@@ -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<ContainerFlow> 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()));
         }
index 48e1f07716ec267ddb52340e3ea21ef64ac8cebd..685ccdb7c44ea78931de795bb21547c1bd116b36 100644 (file)
@@ -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<String> actions = new ArrayList<String>();
         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());
 
     }
 
index b94103fb1c7c9233bb417e93cc74d42bbef498e7..be95bc98d54a272da3ab533d701e0f9f3c9c8a94 100644 (file)
@@ -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