Bug 4579 - Periodic ARP resolver is missing callback for MAC updates
[netvirt.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / openflow13 / services / arp / GatewayMacResolverService.java
index 7c2cfbebae8a3ab589561b4d89ec27bd831f686b..3c1ab52410b9fa41b585e6789c154778cf0b6cec 100644 (file)
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
+import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolverListener;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
@@ -89,7 +90,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                                         implements ConfigInterface, GatewayMacResolver,PacketProcessingListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(GatewayMacResolverService.class);
-    private static final short TABEL_FOR_ARP_FLOW = 0;
+    private static final short TABLE_FOR_ARP_FLOW = 0;
     private static final String ARP_REPLY_TO_CONTROLLER_FLOW_NAME = "GatewayArpReplyRouter";
     private static final int ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY = 10000;
     private static final Instruction SEND_TO_CONTROLLER_INSTRUCTION;
@@ -157,9 +158,9 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                                     }
 
                                     LOG.debug("Refresh Gateway Mac for gateway {} using source ip {} and mac {} for ARP request",
-                                            gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestMacAddress().getValue());
+                                            gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestSourceMacAddress().getValue());
 
-                                    sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestMacAddress());
+                                    sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestSourceMacAddress());
                                 }
                             }, 1, TimeUnit.SECONDS);
                         }
@@ -183,8 +184,10 @@ public class GatewayMacResolverService extends AbstractServiceInstance
      * @return Future object
      */
     @Override
-    public ListenableFuture<MacAddress> resolveMacAddress( final Long externalNetworkBridgeDpid, final Ipv4Address gatewayIp,
-            final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress, final Boolean periodicRefresh){
+    public ListenableFuture<MacAddress> resolveMacAddress(
+            final GatewayMacResolverListener gatewayMacResolverListener, final Long externalNetworkBridgeDpid,
+            final Ipv4Address gatewayIp, final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress,
+            final Boolean periodicRefresh){
         Preconditions.checkNotNull(sourceIpAddress);
         Preconditions.checkNotNull(sourceMacAddress);
         Preconditions.checkNotNull(gatewayIp);
@@ -204,7 +207,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                 });
             }
         }else{
-            gatewayToArpMetadataMap.put(gatewayIp,new ArpResolverMetadata(
+            gatewayToArpMetadataMap.put(gatewayIp,new ArpResolverMetadata(gatewayMacResolverListener,
                     externalNetworkBridgeDpid, gatewayIp,sourceIpAddress,sourceMacAddress,periodicRefresh));
         }
 
@@ -256,16 +259,24 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                 }
                 LOG.debug("Flow to route ARP Reply to Controller installed successfully : {}", flowIid);
 
+                ArpResolverMetadata gatewayArpMetadata = gatewayToArpMetadataMap.get(gatewayIp);
+                if (gatewayArpMetadata == null) {
+                    LOG.warn("No metadata found for gatewayIp: {}", gatewayIp);
+                    return;
+                }
+
                 //cache metadata
-                gatewayToArpMetadataMap.get(gatewayIp).setFlowToRemove(
-                        new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
+                gatewayArpMetadata.setFlowToRemove(new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
+
+                //get MAC DA for ARP packets
+                MacAddress arpRequestDestMacAddress = gatewayArpMetadata.getArpRequestDestMacAddress();
 
-                //Broadcast ARP request packets
+                //Send ARP request packets
                 for (NodeConnector egressNc : externalNetworkBridge.getNodeConnector()) {
                     KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> egressNcIid = nodeIid.child(
                             NodeConnector.class, new NodeConnectorKey(egressNc.getId()));
                     ListenableFuture<RpcResult<Void>> futureSendArpResult = arpSender.sendArp(
-                            senderAddress, gatewayIp, egressNcIid);
+                            senderAddress, gatewayIp, arpRequestDestMacAddress, egressNcIid);
                     Futures.addCallback(futureSendArpResult, logResult(gatewayIp, egressNcIid));
                 }
             }
@@ -304,7 +315,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
     private Flow createArpReplyToControllerFlow(final ArpMessageAddress senderAddress, final Ipv4Address ipForRequestedMac) {
         checkNotNull(senderAddress);
         checkNotNull(ipForRequestedMac);
-        FlowBuilder arpFlow = new FlowBuilder().setTableId(TABEL_FOR_ARP_FLOW)
+        FlowBuilder arpFlow = new FlowBuilder().setTableId(TABLE_FOR_ARP_FLOW)
             .setFlowName(ARP_REPLY_TO_CONTROLLER_FLOW_NAME)
             .setPriority(ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY)
             .setBufferId(OFConstants.OFP_NO_BUFFER)