Fix: enforce security group rules to match tunnel ID

Change-Id: I056eae92049d8929fd32779277256e240458e040
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
index d3bc4d4..d44dab1 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
@@ -32,6 +32,7 @@
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.TpPort;
+import org.onlab.packet.VlanId;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.cluster.ClusterService;
@@ -171,6 +172,9 @@
     private static final String INGRESS = "INGRESS";
     private static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0");
 
+    private static final String VXLAN = "VXLAN";
+    private static final String VLAN = "VLAN";
+
     // We expose pipeline structure to SONA application considering removing pipeline soon.
     private static final int GOTO_CONNTRACK_TABLE = CT_TABLE;
     private static final int GOTO_JUMP_TABLE = JUMP_TABLE;
@@ -284,9 +288,9 @@
         if (sgRule.getRemoteGroupId() != null && !sgRule.getRemoteGroupId().isEmpty()) {
             getRemoteInstPorts(port.getTenantId(), sgRule.getRemoteGroupId())
                     .forEach(rInstPort -> {
-                        populateSecurityGroupRule(sgRule, instPort,
+                        populateSecurityGroupRule(sgRule, instPort, port,
                                 rInstPort.ipAddress().toIpPrefix(), install);
-                        populateSecurityGroupRule(sgRule, rInstPort,
+                        populateSecurityGroupRule(sgRule, rInstPort, port,
                                 instPort.ipAddress().toIpPrefix(), install);
 
                         SecurityGroupRule rSgRule =
@@ -296,13 +300,13 @@
                                 .direction(sgRule.getDirection().toUpperCase()
                                             .equals(EGRESS) ? INGRESS : EGRESS)
                                 .build();
-                        populateSecurityGroupRule(rSgRule, instPort,
+                        populateSecurityGroupRule(rSgRule, instPort, port,
                                 rInstPort.ipAddress().toIpPrefix(), install);
-                        populateSecurityGroupRule(rSgRule, rInstPort,
+                        populateSecurityGroupRule(rSgRule, rInstPort, port,
                                 instPort.ipAddress().toIpPrefix(), install);
                     });
         } else {
-            populateSecurityGroupRule(sgRule, instPort,
+            populateSecurityGroupRule(sgRule, instPort, port,
                     sgRule.getRemoteIpPrefix() == null ? IP_PREFIX_ANY :
                     IpPrefix.valueOf(sgRule.getRemoteIpPrefix()), install);
         }
@@ -310,9 +314,11 @@
 
     private void populateSecurityGroupRule(SecurityGroupRule sgRule,
                                            InstancePort instPort,
-                                           IpPrefix remoteIp, boolean install) {
+                                           Port port,
+                                           IpPrefix remoteIp,
+                                           boolean install) {
         Set<TrafficSelector> selectors = buildSelectors(sgRule,
-                Ip4Address.valueOf(instPort.ipAddress().toInetAddress()), remoteIp);
+                Ip4Address.valueOf(instPort.ipAddress().toInetAddress()), remoteIp, port);
         if (selectors == null || selectors.isEmpty()) {
             return;
         }
@@ -418,7 +424,8 @@
 
     private Set<TrafficSelector> buildSelectors(SecurityGroupRule sgRule,
                                                 Ip4Address vmIp,
-                                                IpPrefix remoteIp) {
+                                                IpPrefix remoteIp,
+                                                Port port) {
         if (remoteIp != null && remoteIp.equals(IpPrefix.valueOf(vmIp, 32))) {
             // do nothing if the remote IP is my IP
             return null;
@@ -427,7 +434,7 @@
         Set<TrafficSelector> selectorSet = Sets.newHashSet();
 
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-        buildMatches(sBuilder, sgRule, vmIp, remoteIp);
+        buildMatches(sBuilder, sgRule, vmIp, remoteIp, port);
 
         if (sgRule.getPortRangeMax() != null && sgRule.getPortRangeMin() != null &&
                 sgRule.getPortRangeMin() < sgRule.getPortRangeMax()) {
@@ -462,7 +469,8 @@
 
     private void buildMatches(TrafficSelector.Builder sBuilder,
                               SecurityGroupRule sgRule,
-                              Ip4Address vmIp, IpPrefix remoteIp) {
+                              Ip4Address vmIp, IpPrefix remoteIp, Port port) {
+        buildTunnelId(sBuilder, port);
         buildMatchEthType(sBuilder, sgRule.getEtherType());
         buildMatchDirection(sBuilder, sgRule.getDirection(), vmIp);
         buildMatchProto(sBuilder, sgRule.getProtocol());
@@ -475,6 +483,17 @@
         }
     }
 
+    private void buildTunnelId(TrafficSelector.Builder sBuilder, Port port) {
+        String segId = osNetService.segmentId(port.getNetworkId());
+        String netType = osNetService.networkType(port.getNetworkId());
+
+        if (VLAN.equals(netType)) {
+            sBuilder.matchVlanId(VlanId.vlanId(segId));
+        } else if (VXLAN.equals(netType)) {
+            sBuilder.matchTunnelId(Long.valueOf(segId));
+        }
+    }
+
     private void buildMatchDirection(TrafficSelector.Builder sBuilder,
                                      String direction,
                                      Ip4Address vmIp) {
@@ -690,8 +709,11 @@
         public void event(InstancePortEvent event) {
             InstancePort instPort = event.subject();
             switch (event.type()) {
-                case OPENSTACK_INSTANCE_PORT_DETECTED:
                 case OPENSTACK_INSTANCE_PORT_UPDATED:
+                    if (instPort.state() == REMOVE_PENDING) {
+                        break;
+                    }
+                case OPENSTACK_INSTANCE_PORT_DETECTED:
                     log.debug("Instance port detected MAC:{} IP:{}",
                             instPort.macAddress(),
                             instPort.ipAddress());