Bug 78 Enable Enqueue action in static flows 76/3476/2
authorAlessandro Boch <aboch@cisco.com>
Thu, 5 Dec 2013 07:22:12 +0000 (23:22 -0800)
committerAlessandro Boch <aboch@cisco.com>
Thu, 5 Dec 2013 07:22:12 +0000 (23:22 -0800)
Change-Id: I9e1558719a4d6e407e90a40c263380b4fac63f8f
Signed-off-by: Alessandro Boch <aboch@cisco.com>
opendaylight/forwardingrulesmanager/api/pom.xml
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/pom.xml
opendaylight/northbound/flowprogrammer/pom.xml
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Enqueue.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NodeConnectorCreator.java

index f25756cc115eb9ed61c40361b9b3d4d18ce6e7d1..499b98c28ad1c04dd8512af4501b799e4a3e0124 100644 (file)
@@ -87,7 +87,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
index 43b0252df7b5c8aa83df94866632887286b44252..de7597730f9062a85d7071b3986044c4874a4e7a 100644 (file)
@@ -13,7 +13,6 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -26,6 +25,7 @@ import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.action.Controller;
 import org.opendaylight.controller.sal.action.Drop;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.action.Controller;
 import org.opendaylight.controller.sal.action.Drop;
+import org.opendaylight.controller.sal.action.Enqueue;
 import org.opendaylight.controller.sal.action.Flood;
 import org.opendaylight.controller.sal.action.HwPath;
 import org.opendaylight.controller.sal.action.Loopback;
 import org.opendaylight.controller.sal.action.Flood;
 import org.opendaylight.controller.sal.action.HwPath;
 import org.opendaylight.controller.sal.action.Loopback;
@@ -609,25 +609,13 @@ public class FlowConfig implements Serializable {
         return true;
     }
 
         return true;
     }
 
-    public boolean isPortValid(Switch sw, Short port) {
-        if (port < 1) {
-            log.debug("port {} is not valid", port);
-            return false;
-        }
-
+    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;
         }
         if (sw == null) {
             log.debug("switch info is not available. Skip checking if port is part of a switch or not.");
             return true;
         }
-
-        Set<NodeConnector> nodeConnectorSet = sw.getNodeConnectors();
-        for (NodeConnector nodeConnector : nodeConnectorSet) {
-            if (((Short) nodeConnector.getID()).equals(port)) {
-                return true;
-            }
-        }
-        log.debug("port {} is not a valid port of node {}", port, sw.getNode());
-        return false;
+        NodeConnector nc = NodeConnectorCreator.createNodeConnector(port, sw.getNode());
+        return sw.getNodeConnectors().contains(nc);
     }
 
     public boolean isVlanIdValid(String vlanId) {
     }
 
     public boolean isVlanIdValid(String vlanId) {
@@ -735,9 +723,8 @@ public class FlowConfig implements Serializable {
             }
 
             if (ingressPort != null) {
             }
 
             if (ingressPort != null) {
-                Short port = Short.decode(ingressPort);
-                if (isPortValid(sw, port) == false) {
-                    String msg = String.format("Ingress port %d is not valid for the Switch", port);
+                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;
                     }
                     if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
                         msg += " in Container " + containerName;
                     }
@@ -850,10 +837,33 @@ public class FlowConfig implements Serializable {
                 if (sstr.matches()) {
                     for (String t : sstr.group(1).split(",")) {
                         Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
                 if (sstr.matches()) {
                     for (String t : sstr.group(1).split(",")) {
                         Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
+                        if (n.matches()) {
+                            String port = n.group(1);
+                            if (port != null) {
+                                if (!isPortValid(sw, port)) {
+                                    String msg = String.format("Output port %s is not valid for this switch", port);
+                                    if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
+                                        msg += " in Container " + containerName;
+                                    }
+                                    return new Status(StatusCode.BADREQUEST, msg);
+                                }
+                            }
+                        } else {
+                            String msg = String.format("Output port %s is not valid", t);
+                            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(",")) {
+                        Matcher n = Pattern.compile("(?:(\\d+:\\d+))").matcher(t);
                         if (n.matches()) {
                             if (n.group(1) != null) {
                         if (n.matches()) {
                             if (n.group(1) != null) {
-                                Short port = Short.parseShort(n.group(1));
-                                if (isPortValid(sw, port) == false) {
+                                String port = n.group(1).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;
                                     String msg = String.format("Output port %d is not valid for this switch", port);
                                     if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
                                         msg += " in Container " + containerName;
@@ -862,7 +872,7 @@ public class FlowConfig implements Serializable {
                                 }
                             }
                         } else {
                                 }
                             }
                         } else {
-                            String msg = String.format("Output port %s is not valid", t);
+                            String msg = String.format("Enqueue port %s is not valid", t);
                             return new Status(StatusCode.BADREQUEST, msg);
                         }
                     }
                             return new Status(StatusCode.BADREQUEST, msg);
                         }
                     }
@@ -990,7 +1000,7 @@ public class FlowConfig implements Serializable {
 
         if (this.ingressPort != null) {
             match.setField(MatchType.IN_PORT,
 
         if (this.ingressPort != null) {
             match.setField(MatchType.IN_PORT,
-                    NodeConnectorCreator.createOFNodeConnector(Short.parseShort(ingressPort), getNode()));
+                    NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), ingressPort, node.toString())));
         }
         if (this.dlSrc != null) {
             match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
         }
         if (this.dlSrc != null) {
             match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
@@ -1095,9 +1105,28 @@ public class FlowConfig implements Serializable {
                         Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
                         if (n.matches()) {
                             if (n.group(1) != null) {
                         Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
                         if (n.matches()) {
                             if (n.group(1) != null) {
-                                short ofPort = Short.parseShort(n.group(1));
-                                actionList.add(new Output(NodeConnectorCreator.createOFNodeConnector(ofPort,
-                                        this.getNode())));
+                                String nc = String.format("%s|%s@%s", node.getType(), n.group(1), node.toString());
+                                actionList.add(new Output(NodeConnector.fromString(nc)));
+                            }
+                        }
+                    }
+                    continue;
+                }
+
+                sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    for (String t : sstr.group(1).split(",")) {
+                        Matcher n = Pattern.compile("(?:(\\d+:\\d+))").matcher(t);
+                        if (n.matches()) {
+                            if (n.group(1) != null) {
+                                String parts[] = n.group(1).split(":");
+                                String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString());
+                                if (parts.length == 1) {
+                                    actionList.add(new Enqueue(NodeConnector.fromString(nc)));
+                                } else {
+                                    actionList
+                                            .add(new Enqueue(NodeConnector.fromString(nc), Integer.parseInt(parts[1])));
+                                }
                             }
                         }
                     }
                             }
                         }
                     }
index 406970711ccf5cc8e93071f3fec172c6582f23cf..48e1f07716ec267ddb52340e3ea21ef64ac8cebd 100644 (file)
@@ -546,11 +546,6 @@ public class frmTest {
         fc.setCookie("100");
         Assert.assertTrue(fc.validate(null).isSuccess());
 
         fc.setCookie("100");
         Assert.assertTrue(fc.validate(null).isSuccess());
 
-        fc.setIngressPort("-1");
-        status = fc.validate(null);
-        Assert.assertFalse(status.isSuccess());
-        Assert.assertTrue(status.getDescription().contains("is not valid for the Switch"));
-
         fc.setIngressPort("100");
         Assert.assertTrue(fc.validate(null).isSuccess());
 
         fc.setIngressPort("100");
         Assert.assertTrue(fc.validate(null).isSuccess());
 
index 23c36a37528b671829584177ac0f9ed4e5498f94..6b3f5347adb58e7bb31f28d4dae6de262a15db65 100644 (file)
@@ -93,7 +93,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index af2c18a217a676c142c73040e29fe52aab80b586..1b81ccb450f71a9050739830c3e57758e0a43fc4 100644 (file)
@@ -88,7 +88,7 @@
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
-      <version>0.5.1-SNAPSHOT</version>
+      <version>0.7.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
     </dependency>
     <dependency>
       <groupId>org.codehaus.enunciate</groupId>
index 8fa4941b88771c94dbf3b578a3f89717339f899e..361f977b2c2c547697b46c6cf8b76d18dbd1bafd 100644 (file)
@@ -57,6 +57,7 @@ import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionDataLayer;
 import org.openflow.protocol.action.OFActionDataLayerDestination;
 import org.openflow.protocol.action.OFActionDataLayerSource;
 import org.openflow.protocol.action.OFActionDataLayer;
 import org.openflow.protocol.action.OFActionDataLayerDestination;
 import org.openflow.protocol.action.OFActionDataLayerSource;
+import org.openflow.protocol.action.OFActionEnqueue;
 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
 import org.openflow.protocol.action.OFActionNetworkLayerSource;
 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
 import org.openflow.protocol.action.OFActionNetworkLayerDestination;
 import org.openflow.protocol.action.OFActionNetworkLayerSource;
@@ -280,6 +281,15 @@ public class FlowConverter {
                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
                     continue;
                 }
                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
                     continue;
                 }
+                if (action.getType() == ActionType.ENQUEUE) {
+                    Enqueue a = (Enqueue) action;
+                    OFActionEnqueue ofAction = new OFActionEnqueue();
+                    ofAction.setPort(PortConverter.toOFPort(a.getPort()));
+                    ofAction.setQueueId(a.getQueue());
+                    actionsList.add(ofAction);
+                    actionsLength += OFActionEnqueue.MINIMUM_LENGTH;
+                    continue;
+                }
                 if (action.getType() == ActionType.DROP) {
                     continue;
                 }
                 if (action.getType() == ActionType.DROP) {
                     continue;
                 }
@@ -683,6 +693,10 @@ public class FlowConverter {
                                     NodeConnectorCreator.createOFNodeConnector(
                                             ofPort, node));
                         }
                                     NodeConnectorCreator.createOFNodeConnector(
                                             ofPort, node));
                         }
+                    } else if (ofAction instanceof OFActionEnqueue) {
+                        salAction = new Enqueue(NodeConnectorCreator.createOFNodeConnector(
+                                ((OFActionEnqueue) ofAction).getPort(), node),
+                                ((OFActionEnqueue) ofAction).getQueueId());
                     } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
                         salAction = new SetVlanId(
                                 ((OFActionVirtualLanIdentifier) ofAction)
                     } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
                         salAction = new SetVlanId(
                                 ((OFActionVirtualLanIdentifier) ofAction)
index b3891c8337b1f2bba4012f378a65f6d3e5e5c7ca..c711e67f9ee33d91831194f05837094c8552de4e 100644 (file)
@@ -21,6 +21,8 @@ public class Enqueue extends Action {
     private static final long serialVersionUID = 1L;
     @XmlElement
     private NodeConnector port;
     private static final long serialVersionUID = 1L;
     @XmlElement
     private NodeConnector port;
+    @XmlElement
+    private int queue;
 
     /* Dummy constructor for JAXB */
     @SuppressWarnings("unused")
 
     /* Dummy constructor for JAXB */
     @SuppressWarnings("unused")
@@ -30,9 +32,25 @@ public class Enqueue extends Action {
     public Enqueue(NodeConnector port) {
         type = ActionType.ENQUEUE;
         this.port = port;
     public Enqueue(NodeConnector port) {
         type = ActionType.ENQUEUE;
         this.port = port;
+        this.queue = 0;
+    }
+
+    public Enqueue(NodeConnector port, int queue) {
+        type = ActionType.ENQUEUE;
+        this.port = port;
+        this.queue = queue;
     }
 
     public NodeConnector getPort() {
         return port;
     }
     }
 
     public NodeConnector getPort() {
         return port;
     }
+
+    public int getQueue() {
+        return queue;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s[%s:%s]", type, port, queue);
+    }
 }
 }
index cbf3f95b2a776dc616ebd8606697b7b46aa06f2d..da4cd5388380f81f69fd9dc9a431da61093a67a6 100644 (file)
@@ -40,7 +40,7 @@ public abstract class NodeConnectorCreator {
         if (node.getType().equals(NodeIDType.OPENFLOW)) {
             try {
                 return new NodeConnector(NodeConnectorIDType.OPENFLOW,
         if (node.getType().equals(NodeIDType.OPENFLOW)) {
             try {
                 return new NodeConnector(NodeConnectorIDType.OPENFLOW,
-                        (Short) portId, node);
+                        portId, node);
             } catch (ConstructionException e1) {
                 logger.error("",e1);
                 return null;
             } catch (ConstructionException e1) {
                 logger.error("",e1);
                 return null;
@@ -49,6 +49,18 @@ public abstract class NodeConnectorCreator {
         return null;
     }
 
         return null;
     }
 
+    /**
+     * Generic NodeConnector creator
+     * The nodeConnector type is inferred from the node type
+     *
+     * @param portId The string representing the port id
+     * @param node The network node as {@link org.opendaylight.controller.sal.core.Node Node} object
+     * @return The corresponding {@link org.opendaylight.controller.sal.core.NodeConnector NodeConnector} object
+     */
+    public static NodeConnector createNodeConnector(String portId, Node node) {
+        return NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), portId, node.toString()));
+    }
+
     /**
      * NodeConnector creator where NodeConnector type can be specified
      * Needed to create special internal node connectors (like software stack)
     /**
      * NodeConnector creator where NodeConnector type can be specified
      * Needed to create special internal node connectors (like software stack)