Improve Xconnect to support BSOD use case

- Push ACL flow to ignore xconnect VLAN
- Add pair port to the L2FG internally
- Remove the ETH_TYPE restriction in OFDPA processVersatile
- Remove the NOACTION warning in OFDPA processVersatile
- Do not push bridging flow for hosts that have wrong VLAN tag

Known issue:
- flooding issue on the pair port
- tagged host will be learnt before xconnect config is pushed (will be ignored by SR)

Change-Id: I30e4f46e54daa0f7bd349419df100523dceb2c4c
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index 3982731..4c56db5 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -114,7 +114,10 @@
                 srManager.getPairLocalPort(pairDeviceId).ifPresent(pairRemotePort -> {
                     // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
                     //       when the host is untagged
-                    VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(hostVlanId);
+                    VlanId vlanId = vlanForPairPort(hostVlanId, location);
+                    if (vlanId == null) {
+                        return;
+                    }
 
                     processBridgingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, false);
                     ips.forEach(ip -> processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId,
@@ -158,7 +161,10 @@
             if (pairDeviceId.isPresent() && pairLocalPort.isPresent()) {
                 // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
                 //       when the host is untagged
-                VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(hostVlanId);
+                VlanId vlanId = vlanForPairPort(hostVlanId, location);
+                if (vlanId == null) {
+                    return;
+                }
 
                 processBridgingRule(pairDeviceId.get(), pairLocalPort.get(), hostMac, vlanId, true);
                 ips.forEach(ip ->
@@ -362,7 +368,10 @@
                     srManager.getPairLocalPort(pairDeviceId).ifPresent(pairRemotePort -> {
                         // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
                         //       when the host is untagged
-                        VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(location)).orElse(hostVlanId);
+                        VlanId vlanId = vlanForPairPort(hostVlanId, location);
+                        if (vlanId == null) {
+                            return;
+                        }
 
                         ipsToRemove.forEach(ip ->
                                 processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, ip, true)
@@ -526,6 +535,28 @@
     }
 
     /**
+     * Returns VLAN ID to be used to program redirection flow on pair port.
+     *
+     * @param hostVlanId host VLAN ID
+     * @param location host location
+     * @return VLAN ID to be used; Or null if host VLAN does not match the interface config
+     */
+    VlanId vlanForPairPort(VlanId hostVlanId, ConnectPoint location) {
+        VlanId internalVlan = srManager.getInternalVlanId(location);
+        Set<VlanId> taggedVlan = srManager.interfaceService.getTaggedVlanId(location);
+
+        if (!hostVlanId.equals(VlanId.NONE) && taggedVlan.contains(hostVlanId)) {
+            return hostVlanId;
+        } else if (hostVlanId.equals(VlanId.NONE) && internalVlan != null) {
+            return internalVlan;
+        } else {
+            log.warn("VLAN mismatch. hostVlan={}, location={}, internalVlan={}, taggedVlan={}",
+                    hostVlanId, location, internalVlan, taggedVlan);
+            return null;
+        }
+    }
+
+    /**
      * Update forwarding objective for unicast bridging and unicast routing.
      * Also check the validity of updated interface configuration on VLAN.
      *