2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.vpnmanager;
10 import java.math.BigInteger;
11 import java.util.Collection;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.Future;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
17 import org.opendaylight.genius.mdsalutil.MDSALUtil;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.opendaylight.yangtools.yang.common.RpcResult;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 import com.google.common.net.InetAddresses;
40 public class FloatingIpGarpHandler extends AsyncDataTreeChangeListenerBase<RouterPorts, FloatingIpGarpHandler>
41 implements AutoCloseable {
43 private DataBroker broker;
44 private PacketProcessingService packetService;
45 OdlInterfaceRpcService intfRpc;
46 private static final Logger s_logger = LoggerFactory.getLogger(FloatingIpGarpHandler.class);
48 public FloatingIpGarpHandler(DataBroker broker) {
49 super(RouterPorts.class, FloatingIpGarpHandler.class);
53 public void setPacketService(PacketProcessingService packetService) {
54 this.packetService = packetService;
58 protected InstanceIdentifier<RouterPorts> getWildCardPath() {
59 return InstanceIdentifier.create(FloatingIpInfo.class).child(RouterPorts.class);
63 protected void remove(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModification) {
67 protected void update(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModificationBefore,
68 RouterPorts dataObjectModificationAfter) {
69 sendGarpForFloatingIps(dataObjectModificationAfter);
72 private void sendGarpForFloatingIps(RouterPorts dataObjectModificationAfter) {
73 for (Ports port : dataObjectModificationAfter.getPorts()) {
74 for (IpMapping ipMapping : port.getIpMapping()) {
75 IpAddress ip = IpAddressBuilder.getDefaultInstance(ipMapping.getExternalIp());
76 sendGarpForIp(dataObjectModificationAfter, ip);
81 private void sendGarpForIp(RouterPorts dataObjectModificationAfter, IpAddress ip) {
82 if (ip.getIpv4Address() == null) {
83 s_logger.warn("Faild to send GARP for IP. recieved IPv6.");
86 Port floatingIpPort = VpnUtil.getNeutronPortForFloatingIp(broker, ip);
87 MacAddress floatingIpMac = floatingIpPort.getMacAddress();
88 String extNet = VpnUtil.getAssociatedExternalNetwork(broker, dataObjectModificationAfter.getRouterId());
89 Collection<String> interfaces = VpnmanagerServiceAccessor. getElanProvider().getExternalElanInterfaces(extNet);
90 for (String externalInterface:interfaces) {
91 sendGarpOnInterface(ip, floatingIpMac, externalInterface);
96 private void sendGarpOnInterface(IpAddress ip, MacAddress floatingIpMac, String externalInterface) {
97 GetPortFromInterfaceInput getPortFromInterfaceInput = new GetPortFromInterfaceInputBuilder().setIntfName(externalInterface).build();
98 Future<RpcResult<GetPortFromInterfaceOutput>> interfacePort = intfRpc.getPortFromInterface(getPortFromInterfaceInput);
100 BigInteger dpId = interfacePort.get().getResult().getDpid();
101 String portName = interfacePort.get().getResult().getPortname();
102 NodeConnectorRef ingress = MDSALUtil.getNodeConnRef(dpId, portName);
103 byte[] ipBytes = InetAddresses.forString(ip.getIpv4Address().getValue()).getAddress();
104 TransmitPacketInput arpRequestInput = ArpUtils.createArpRequestInput(dpId, ArpUtils.getMacInBytes(floatingIpMac.getValue()), ipBytes, ipBytes, ingress);
105 packetService.transmitPacket(arpRequestInput);
106 } catch (InterruptedException e) {
107 s_logger.warn("Faild to send GARP. rpc call getPortFromInterface did not return with a value.");
108 } catch (ExecutionException e) {
109 s_logger.warn("Faild to send GARP. rpc call getPortFromInterface did not return with a value.");
115 protected void add(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModification) {
116 sendGarpForFloatingIps(dataObjectModification);
120 protected FloatingIpGarpHandler getDataTreeChangeListener() {