Implemented extended SONA pipeline /w splitting VNI from DHCP Table

Change-Id: I1644b486e85ea2d0af9b9f317fe9b4a333915480
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
index 2ad9109..309cc03 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/Constants.java
@@ -59,12 +59,13 @@
     public static final int PRIORITY_ARP_REQUEST_RULE = 40000;
 
     public static final int DHCP_ARP_TABLE = 0;
-    public static final int SRC_VNI_TABLE = 0;
-    public static final int ACL_TABLE = 1;
-    public static final int CT_TABLE = 2;
-    public static final int JUMP_TABLE = 3;
-    public static final int ROUTING_TABLE = 4;
-    public static final int FORWARDING_TABLE = 5;
+    public static final int FLAT_TABLE = 1;
+    public static final int VTAG_TABLE = 10;
+    public static final int ACL_TABLE = 20;
+    public static final int CT_TABLE = 21;
+    public static final int JUMP_TABLE = 30;
+    public static final int ROUTING_TABLE = 40;
+    public static final int FORWARDING_TABLE = 50;
     public static final int GW_COMMON_TABLE = 0;
-    public static final int ERROR_TABLE = 10;
+    public static final int ERROR_TABLE = 100;
 }
\ No newline at end of file
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
index d4a8b68..48983e2 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
@@ -143,7 +143,8 @@
     }
 
     private void initializePipeline(DeviceId deviceId) {
-        connectTables(deviceId, Constants.SRC_VNI_TABLE, Constants.ACL_TABLE);
+        connectTables(deviceId, Constants.DHCP_ARP_TABLE, Constants.VTAG_TABLE);
+        connectTables(deviceId, Constants.VTAG_TABLE, Constants.ACL_TABLE);
         connectTables(deviceId, Constants.ACL_TABLE, Constants.JUMP_TABLE);
         setupJumpTable(deviceId);
     }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
index bfbd716..a769759 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
@@ -80,8 +80,8 @@
 import static org.onlab.packet.DHCP.MsgType.DHCPACK;
 import static org.onlab.packet.DHCP.MsgType.DHCPOFFER;
 import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_GATEWAY_MAC_STR;
+import static org.onosproject.openstacknetworking.api.Constants.DHCP_ARP_TABLE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_DHCP_RULE;
-import static org.onosproject.openstacknetworking.api.Constants.SRC_VNI_TABLE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -462,7 +462,7 @@
                     selector,
                     treatment,
                     PRIORITY_DHCP_RULE,
-                    SRC_VNI_TABLE,
+                    DHCP_ARP_TABLE,
                     install);
         }
     }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index 3848174..6fabacd 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -56,13 +56,15 @@
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.openstacknetworking.api.Constants.ACL_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.DHCP_ARP_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.FLAT_TABLE;
 import static org.onosproject.openstacknetworking.api.Constants.FORWARDING_TABLE;
 import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ADMIN_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLAT_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
-import static org.onosproject.openstacknetworking.api.Constants.SRC_VNI_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.VTAG_TABLE;
 import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -146,6 +148,7 @@
                 setForwardingRulesForVlan(instPort, install);
                 break;
             case FLAT:
+                setFlatJumpRules(instPort, install);
                 setDownstreamRules(instPort, install);
                 setUpstreamRules(instPort, install);
                 break;
@@ -155,6 +158,50 @@
         }
     }
 
+    private void setFlatJumpRules(InstancePort port, boolean install) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchInPort(port.portNumber());
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.transition(FLAT_TABLE);
+
+        osFlowRuleService.setRule(
+                appId,
+                port.deviceId(),
+                selector.build(),
+                treatment.build(),
+                PRIORITY_FLAT_RULE,
+                DHCP_ARP_TABLE,
+                install);
+
+        Network network = osNetworkService.network(port.networkId());
+
+        if (network == null) {
+            log.warn("The network does not exist");
+            return;
+        }
+
+        PortNumber portNumber = osNodeService.node(port.deviceId())
+                .phyIntfPortNum(network.getProviderPhyNet());
+
+        if (portNumber == null) {
+            log.warn("The port number does not exist");
+            return;
+        }
+
+        selector = DefaultTrafficSelector.builder();
+        selector.matchInPort(portNumber);
+
+        osFlowRuleService.setRule(
+                appId,
+                port.deviceId(),
+                selector.build(),
+                treatment.build(),
+                PRIORITY_FLAT_RULE,
+                DHCP_ARP_TABLE,
+                install);
+    }
+
     private void setDownstreamRules(InstancePort instPort, boolean install) {
         TrafficSelector selector = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
@@ -170,7 +217,7 @@
                 selector,
                 treatment,
                 PRIORITY_FLAT_RULE,
-                SRC_VNI_TABLE,
+                FLAT_TABLE,
                 install);
 
         selector = DefaultTrafficSelector.builder()
@@ -184,7 +231,7 @@
                 selector,
                 treatment,
                 PRIORITY_FLAT_RULE,
-                SRC_VNI_TABLE,
+                FLAT_TABLE,
                 install);
     }
 
@@ -218,7 +265,7 @@
                 selector,
                 treatment,
                 PRIORITY_FLAT_RULE,
-                SRC_VNI_TABLE,
+                FLAT_TABLE,
                 install);
     }
 
@@ -371,7 +418,7 @@
                 selector,
                 tb.build(),
                 PRIORITY_TUNNEL_TAG_RULE,
-                SRC_VNI_TABLE,
+                VTAG_TABLE,
                 install);
     }
 
@@ -402,7 +449,7 @@
                 selector,
                 treatment,
                 PRIORITY_TUNNEL_TAG_RULE,
-                SRC_VNI_TABLE,
+                VTAG_TABLE,
                 install);
     }
 
@@ -437,6 +484,7 @@
                 );
     }
 
+    // TODO: need to be purged sooner or later
     private void setPortAdminRules(Port port, boolean install) {
         InstancePort instancePort =
                 instancePortService.instancePort(MacAddress.valueOf(port.getMacAddress()));
@@ -454,7 +502,7 @@
                 selector,
                 treatment,
                 PRIORITY_ADMIN_RULE,
-                SRC_VNI_TABLE,
+                VTAG_TABLE,
                 install);
     }