[ONOS-6037]Support Neutron router admin state up/down configuration

Change-Id: I441ef1c8918f80d2a2e6e26ebfc880d677ce83ed
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index 254dba9..dd2e887 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -94,6 +94,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_STATEFUL_SNAT_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.ROUTING_TABLE;
+import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ADMIN_RULE;
 import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -206,6 +207,13 @@
 
     private void routerUpdated(Router osRouter) {
         ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
+
+        osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> {
+            Network network = osNetworkService.network(osNetworkService.subnet(iface.getSubnetId())
+                    .getNetworkId());
+            setRouterAdminRules(network.getProviderSegID(), network.getNetworkType(), !osRouter.isAdminStateUp());
+        });
+
         if (exGateway == null) {
             osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> {
                 setSourceNat(osRouter, iface, false);
@@ -217,6 +225,14 @@
         }
     }
 
+    private void routerRemove(Router osRouter) {
+        osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> {
+            Network network = osNetworkService.network(osNetworkService.subnet(iface.getSubnetId())
+                    .getNetworkId());
+            setRouterAdminRules(network.getProviderSegID(), network.getNetworkType(), false);
+        });
+    }
+
     private void routerIfaceAdded(Router osRouter, RouterInterface osRouterIface) {
         Subnet osSubnet = osNetworkService.subnet(osRouterIface.getSubnetId());
         if (osSubnet == null) {
@@ -226,6 +242,12 @@
                     osRouterIface.getSubnetId());
             throw new IllegalStateException(error);
         }
+
+        if (!osRouter.isAdminStateUp()) {
+            Network network = osNetworkService.network(osSubnet.getNetworkId());
+            setRouterAdminRules(network.getProviderSegID(), network.getNetworkType(), true);
+        }
+
         setInternalRoutes(osRouter, osSubnet, true);
         setGatewayIcmp(osSubnet, true);
         ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
@@ -245,6 +267,11 @@
             throw new IllegalStateException(error);
         }
 
+        if (!osRouter.isAdminStateUp()) {
+            Network network = osNetworkService.network(osSubnet.getNetworkId());
+            setRouterAdminRules(network.getProviderSegID(), network.getNetworkType(), false);
+        }
+
         setInternalRoutes(osRouter, osSubnet, false);
         setGatewayIcmp(osSubnet, false);
         ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
@@ -812,6 +839,43 @@
                 install);
     }
 
+    private void setRouterAdminRules(String segmentId, NetworkType networkType, boolean install) {
+        TrafficTreatment treatment;
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4);
+
+        switch (networkType) {
+            case VXLAN:
+                sBuilder.matchTunnelId(Long.parseLong(segmentId));
+                break;
+            case VLAN:
+                sBuilder.matchVlanId(VlanId.vlanId(segmentId));
+                break;
+            default:
+                final String error = String.format(
+                        ERR_UNSUPPORTED_NET_TYPE + "%s",
+                        networkType.toString());
+                throw new IllegalStateException(error);
+        }
+
+        treatment = DefaultTrafficTreatment.builder()
+                .drop()
+                .build();
+
+        osNodeService.completeNodes().stream()
+                .filter(osNode -> osNode.type() == COMPUTE)
+                .forEach(osNode -> {
+                    osFlowRuleService.setRule(
+                            appId,
+                            osNode.intgBridge(),
+                            sBuilder.build(),
+                            treatment,
+                            PRIORITY_ADMIN_RULE,
+                            ROUTING_TABLE,
+                            install);
+                });
+    }
+
     private class InternalRouterEventListener implements OpenstackRouterListener {
 
         @Override
@@ -841,6 +905,7 @@
                     log.debug("Router(name:{}, ID:{}) is removed",
                             event.subject().getName(),
                             event.subject().getId());
+                    eventExecutor.execute(() -> routerRemove(event.subject()));
                     break;
                 case OPENSTACK_ROUTER_INTERFACE_ADDED:
                     log.debug("Router interface {} added to router {}",