Merge "BUG 6598 listen to a change on BridgeRefEntry"
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / FloatingIpGarpHandler.java
index b459a04c29d1eeb66ab0cc8afa7cb3f7695c2b7e..ce3fcbc032535e73cf70be70034f7cce7300c0f1 100644 (file)
@@ -7,21 +7,30 @@
  */
 package org.opendaylight.netvirt.vpnmanager;
 
+import com.google.common.net.InetAddresses;
 import java.math.BigInteger;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.ActionType;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.vpnmanager.utilities.VpnManagerCounters;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
@@ -35,23 +44,26 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.net.InetAddresses;
-
 public class FloatingIpGarpHandler extends AsyncDataTreeChangeListenerBase<RouterPorts, FloatingIpGarpHandler>
         implements AutoCloseable {
-
-    private DataBroker broker;
-    private PacketProcessingService packetService;
-    OdlInterfaceRpcService intfRpc;
-    private static final Logger s_logger = LoggerFactory.getLogger(FloatingIpGarpHandler.class);
-
-    public FloatingIpGarpHandler(DataBroker broker) {
+    private static final Logger LOG = LoggerFactory.getLogger(FloatingIpGarpHandler.class);
+    private final DataBroker dataBroker;
+    private final PacketProcessingService packetService;
+    private final IElanService elanService;
+    private final OdlInterfaceRpcService intfRpc;
+
+    public FloatingIpGarpHandler(final DataBroker dataBroker, final PacketProcessingService packetService,
+                                 final IElanService elanService, final OdlInterfaceRpcService interfaceManager) {
         super(RouterPorts.class, FloatingIpGarpHandler.class);
-        this.broker = broker;
+        this.dataBroker = dataBroker;
+        this.packetService = packetService;
+        this.elanService = elanService;
+        this.intfRpc = interfaceManager;
     }
 
-    public void setPacketService(PacketProcessingService packetService) {
-        this.packetService = packetService;
+    public void start() {
+        LOG.info("{} start", getClass().getSimpleName());
+        registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
     }
 
     @Override
@@ -66,6 +78,7 @@ public class FloatingIpGarpHandler extends AsyncDataTreeChangeListenerBase<Route
     @Override
     protected void update(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModificationBefore,
             RouterPorts dataObjectModificationAfter) {
+        VpnManagerCounters.garp_update_notification.inc();
         sendGarpForFloatingIps(dataObjectModificationAfter);
     }
 
@@ -80,37 +93,47 @@ public class FloatingIpGarpHandler extends AsyncDataTreeChangeListenerBase<Route
 
     private void sendGarpForIp(RouterPorts dataObjectModificationAfter, IpAddress ip) {
         if (ip.getIpv4Address() == null) {
-            s_logger.warn("Faild to send GARP for IP. recieved IPv6.");
+            LOG.warn("Faild to send GARP for IP. recieved IPv6.");
+            VpnManagerCounters.garp_sent_ipv6.inc();
             return;
         }
-        Port floatingIpPort = VpnUtil.getNeutronPortForFloatingIp(broker, ip);
+        Port floatingIpPort = VpnUtil.getNeutronPortForFloatingIp(dataBroker, ip);
         MacAddress floatingIpMac = floatingIpPort.getMacAddress();
-        String extNet = VpnUtil.getAssociatedExternalNetwork(broker, dataObjectModificationAfter.getRouterId());
-        Collection<String> interfaces = VpnmanagerServiceAccessor. getElanProvider().getExternalElanInterfaces(extNet);
+        String extNet = VpnUtil.getAssociatedExternalNetwork(dataBroker, dataObjectModificationAfter.getRouterId());
+        Collection<String> interfaces = elanService.getExternalElanInterfaces(extNet);
         for (String externalInterface:interfaces) {
             sendGarpOnInterface(ip, floatingIpMac, externalInterface);
-            
         }
     }
 
     private void sendGarpOnInterface(IpAddress ip, MacAddress floatingIpMac, String externalInterface) {
-        GetPortFromInterfaceInput getPortFromInterfaceInput = new GetPortFromInterfaceInputBuilder().setIntfName(externalInterface).build();
-        Future<RpcResult<GetPortFromInterfaceOutput>> interfacePort = intfRpc.getPortFromInterface(getPortFromInterfaceInput);
         try {
+            GetPortFromInterfaceInput getPortFromInterfaceInput = new GetPortFromInterfaceInputBuilder()
+                    .setIntfName(externalInterface).build();
+            Future<RpcResult<GetPortFromInterfaceOutput>> interfacePort = intfRpc
+                    .getPortFromInterface(getPortFromInterfaceInput);
+            if (interfacePort == null || !interfacePort.get().isSuccessful()) {
+                VpnManagerCounters.garp_interface_rpc_failed.inc();
+                return;
+            }
             BigInteger dpId = interfacePort.get().getResult().getDpid();
-            String portName = interfacePort.get().getResult().getPortname();
-            NodeConnectorRef ingress = MDSALUtil.getNodeConnRef(dpId, portName);
+            String portId = interfacePort.get().getResult().getPortno().toString();
+            NodeConnectorRef ingress = MDSALUtil.getNodeConnRef(dpId, portId);
             byte[] ipBytes = InetAddresses.forString(ip.getIpv4Address().getValue()).getAddress();
-            TransmitPacketInput arpRequestInput = ArpUtils.createArpRequestInput(dpId, ArpUtils.getMacInBytes(floatingIpMac.getValue()), ipBytes, ipBytes, ingress);
+            List<ActionInfo> actionList = new ArrayList<ActionInfo>();
+            actionList.add(new ActionInfo(ActionType.output, new String[]{portId}));
+
+            byte[] floatingMac = ArpUtils.getMacInBytes(floatingIpMac.getValue());
+            TransmitPacketInput arpRequestInput = ArpUtils.createArpRequestInput(dpId, null,
+                    floatingMac, VpnConstants.MAC_Broadcast, ipBytes, ipBytes, ingress, actionList);
             packetService.transmitPacket(arpRequestInput);
-        } catch (InterruptedException e) {
-            s_logger.warn("Faild to send GARP. rpc call getPortFromInterface did not return with a value.");
-        } catch (ExecutionException e) {
-            s_logger.warn("Faild to send GARP. rpc call getPortFromInterface did not return with a value.");
+            VpnManagerCounters.garp_sent.inc();
+        } catch (InterruptedException|ExecutionException e) {
+            LOG.warn("Faild to send GARP. rpc call getPortFromInterface did not return with a value.");
+            VpnManagerCounters.garp_sent_failed.inc();
         }
     }
 
-
     @Override
     protected void add(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModification) {
         sendGarpForFloatingIps(dataObjectModification);