<artifactId>natservice-api</artifactId>
<version>${vpnservices.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.genius</groupId>
+ <artifactId>arputil-api</artifactId>
+ <version>${genius.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.genius</groupId>
<artifactId>mdsalutil-api</artifactId>
remove_external_network_group, //
subnetmap_add, //
subnetmap_remove, //
- subnetmap_update;
+ subnetmap_update, //
+ port_not_found_for_floating, //
+ garp_sent, //
+ garp_sent_ipv6, //
+ garp_sent_failed;
private OccurenceCounter counter;
}
public static Port getNeutronPortForFloatingIp(DataBroker broker,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress targetIP) {
- return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_FLOATING_IP);
+ IpAddress targetIP) {
+ return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_FLOATING_IP);
}
public static Port getNeutronPortForRouterGetewayIp(DataBroker broker,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress targetIP) {
- return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
+ IpAddress targetIP) {
+ return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
}
public static Port getNeutronPortForIp(DataBroker broker,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress targetIP, String deviceType) {
+ IpAddress targetIP, String deviceType) {
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
portsIdentifier = InstanceIdentifier
.create(Neutron.class)
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
+import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
+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.PhysAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.SendArpRequestInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.interfaces.InterfaceAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.CreateFibEntryInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.CreateFibEntryInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.FibRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveVpnLabelInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveVpnLabelInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final FibRpcService fibService;
private final FloatingIPListener floatingIPListener;
private final IFibManager fibManager;
+ private final OdlArputilService arpUtilService;
static final BigInteger COOKIE_TUNNEL = new BigInteger("9000000", 16);
static final String FLOWID_PREFIX = "NAT.";
final IBgpManager bgpManager,
final FibRpcService fibService,
final FloatingIPListener floatingIPListener,
- final IFibManager fibManager) {
+ final IFibManager fibManager,
+ final OdlArputilService arputilService) {
this.dataBroker = dataBroker;
this.mdsalManager = mdsalManager;
this.vpnService = vpnService;
this.fibService = fibService;
this.floatingIPListener = floatingIPListener;
this.fibManager = fibManager;
+ this.arpUtilService = arputilService;
}
@Override
public void onAddFloatingIp(final BigInteger dpnId, final String routerId,
- Uuid networkId, final String interfaceName, final String externalIp, final String internalIp) {
+ Uuid networkId, final String interfaceName, final String externalIp,
+ final String internalIp) {
final String vpnName = getAssociatedVPN(networkId, routerId);
- if(vpnName == null) {
+ if (vpnName == null) {
LOG.info("No VPN associated with ext nw {} to handle add floating ip configuration {} in router {}",
networkId, externalIp, routerId);
return;
}
- GenerateVpnLabelInput labelInput = new GenerateVpnLabelInputBuilder().setVpnName(vpnName).setIpPrefix(externalIp).build();
+ GenerateVpnLabelInput labelInput = new GenerateVpnLabelInputBuilder().setVpnName(vpnName)
+ .setIpPrefix(externalIp).build();
Future<RpcResult<GenerateVpnLabelOutput>> labelFuture = vpnService.generateVpnLabel(labelInput);
- ListenableFuture<RpcResult<Void>> future = Futures.transform(JdkFutureAdapters.listenInPoolThread(labelFuture), new AsyncFunction<RpcResult<GenerateVpnLabelOutput>, RpcResult<Void>>() {
+ ListenableFuture<RpcResult<Void>> future = Futures.transform(JdkFutureAdapters.listenInPoolThread(labelFuture),
+ new AsyncFunction<RpcResult<GenerateVpnLabelOutput>, RpcResult<Void>>() {
@Override
public ListenableFuture<RpcResult<Void>> apply(RpcResult<GenerateVpnLabelOutput> result) throws Exception {
}
}
});
+
+ // Handle GARP transmission
+ final IpAddress extrenalAddress = IpAddressBuilder.getDefaultInstance(externalIp);
+ final IpAddress internalAddress = IpAddressBuilder.getDefaultInstance(internalIp);
+ Port neutronPortForIp = NatUtil.getNeutronPortForIp(dataBroker,internalAddress,
+ NeutronConstants.DEVICE_OWNER_NEUTRON_PORT);
+ if (neutronPortForIp == null) {
+ LOG.warn("No neutron port was found for external ip {} in router {}", internalIp, routerId);
+ NatServiceCounters.port_not_found_for_floating.inc();
+ return;
+ }
+ sendGarpOnInterface(neutronPortForIp.getUuid().getValue(), extrenalAddress, routerId);
+
}
@Override
public void onRemoveFloatingIp(final BigInteger dpnId, String routerId, Uuid networkId, final String externalIp,
String internalIp, final long label) {
final String vpnName = getAssociatedVPN(networkId, routerId);
- if(vpnName == null) {
+ if (vpnName == null) {
LOG.info("No VPN associated with ext nw {} to handle remove floating ip configuration {} in router {}",
networkId, externalIp, routerId);
return;
String vpnName = NatUtil.getAssociatedVPN(dataBroker, networkId, LOG);
return vpnName != null ? vpnName : routerId;
}
+
+ private void sendGarpOnInterface(String interfaceName, final IpAddress floatingIpAddress, final String routerId) {
+ if (floatingIpAddress.getIpv4Address() == null) {
+ LOG.warn("Faild to send GARP for IP. recieved IPv6.");
+ NatServiceCounters.garp_sent_ipv6.inc();
+ return;
+ }
+
+ try {
+ Port floatingPort = NatUtil.getNeutronPortForFloatingIp(dataBroker, floatingIpAddress);
+ PhysAddress floatingPortMac = new PhysAddress(floatingPort.getMacAddress().getValue());
+ List<InterfaceAddress> interfaceAddresses = new ArrayList<>();
+ interfaceAddresses.add(new InterfaceAddressBuilder()
+ .setInterface(interfaceName)
+ .setIpAddress(floatingIpAddress)
+ .setMacaddress(floatingPortMac).build());
+
+ SendArpRequestInput sendArpRequestInput = new SendArpRequestInputBuilder().setIpaddress(floatingIpAddress)
+ .setInterfaceAddress(interfaceAddresses).build();
+ arpUtilService.sendArpRequest(sendArpRequestInput);
+ NatServiceCounters.garp_sent.inc();
+ } catch (Exception e) {
+ LOG.error("Failed to send GARP request for floating ip {} from interface {}",
+ floatingIpAddress.getIpv4Address().getValue(), interfaceName, e);
+ NatServiceCounters.garp_sent_failed.inc();
+ }
+ }
+
}
interface="org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService" />
<odl:rpc-service id="fibRpcService"
interface="org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.FibRpcService" />
+ <odl:rpc-service id="odlArputilService"
+ interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService" />
<bean id="subnetmapListener"
class="org.opendaylight.netvirt.natservice.internal.SubnetmapListener"
<argument ref="fibRpcService" />
<argument ref="floatingIPListener" />
<argument ref="fibManager" />
+ <argument ref="odlArputilService" />
</bean>
<service ref="vpnFloatingIpHandler"
interface="org.opendaylight.netvirt.natservice.internal.FloatingIPHandler" />
public static final String DEVICE_OWNER_GATEWAY_INF = "network:router_gateway";
public static final String DEVICE_OWNER_ROUTER_INF = "network:router_interface";
public static final String DEVICE_OWNER_FLOATING_IP = "network:floatingip";
+ public static final String DEVICE_OWNER_NEUTRON_PORT = "compute:nova";
public static final String VNIC_TYPE_NORMAL = "normal";
public static final String VIF_TYPE_VHOSTUSER = "vhostuser";
public static final String VIF_TYPE_UNBOUND = "unbound";
+++ /dev/null
-/*
- * Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-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;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FloatingIpGarpHandler extends AsyncDataTreeChangeListenerBase<RouterPorts, FloatingIpGarpHandler>
- implements AutoCloseable {
- 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.dataBroker = dataBroker;
- this.packetService = packetService;
- this.elanService = elanService;
- this.intfRpc = interfaceManager;
- }
-
- public void start() {
- LOG.info("{} start", getClass().getSimpleName());
- registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
- }
-
- @Override
- protected InstanceIdentifier<RouterPorts> getWildCardPath() {
- return InstanceIdentifier.create(FloatingIpInfo.class).child(RouterPorts.class);
- }
-
- @Override
- protected void remove(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModification) {
- }
-
- @Override
- protected void update(InstanceIdentifier<RouterPorts> key, RouterPorts dataObjectModificationBefore,
- RouterPorts dataObjectModificationAfter) {
- VpnManagerCounters.garp_update_notification.inc();
- sendGarpForFloatingIps(dataObjectModificationAfter);
- }
-
- private void sendGarpForFloatingIps(RouterPorts dataObjectModificationAfter) {
- for (Ports port : dataObjectModificationAfter.getPorts()) {
- for (IpMapping ipMapping : port.getIpMapping()) {
- IpAddress ip = IpAddressBuilder.getDefaultInstance(ipMapping.getExternalIp());
- sendGarpForIp(dataObjectModificationAfter, ip);
- }
- }
- }
-
- private void sendGarpForIp(RouterPorts dataObjectModificationAfter, IpAddress ip) {
- if (ip.getIpv4Address() == null) {
- LOG.warn("Faild to send GARP for IP. recieved IPv6.");
- VpnManagerCounters.garp_sent_ipv6.inc();
- return;
- }
- Port floatingIpPort = VpnUtil.getNeutronPortForFloatingIp(dataBroker, ip);
- MacAddress floatingIpMac = floatingIpPort.getMacAddress();
- 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) {
- 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 portId = interfacePort.get().getResult().getPortno().toString();
- NodeConnectorRef ingress = MDSALUtil.getNodeConnRef(dpId, portId);
- byte[] ipBytes = InetAddresses.forString(ip.getIpv4Address().getValue()).getAddress();
- 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);
- 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);
- }
-
- @Override
- protected FloatingIpGarpHandler getDataTreeChangeListener() {
- return this;
- }
-}