Fixes OpenstackRoutingArpHandler respond arp request from peer router to source NAT ip of the external gateway.

Change-Id: I7c059bb86735487a3785e5fff73682cd747ab1fb
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index d751c03..7708d06 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -216,11 +216,27 @@
 
             //In case target ip is for associated floating ip, sets target mac to vm's.
             if (floatingIP != null && floatingIP.getPortId() != null) {
-                targetMac = MacAddress.valueOf(osNetworkAdminService.port(
-                                        floatingIP.getPortId()).getMacAddress());
+                InstancePort instPort = instancePortService.instancePort(floatingIP.getPortId());
+                if (instPort == null) {
+                    log.trace("Unknown target ARP request for {}, ignore it", targetIp);
+                    return;
+                } else {
+                    targetMac = instPort.macAddress();
+                }
+
+                OpenstackNode gw = getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
+
+                if (gw == null) {
+                    return;
+                }
+
+                // if the ARP packet_in received from non-relevant GWs, we simply ignore it
+                if (!Objects.equals(gw.intgBridge(), context.inPacket().receivedFrom().deviceId())) {
+                    return;
+                }
             }
 
-            if (isExternalGatewaySourceIp(targetIp.getIp4Address())) {
+            if (isExternalGatewaySourceIp(targetIp)) {
                 targetMac = Constants.DEFAULT_GATEWAY_MAC;
             }
 
@@ -229,19 +245,6 @@
                 return;
             }
 
-            InstancePort instPort = instancePortService.instancePort(targetMac);
-
-            OpenstackNode gw = getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
-
-            if (gw == null) {
-                return;
-            }
-
-            // if the ARP packet_in received from non-relevant GWs, we simply ignore it
-            if (!Objects.equals(gw.intgBridge(), context.inPacket().receivedFrom().deviceId())) {
-                return;
-            }
-
             Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(),
                     targetMac, ethernet);
 
@@ -484,6 +487,64 @@
         }
     }
 
+    private void setFakeGatewayArpRule(Router router, boolean install) {
+        setFakeGatewayArpRule(router.getExternalGatewayInfo(), install);
+    }
+
+    private Set<IP> getExternalGatewaySnatIps(ExternalGateway extGw) {
+        return osNetworkAdminService.ports().stream()
+                .filter(port ->
+                        Objects.equals(port.getNetworkId(), extGw.getNetworkId()))
+                .filter(port ->
+                        Objects.equals(port.getDeviceOwner(), DEVICE_OWNER_ROUTER_GW))
+                .flatMap(port -> port.getFixedIps().stream())
+                .collect(Collectors.toSet());
+    }
+
+    private void setFakeGatewayArpRule(ExternalGateway extGw, boolean install) {
+        if (ARP_BROADCAST_MODE.equals(getArpMode())) {
+
+            if (extGw == null) {
+                return;
+            }
+
+            Set<IP> ips = getExternalGatewaySnatIps(extGw);
+
+            ips.forEach(ip -> {
+                TrafficSelector selector = DefaultTrafficSelector.builder()
+                        .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+                        .matchArpOp(ARP.OP_REQUEST)
+                        .matchArpTpa(Ip4Address.valueOf(ip.getIpAddress()))
+                        .build();
+
+                TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                        .setArpOp(ARP.OP_REPLY)
+                        .setArpSha(MacAddress.valueOf(gatewayMac))
+                        .setArpSpa(Ip4Address.valueOf(ip.getIpAddress()))
+                        .setOutput(PortNumber.IN_PORT)
+                        .build();
+
+                osNodeService.completeNodes(GATEWAY).forEach(n ->
+                        osFlowRuleService.setRule(
+                                appId,
+                                n.intgBridge(),
+                                selector,
+                                treatment,
+                                PRIORITY_ARP_GATEWAY_RULE,
+                                GW_COMMON_TABLE,
+                                install
+                        )
+                );
+
+                if (install) {
+                    log.info("Install ARP Rule for Gateway Snat {}", ip.getIpAddress());
+                } else {
+                    log.info("Uninstall ARP Rule for Gateway Snat {}", ip.getIpAddress());
+                }
+            });
+        }
+    }
+
     /**
      * An internal router event listener, intended to install/uninstall
      * ARP rules for forwarding packets created from floating IPs.
@@ -589,64 +650,6 @@
 
             return null;
         }
-
-        private Set<IP> getExternalGatewaySnatIps(ExternalGateway extGw) {
-            return osNetworkAdminService.ports().stream()
-                    .filter(port ->
-                            Objects.equals(port.getNetworkId(), extGw.getNetworkId()))
-                    .filter(port ->
-                            Objects.equals(port.getDeviceOwner(), DEVICE_OWNER_ROUTER_GW))
-                    .flatMap(port -> port.getFixedIps().stream())
-                    .collect(Collectors.toSet());
-        }
-
-        private void setFakeGatewayArpRule(ExternalGateway extGw, boolean install) {
-            if (ARP_BROADCAST_MODE.equals(getArpMode())) {
-
-                if (extGw == null) {
-                    return;
-                }
-
-                Set<IP> ips = getExternalGatewaySnatIps(extGw);
-
-                ips.forEach(ip -> {
-                    TrafficSelector selector = DefaultTrafficSelector.builder()
-                            .matchEthType(EthType.EtherType.ARP.ethType().toShort())
-                            .matchArpOp(ARP.OP_REQUEST)
-                            .matchArpTpa(Ip4Address.valueOf(ip.getIpAddress()))
-                            .build();
-
-                    TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                            .setArpOp(ARP.OP_REPLY)
-                            .setArpSha(MacAddress.valueOf(gatewayMac))
-                            .setArpSpa(Ip4Address.valueOf(ip.getIpAddress()))
-                            .setOutput(PortNumber.IN_PORT)
-                            .build();
-
-                    osNodeService.completeNodes(GATEWAY).forEach(n ->
-                            osFlowRuleService.setRule(
-                                    appId,
-                                    n.intgBridge(),
-                                    selector,
-                                    treatment,
-                                    PRIORITY_ARP_GATEWAY_RULE,
-                                    GW_COMMON_TABLE,
-                                    install
-                            )
-                    );
-
-                    if (install) {
-                        log.info("Install ARP Rule for Gateway Snat {}", ip.getIpAddress());
-                    } else {
-                        log.info("Uninstall ARP Rule for Gateway Snat {}", ip.getIpAddress());
-                    }
-                });
-            }
-        }
-
-        private void setFakeGatewayArpRule(Router router, boolean install) {
-            setFakeGatewayArpRule(router.getExternalGatewayInfo(), install);
-        }
     }
 
     private class InternalInstancePortListener implements InstancePortListener {
@@ -802,6 +805,10 @@
                     GW_COMMON_TABLE,
                     install
             );
+
+            osRouterService.routers().stream()
+                    .filter(router -> router.getExternalGatewayInfo() != null)
+                    .forEach(router -> setFakeGatewayArpRule(router, install));
         }
     }
 }