[ONOS-7444] Optimize SONA gw doesn't use vrouter app and quagga anymore
- Done: Deriving MAC address from external peer router, SNAT, Floating IP-based routing, SNAT with VLAN
- Todo: Floating IP-based routing with VLAN, GW loadbalancing

Change-Id: I718b71eaf64a40049fc86687f10432446bb1b5bf
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index ac1e796..e67270c 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -124,7 +124,6 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected OpenstackNodeService osNodeService;
 
-
     private final OpenstackNetworkStoreDelegate delegate = new InternalNetworkStoreDelegate();
 
     private ConsistentMap<String, ExternalPeerRouter> externalPeerRouterMap;
@@ -342,7 +341,22 @@
     }
 
     @Override
-    public void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router) {
+    public ExternalPeerRouter externalPeerRouter(ExternalGateway externalGateway) {
+        IpAddress ipAddress = getExternalPeerRouterIp(externalGateway);
+
+        if (ipAddress == null) {
+            return null;
+        }
+
+        if (externalPeerRouterMap.containsKey(ipAddress.toString())) {
+            return externalPeerRouterMap.get(ipAddress.toString()).value();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router, VlanId vlanId) {
         log.info("deriveExternalPeerRouterMac called");
 
         IpAddress sourceIp = getExternalGatewaySourceIp(externalGateway, router);
@@ -364,7 +378,7 @@
         Ethernet ethRequest = ARP.buildArpRequest(sourceMac.toBytes(),
                 sourceIp.toOctets(),
                 targetIp.toOctets(),
-                VlanId.NO_VID);
+                vlanId.id());
 
         if (osNodeService.completeNodes(OpenstackNode.NodeType.GATEWAY).isEmpty()) {
             log.warn("There's no complete gateway");
@@ -400,7 +414,7 @@
                 ByteBuffer.wrap(ethRequest.serialize())));
 
         externalPeerRouterMap.put(
-                targetIp.toString(), new DefaultExternalPeerRouter(targetIp, MacAddress.NONE, VlanId.NONE));
+                targetIp.toString(), new DefaultExternalPeerRouter(targetIp, MacAddress.NONE, vlanId));
 
         log.info("Initializes external peer router map with peer router IP {}", targetIp.toString());
     }
@@ -428,32 +442,6 @@
         }
 
     }
-    private IpAddress getExternalGatewaySourceIp(ExternalGateway externalGateway, Router router) {
-        Port exGatewayPort = ports(externalGateway.getNetworkId())
-                .stream()
-                .filter(port -> Objects.equals(port.getDeviceId(), router.getId()))
-                .findAny().orElse(null);
-        if (exGatewayPort == null) {
-            log.warn("no external gateway port for router({})", router.getName());
-            return null;
-        }
-
-        IP ipAddress = exGatewayPort.getFixedIps().stream().findFirst().orElse(null);
-
-        return ipAddress == null ? null : IpAddress.valueOf(ipAddress.getIpAddress());
-    }
-
-    private IpAddress getExternalPeerRouterIp(ExternalGateway externalGateway) {
-        Optional<Subnet> externalSubnet = subnets(externalGateway.getNetworkId())
-                .stream()
-                .findFirst();
-
-        if (externalSubnet.isPresent()) {
-            return IpAddress.valueOf(externalSubnet.get().getGateway());
-        } else {
-            return null;
-        }
-    }
 
     @Override
     public void updateExternalPeerRouterMac(IpAddress ipAddress, MacAddress macAddress) {
@@ -497,9 +485,9 @@
     public void updateExternalPeerRouterVlan(IpAddress ipAddress, VlanId vlanId) {
 
         try {
-            externalPeerRouterMap.computeIfPresent(ipAddress.toString(), (id, existing) -> {
-                return new DefaultExternalPeerRouter(ipAddress, existing.externalPeerRouterMac(), vlanId);
-            });
+            externalPeerRouterMap.computeIfPresent(ipAddress.toString(), (id, existing) ->
+                    new DefaultExternalPeerRouter(ipAddress, existing.externalPeerRouterMac(), vlanId));
+
         } catch (Exception e) {
             log.error("Exception occurred because of {}", e.toString());
         }
@@ -534,4 +522,27 @@
             }
         }
     }
+
+    private IpAddress getExternalGatewaySourceIp(ExternalGateway externalGateway, Router router) {
+        Port exGatewayPort = ports(externalGateway.getNetworkId())
+                .stream()
+                .filter(port -> Objects.equals(port.getDeviceId(), router.getId()))
+                .findAny().orElse(null);
+        if (exGatewayPort == null) {
+            log.warn("no external gateway port for router({})", router.getName());
+            return null;
+        }
+
+        IP ipAddress = exGatewayPort.getFixedIps().stream().findFirst().orElse(null);
+
+        return ipAddress == null ? null : IpAddress.valueOf(ipAddress.getIpAddress());
+    }
+
+    private IpAddress getExternalPeerRouterIp(ExternalGateway externalGateway) {
+        Optional<Subnet> externalSubnet = subnets(externalGateway.getNetworkId())
+                .stream()
+                .findFirst();
+
+        return externalSubnet.map(subnet -> IpAddress.valueOf(subnet.getGateway())).orElse(null);
+    }
 }