Initial implementation of security group for kubevirt tenant network

Change-Id: If49d03021408a134be01267cc4eee9e0091e3c3d
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
index 603a293..f3edd55 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
@@ -88,12 +88,17 @@
 import static org.onosproject.kubevirtnetworking.api.Constants.FORWARDING_TABLE;
 import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRE_FLAT_TABLE;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_DEFAULT_RULE;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_DHCP_RULE;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_FORWARDING_RULE;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ICMP_RULE;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_INTERNAL_ROUTING_RULE;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_IP_EGRESS_RULE;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_IP_INGRESS_RULE;
 import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_TUNNEL_RULE;
+import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ACL_EGRESS_TABLE;
+import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ACL_INGRESS_TABLE;
 import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_ARP_TABLE;
 import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_DHCP_TABLE;
 import static org.onosproject.kubevirtnetworking.api.Constants.TENANT_FORWARDING_TABLE;
@@ -219,9 +224,9 @@
 
     private void createBridge(KubevirtNode node, KubevirtNetwork network) {
 
-        Device tunBridge = deviceService.getDevice(network.tenantDeviceId(node.hostname()));
-        if (tunBridge != null) {
-            log.warn("The tunnel bridge {} already exists at node {}",
+        Device tenantBridge = deviceService.getDevice(network.tenantDeviceId(node.hostname()));
+        if (tenantBridge != null) {
+            log.warn("The tenant bridge {} already exists at node {}",
                     network.tenantBridgeName(), node.hostname());
             setDefaultRulesForTenantNetwork(node, network);
             return;
@@ -321,7 +326,8 @@
         ifaceConfig.removePatchMode(tunToIntIntf);
     }
 
-    private void setArpRulesForTenantNetwork(KubevirtNode node, KubevirtNetwork network) {
+    private void setGatewayArpRulesForTenantNetwork(KubevirtNode node,
+                                                    KubevirtNetwork network) {
 
         KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
         if (router == null) {
@@ -333,11 +339,12 @@
             return;
         }
 
-        setGatewayArpRuleForTenantInternalNetwork(router, network, TENANT_ARP_TABLE, electedGw.intgBridge(),
-                network.tenantDeviceId(node.hostname()), true);
+        setGatewayArpRuleForTenantInternalNetwork(router, network, TENANT_ARP_TABLE,
+                electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
     }
 
-    private void setIcmpRulesForTenantNetwork(KubevirtNode node, KubevirtNetwork network) {
+    private void setGatewayIcmpRulesForTenantNetwork(KubevirtNode node,
+                                                     KubevirtNetwork network) {
         KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
         if (router == null) {
             return;
@@ -348,11 +355,12 @@
             return;
         }
 
-        setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE, electedGw.intgBridge(),
-                network.tenantDeviceId(node.hostname()), true);
+        setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE,
+                electedGw.intgBridge(), network.tenantDeviceId(node.hostname()), true);
     }
 
-    private void setDefaultGatewayRuleToWorkerNodeWhenNodeCreated(KubevirtNode node, KubevirtNetwork network) {
+    private void setGatewayRuleToWorkerNodeWhenNodeCreated(KubevirtNode node,
+                                                           KubevirtNetwork network) {
         KubevirtRouter router = getRouterForKubevirtNetwork(kubevirtRouterService, network);
         if (router == null) {
             return;
@@ -363,10 +371,12 @@
             return;
         }
 
-        setDefaultGatewayRuleToWorkerNodeTunBridge(router, network, electedGw.intgBridge(), node, true);
+        setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
+                electedGw.intgBridge(), node, true);
     }
 
-    private void setDefaultRulesForTenantNetwork(KubevirtNode node, KubevirtNetwork network) {
+    private void setDefaultRulesForTenantNetwork(KubevirtNode node,
+                                                 KubevirtNetwork network) {
         DeviceId deviceId = network.tenantDeviceId(node.hostname());
 
         while (!deviceService.isAvailable(deviceId)) {
@@ -384,9 +394,14 @@
         flowService.connectTables(deviceId, TENANT_ARP_TABLE, TENANT_ICMP_TABLE);
         flowService.connectTables(deviceId, TENANT_ICMP_TABLE, TENANT_FORWARDING_TABLE);
 
+        setArpRuleForTenantNetwork(deviceId, true);
         setDhcpRuleForTenantNetwork(deviceId, true);
         setForwardingRule(deviceId, true);
 
+        // security group related rules
+        setTenantIngressTransitionRule(network, network.tenantDeviceId(node.hostname()), true);
+        setEgressTransitionRule(network.tenantDeviceId(node.hostname()), true);
+
         log.info("Install default flow rules for tenant bridge {}", network.tenantBridgeName());
     }
 
@@ -436,13 +451,14 @@
             case VXLAN:
             case GRE:
             case GENEVE:
-                setDefaultEgressRuleToGatewayNode(router, network, electedGateway.intgBridge(), install);
+                setDefaultEgressRuleToGatewayNode(router, network,
+                        electedGateway.intgBridge(), install);
                 kubevirtNodeService.completeNodes(WORKER).forEach(node -> {
-                    setGatewayArpRuleForTenantInternalNetwork(router, network, TENANT_ARP_TABLE,
-                            electedGateway.intgBridge(),
+                    setGatewayArpRuleForTenantInternalNetwork(router, network,
+                            TENANT_ARP_TABLE, electedGateway.intgBridge(),
                             network.tenantDeviceId(node.hostname()), install);
-                    setGatewayIcmpRuleForTenantInternalNetwork(router, network, TENANT_ICMP_TABLE,
-                            electedGateway.intgBridge(),
+                    setGatewayIcmpRuleForTenantInternalNetwork(router, network,
+                            TENANT_ICMP_TABLE, electedGateway.intgBridge(),
                             network.tenantDeviceId(node.hostname()), install);
                     setDefaultGatewayRuleToWorkerNodeTunBridge(router, network,
                             electedGateway.intgBridge(), node, install);
@@ -451,11 +467,12 @@
                 break;
             case FLAT:
             case VLAN:
-                setGatewayArpRuleForProviderInternalNetwork(router, network, PRE_FLAT_TABLE,
-                        electedGateway.intgBridge(), install);
-                setGatewayIcmpRuleForProviderInternalNetwork(router, network, PRE_FLAT_TABLE,
-                        electedGateway.intgBridge(), install);
-                setGatewayProviderInterNetworkRoutingWithinSameRouter(network, router, electedGateway, install);
+                setGatewayArpRuleForProviderInternalNetwork(router, network,
+                        PRE_FLAT_TABLE, electedGateway.intgBridge(), install);
+                setGatewayIcmpRuleForProviderInternalNetwork(router, network,
+                        PRE_FLAT_TABLE, electedGateway.intgBridge(), install);
+                setGatewayProviderInterNetworkRoutingWithinSameRouter(network,
+                        router, electedGateway, install);
                 break;
             default:
                 // do nothing
@@ -519,6 +536,42 @@
                 install);
     }
 
+    private void setTenantIngressTransitionRule(KubevirtNetwork network,
+                                                DeviceId deviceId, boolean install) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
+                .matchInPort(network.tenantToTunnelPort(deviceId));
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        tBuilder.transition(TENANT_ACL_INGRESS_TABLE);
+
+        flowService.setRule(appId,
+                deviceId,
+                sBuilder.build(),
+                tBuilder.build(),
+                PRIORITY_IP_INGRESS_RULE,
+                TENANT_ICMP_TABLE,
+                install
+        );
+    }
+
+    private void setEgressTransitionRule(DeviceId deviceId, boolean install) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        sBuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        tBuilder.transition(TENANT_ACL_EGRESS_TABLE);
+
+        flowService.setRule(appId,
+                deviceId,
+                sBuilder.build(),
+                tBuilder.build(),
+                PRIORITY_IP_EGRESS_RULE,
+                TENANT_ICMP_TABLE,
+                install
+        );
+    }
+
     private void setDefaultEgressRuleToGatewayNode(KubevirtRouter router,
                                                    KubevirtNetwork network,
                                                    DeviceId gwDeviceId,
@@ -610,6 +663,25 @@
                 install);
     }
 
+    private void setArpRuleForTenantNetwork(DeviceId tenantDeviceId,
+                                            boolean install) {
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+                .matchEthType(EthType.EtherType.ARP.ethType().toShort());
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+                .transition(TENANT_FORWARDING_TABLE);
+
+        flowService.setRule(
+                appId,
+                tenantDeviceId,
+                sBuilder.build(),
+                tBuilder.build(),
+                PRIORITY_ARP_DEFAULT_RULE,
+                TENANT_ARP_TABLE,
+                install
+        );
+    }
+
     private void setGatewayArpRuleForTenantInternalNetwork(KubevirtRouter router,
                                                            KubevirtNetwork network,
                                                            int tableNum,
@@ -1000,7 +1072,8 @@
             });
         }
 
-        private void removeDetachedInternalNetworkRules(KubevirtNetwork removedNetwork, KubevirtRouter router,
+        private void removeDetachedInternalNetworkRules(KubevirtNetwork removedNetwork,
+                                                        KubevirtRouter router,
                                                         KubevirtNode electedGw) {
             router.internal().stream().filter(networkId -> kubevirtNetworkService.network(networkId) != null)
                     .forEach(networkId -> {
@@ -1213,9 +1286,9 @@
                             createBridge(node, network);
                             createPatchTenantInterface(node, network);
                             setDefaultRulesForTenantNetwork(node, network);
-                            setArpRulesForTenantNetwork(node, network);
-                            setIcmpRulesForTenantNetwork(node, network);
-                            setDefaultGatewayRuleToWorkerNodeWhenNodeCreated(node, network);
+                            setGatewayArpRulesForTenantNetwork(node, network);
+                            setGatewayIcmpRulesForTenantNetwork(node, network);
+                            setGatewayRuleToWorkerNodeWhenNodeCreated(node, network);
                             break;
                         case FLAT:
                             reserveVrouterIp(network);
@@ -1322,7 +1395,8 @@
                             || kubevirtNetworkService.network(srcNetwork) == null) {
                         return;
                     }
-                    setGatewayInterNetworkRoutingFromNetworkToPort(router, kubevirtNetworkService.network(srcNetwork),
+                    setGatewayInterNetworkRoutingFromNetworkToPort(router,
+                            kubevirtNetworkService.network(srcNetwork),
                             kubevirtPort, gwNode, true);
                 });
             }
@@ -1347,7 +1421,8 @@
                             || kubevirtNetworkService.network(srcNetwork) == null) {
                         return;
                     }
-                    setGatewayInterNetworkRoutingFromNetworkToPort(router, kubevirtNetworkService.network(srcNetwork),
+                    setGatewayInterNetworkRoutingFromNetworkToPort(router,
+                            kubevirtNetworkService.network(srcNetwork),
                             kubevirtPort, gwNode, true);
                 });
             }
@@ -1372,7 +1447,8 @@
                             || kubevirtNetworkService.network(srcNetwork) == null) {
                         return;
                     }
-                    setGatewayInterNetworkRoutingFromNetworkToPort(router, kubevirtNetworkService.network(srcNetwork),
+                    setGatewayInterNetworkRoutingFromNetworkToPort(router,
+                            kubevirtNetworkService.network(srcNetwork),
                             kubevirtPort, gwNode, false);
                 });
             }