yang-gen-config
yang-gen-sal
maven-metadata-local.xml
-.metadata
-.recommenders
-/.gitignore
}
}
}
-
- container subnet-dhcp-port-data {
- config true;
- list subnet-to-dhcp-port {
- key "subnet-id";
- leaf subnet-id { type string;}
- leaf port-name { type string;}
- leaf port-fixedip { type string;}
- leaf port-macaddress { type string;}
- }
- }
-
}
\ No newline at end of file
import java.math.BigInteger;
import java.util.List;
+
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.netvirt.dhcpservice.jobs.DhcpInterfaceAddJob;
import org.opendaylight.netvirt.dhcpservice.jobs.DhcpInterfaceRemoveJob;
import org.opendaylight.netvirt.dhcpservice.jobs.DhcpInterfaceUpdateJob;
-import org.opendaylight.netvirt.elanmanager.api.IElanService;
-import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final DhcpExternalTunnelManager dhcpExternalTunnelManager;
private DataStoreJobCoordinator dataStoreJobCoordinator;
private final IInterfaceManager interfaceManager;
- private final IElanService elanService;
public DhcpInterfaceEventListener(DhcpManager dhcpManager, DataBroker dataBroker,
DhcpExternalTunnelManager dhcpExternalTunnelManager,
- IInterfaceManager interfaceManager, IElanService elanService) {
+ IInterfaceManager interfaceManager) {
super(Interface.class, DhcpInterfaceEventListener.class);
this.dhcpManager = dhcpManager;
this.dataBroker = dataBroker;
this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
this.interfaceManager = interfaceManager;
- this.elanService = elanService;
registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
dataStoreJobCoordinator = DataStoreJobCoordinator.getInstance();
}
return;
}
String interfaceName = del.getName();
- Port port = dhcpManager.getNeutronPort(interfaceName);
- if (NeutronConstants.IS_DHCP_PORT.test(port)) {
- return;
- }
NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
BigInteger dpnId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
DhcpInterfaceRemoveJob job = new DhcpInterfaceRemoveJob(dhcpManager, dhcpExternalTunnelManager,
- dataBroker, del, dpnId, interfaceManager, elanService);
+ dataBroker, interfaceName, dpnId, interfaceManager);
dataStoreJobCoordinator.enqueueJob(DhcpServiceUtils.getJobKey(interfaceName), job, DhcpMConstants.RETRY_COUNT);
}
@Override
protected void add(InstanceIdentifier<Interface> identifier, Interface add) {
String interfaceName = add.getName();
- LOG.trace("DhcpInterfaceAddJob to be created for interface {}", interfaceName);
List<String> ofportIds = add.getLowerLayerIf();
if (ofportIds == null || ofportIds.isEmpty()) {
return;
}
- Port port = dhcpManager.getNeutronPort(interfaceName);
- if (NeutronConstants.IS_DHCP_PORT.test(port)) {
- return;
- }
-
NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
BigInteger dpnId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
DhcpInterfaceAddJob job = new DhcpInterfaceAddJob(dhcpManager, dhcpExternalTunnelManager, dataBroker,
- add, dpnId, interfaceManager, elanService);
+ interfaceName, dpnId, interfaceManager);
dataStoreJobCoordinator.enqueueJob(DhcpServiceUtils.getJobKey(interfaceName), job, DhcpMConstants.RETRY_COUNT);
}
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
-import javax.inject.Named;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.netvirt.dhcpservice.api.DhcpMConstants;
-import org.opendaylight.netvirt.elanmanager.api.IElanService;
import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
private final DataBroker broker;
private final DhcpExternalTunnelManager dhcpExternalTunnelManager;
private final IInterfaceManager interfaceManager;
- private final IElanService elanService;
private int dhcpOptLeaseTime = 0;
private String dhcpOptDefDomainName;
public DhcpManager(final IMdsalApiManager mdsalApiManager,
final INeutronVpnManager neutronVpnManager,
final DhcpserviceConfig config, final DataBroker dataBroker,
- final DhcpExternalTunnelManager dhcpExternalTunnelManager, final IInterfaceManager interfaceManager,
- final @Named("elanService") IElanService ielanService) {
+ final DhcpExternalTunnelManager dhcpExternalTunnelManager, final IInterfaceManager interfaceManager) {
this.mdsalUtil = mdsalApiManager;
this.neutronVpnService = neutronVpnManager;
this.config = config;
this.broker = dataBroker;
this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
this.interfaceManager = interfaceManager;
- this.elanService = ielanService;
+
configureLeaseDuration(DhcpMConstants.DEFAULT_LEASE_TIME);
}
@PostConstruct
public void init() {
- LOG.trace("Netvirt DHCP Manager Init .... {}",config.isControllerDhcpEnabled());
if (config.isControllerDhcpEnabled()) {
- dhcpInterfaceEventListener = new DhcpInterfaceEventListener(this, broker, dhcpExternalTunnelManager,
- interfaceManager, elanService);
+ dhcpInterfaceEventListener =
+ new DhcpInterfaceEventListener(this, broker, dhcpExternalTunnelManager, interfaceManager);
dhcpInterfaceConfigListener = new DhcpInterfaceConfigListener(broker, dhcpExternalTunnelManager, this);
LOG.info("DHCP Service initialized");
}
*/
package org.opendaylight.netvirt.dhcpservice;
-import com.google.common.util.concurrent.ListenableFuture;
import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.List;
-import java.util.function.Consumer;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
-import javax.inject.Named;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
-import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput.ArpReponderInputBuilder;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
-import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
-import org.opendaylight.netvirt.elanmanager.api.IElanService;
-import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
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.neutron.binding.rev150712.PortBindingExtension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
private static final Logger LOG = LoggerFactory.getLogger(DhcpNeutronPortListener.class);
private final DhcpExternalTunnelManager dhcpExternalTunnelManager;
- private final IElanService elanService;
private final DataBroker broker;
- private final DhcpserviceConfig config;
- private final IInterfaceManager interfaceManager;
+ private DhcpserviceConfig config;
@Inject
- public DhcpNeutronPortListener(DataBroker db, DhcpExternalTunnelManager dhcpExternalTunnelManager,
- @Named("elanService") IElanService ielanService, IInterfaceManager interfaceManager,
- DhcpserviceConfig config) {
+ public DhcpNeutronPortListener(final DataBroker db, final DhcpExternalTunnelManager dhcpExternalTunnelManager,
+ final DhcpserviceConfig config) {
super(Port.class, DhcpNeutronPortListener.class);
this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
- this.elanService = ielanService;
- this.interfaceManager = interfaceManager;
this.broker = db;
this.config = config;
}
}
@Override
- @SuppressWarnings("deprecation")
protected void remove(InstanceIdentifier<Port> identifier, Port del) {
LOG.trace("Port removed: {}", del);
- if (NeutronConstants.IS_ODL_DHCP_PORT.test(del)) {
- DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- portDataStoreCoordinator.enqueueJob(getJobKey(del), () -> {
- WriteTransaction wrtConfigTxn = broker.newWriteOnlyTransaction();
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- DhcpServiceUtils.removeSubnetDhcpPortData(del, subnetDhcpPortIdfr -> wrtConfigTxn
- .delete(LogicalDatastoreType.CONFIGURATION, subnetDhcpPortIdfr));
- processArpResponderForElanDpns(del, arpInput -> {
- LOG.trace("Removing ARP RESPONDER Flows for dhcp port {} with ipaddress {} with mac {} on dpn {}",
- arpInput.getInterfaceName(), arpInput.getSpa(), arpInput.getSha(), arpInput.getDpId());
- elanService.removeArpResponderFlow(arpInput);
- });
- futures.add(wrtConfigTxn.submit());
- return futures;
- });
- }
if (isVnicTypeDirectOrMacVtap(del)) {
removePort(del);
}
}
- private String getJobKey(Port port) {
- return "PORT- " + port.getUuid().getValue();
- }
-
@Override
protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
LOG.trace("Port changed to {}", update);
}
@Override
- @SuppressWarnings("deprecation")
protected void add(InstanceIdentifier<Port> identifier, Port add) {
LOG.trace("Port added {}", add);
- if (NeutronConstants.IS_ODL_DHCP_PORT.test(add)) {
- DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- portDataStoreCoordinator.enqueueJob(getJobKey(add), () -> {
- WriteTransaction wrtConfigTxn = broker.newWriteOnlyTransaction();
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- DhcpServiceUtils.createSubnetDhcpPortData(add, (subnetDhcpPortIdfr, subnetToDhcpport) -> wrtConfigTxn
- .put(LogicalDatastoreType.CONFIGURATION, subnetDhcpPortIdfr, subnetToDhcpport));
- processArpResponderForElanDpns(add, arpInput -> {
- LOG.trace("Installing ARP RESPONDER Flows for dhcp port {} ipaddress {} with mac {} on dpn {}",
- arpInput.getInterfaceName(), arpInput.getSpa(), arpInput.getSha(), arpInput.getDpId());
- ArpReponderInputBuilder builder = new ArpReponderInputBuilder(arpInput);
- builder.setInstructions(ArpResponderUtil.getInterfaceInstructions(interfaceManager,
- arpInput.getInterfaceName(), arpInput.getSpa(), arpInput.getSha()));
- elanService.addArpResponderFlow(builder.buildForInstallFlow());
- });
- futures.add(wrtConfigTxn.submit());
- return futures;
- });
- }
if (!isVnicTypeDirectOrMacVtap(add)) {
return;
}
return;
}
dhcpExternalTunnelManager.updateVniMacToPortCache(new BigInteger(segmentationId), macAddress, port);
-
}
private String getMacAddress(Port port) {
protected DhcpNeutronPortListener getDataTreeChangeListener() {
return DhcpNeutronPortListener.this;
}
-
- /**
- * Handle(Add/Remove) ARP Responder for DHCP IP on all the DPNs when DHCP is
- * enabled/disabled on subnet add or update or delete.
- *
- * @param port
- * DHCP port for which ARP Responder flow to be added when dhcp
- * flag is enabled on the subnet or DHCP port for which ARP
- * Responder flow to be removed when dhcp flag is disabled on the
- * Subnet
- * @param arpResponderAction
- * ARP Responder Action to be performed i.e., add or remove flow
- */
- private void processArpResponderForElanDpns(Port port, Consumer<ArpResponderInput> arpResponderAction) {
-
- java.util.Optional<String> ip4Address = DhcpServiceUtils.getIpV4Address(port);
- if (!ip4Address.isPresent()) {
- LOG.warn("There is no IPv4Address for port {}, not performing ARP responder add/remove flow operation",
- port.getName());
- return;
- }
- ElanHelper.getDpnInterfacesInElanInstance(broker, port.getNetworkId().getValue()).stream()
- .map(ifName -> DhcpServiceUtils.getInterfaceInfo(interfaceManager, ifName)).forEach(interfaceInfo -> {
- ArpResponderInput arpResponderInput = new ArpResponderInput.ArpReponderInputBuilder()
- .setDpId(interfaceInfo.getDpId()).setInterfaceName(interfaceInfo.getInterfaceName())
- .setLportTag(interfaceInfo.getInterfaceTag()).setSha(port.getMacAddress().getValue())
- .setSpa(ip4Address.get()).build();
- arpResponderAction.accept(arpResponderInput);
- });
-
- }
-
}
\ No newline at end of file
*/
package org.opendaylight.netvirt.dhcpservice;
-import com.google.common.base.Optional;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.opendaylight.controller.liblldp.EtherTypes;
import org.opendaylight.controller.liblldp.NetUtils;
import org.opendaylight.controller.liblldp.PacketException;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.config.rev150710.DhcpserviceConfig;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
@Singleton
public class DhcpPktHandler implements PacketProcessingListener {
private final IInterfaceManager interfaceManager;
private final DhcpserviceConfig config;
private final DhcpAllocationPoolManager dhcpAllocationPoolMgr;
- private final DataBroker broker;
@Inject
public DhcpPktHandler(final DhcpManager dhcpManager,
final PacketProcessingService pktService,
final IInterfaceManager interfaceManager,
final DhcpserviceConfig config,
- final DhcpAllocationPoolManager dhcpAllocationPoolMgr,
- final DataBroker dataBroker) {
+ final DhcpAllocationPoolManager dhcpAllocationPoolMgr) {
this.interfaceManagerRpc = interfaceManagerRpc;
this.pktService = pktService;
this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
this.interfaceManager = interfaceManager;
this.config = config;
this.dhcpAllocationPoolMgr = dhcpAllocationPoolMgr;
- this.broker = dataBroker;
}
//TODO: Handle this in a separate thread
private DhcpInfo getDhcpInfo(Port port, Subnet subnet) {
DhcpInfo dhcpInfo = null;
- List<IpAddress> dnsServers = subnet.getDnsNameservers();
if (port != null && subnet != null) {
String clientIp = getIpv4Address(port);
String serverIp = null;
- /* If neutronport-dhcp flag was enabled and an ODL network DHCP Port data was made available use the
- * ports Fixed IP as server IP for DHCP communication.
- */
- if (config.getControllerDhcpMode() == DhcpserviceConfig.ControllerDhcpMode.UseOdlDhcpNeutronPort) {
- java.util.Optional<SubnetToDhcpPort> dhcpPortData = DhcpServiceUtils.getSubnetDhcpPortData(broker,
- subnet.getUuid().getValue());
- if (dhcpPortData.isPresent()) {
- serverIp = dhcpPortData.get().getPortFixedip();
- dhcpInfo = new DhcpInfo();
- if (isIpv4Address(subnet.getGatewayIp())) {
- dhcpInfo.setGatewayIp(subnet.getGatewayIp().getIpv4Address().getValue());
- }
- dhcpInfo.setClientIp(clientIp).setServerIp(serverIp)
- .setCidr(String.valueOf(subnet.getCidr().getValue())).setHostRoutes(subnet.getHostRoutes())
- .setDnsServersIpAddrs(dnsServers);
- } else {
- // DHCP Neutron Port not found for this network
- LOG.error("Neutron DHCP port is not available for the Subnet {} and port {}.", subnet.getUuid(),
- port.getUuid());
- }
- //When neutronport-dhcp flag is disabled continue running DHCP Server by hijacking the subnet-gateway-ip
- } else if (isIpv4Address(subnet.getGatewayIp())) {
+ if (isIpv4Address(subnet.getGatewayIp())) {
serverIp = subnet.getGatewayIp().getIpv4Address().getValue();
- if (clientIp != null && serverIp != null) {
- dhcpInfo = new DhcpInfo();
- dhcpInfo.setClientIp(clientIp).setServerIp(serverIp)
- .setCidr(String.valueOf(subnet.getCidr().getValue())).setHostRoutes(subnet.getHostRoutes())
- .setDnsServersIpAddrs(dnsServers).setGatewayIp(serverIp);
- }
+ }
+ if (clientIp != null && serverIp != null) {
+ List<IpAddress> dnsServers = subnet.getDnsNameservers();
+ dhcpInfo = new DhcpInfo();
+ dhcpInfo.setClientIp(clientIp).setServerIp(serverIp)
+ .setCidr(String.valueOf(subnet.getCidr().getValue())).setHostRoutes(subnet.getHostRoutes())
+ .setDnsServersIpAddrs(dnsServers).setGatewayIp(serverIp);
}
}
return dhcpInfo;
}
private void setCommonOptions(DHCP pkt, DhcpInfo dhcpInfo) {
- String serverIp = dhcpInfo.getServerIp();
+ String gwIp = dhcpInfo.getGatewayIp();
if (pkt.getMsgType() != DHCPConstants.MSG_NAK) {
setNonNakOptions(pkt, dhcpInfo);
}
* options to maintain order. If we can't fill them, unset to avoid
* sending wrong information in reply.
*/
- if (serverIp != null) {
- pkt.setOptionInetAddr(DHCPConstants.OPT_SERVER_IDENTIFIER, serverIp);
+ if (gwIp != null) {
+ pkt.setOptionInetAddr(DHCPConstants.OPT_SERVER_IDENTIFIER, gwIp);
} else {
pkt.unsetOption(DHCPConstants.OPT_SERVER_IDENTIFIER);
}
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
-import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
-import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.SubnetDhcpPortData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPortBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPortKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return;
}
List<MatchInfo> matches = getDhcpMatch(vmMacAddress);
+
List<InstructionInfo> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
.addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
}
- @SuppressWarnings("checkstyle:IllegalCatch")
- protected static void createSubnetDhcpPortData(Port port,
- BiConsumer<InstanceIdentifier<SubnetToDhcpPort>, SubnetToDhcpPort> consumer) {
- java.util.Optional<String> ip4Address = getIpV4Address(port);
- java.util.Optional<String> subnetId = getNeutronSubnetId(port);
- if (!(ip4Address.isPresent() && subnetId.isPresent())) {
- return;
- }
- LOG.trace("Adding SubnetPortData entry for subnet {}", subnetId.get());
- InstanceIdentifier<SubnetToDhcpPort> identifier = buildSubnetToDhcpPort(subnetId.get());
- SubnetToDhcpPort subnetToDhcpPort = getSubnetToDhcpPort(port, subnetId.get(), ip4Address.get());
- try {
- LOG.trace("Adding to SubnetToDhcpPort subnet {} mac {}.", subnetId.get(),
- port.getMacAddress().getValue());
- consumer.accept(identifier, subnetToDhcpPort);
- } catch (Exception e) {
- LOG.error("Failure while creating SubnetToDhcpPort map for network {}.", port.getNetworkId(), e);
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- protected static void removeSubnetDhcpPortData(Port port, Consumer<InstanceIdentifier<SubnetToDhcpPort>> consumer) {
- java.util.Optional<String> subnetId = getNeutronSubnetId(port);
- if (!subnetId.isPresent()) {
- return;
- }
- LOG.trace("Removing NetworkPortData entry for Subnet {}", subnetId);
- InstanceIdentifier<SubnetToDhcpPort> identifier = buildSubnetToDhcpPort(subnetId.get());
- try {
- consumer.accept(identifier);
- LOG.trace("Deleted SubnetDhcpPort for Network {}", subnetId.get());
- } catch (Exception e) {
- LOG.error("Failure while removing SubnetToDhcpPort for subnet {}.", subnetId, e);
- }
-
- }
-
- static InstanceIdentifier<SubnetToDhcpPort> buildSubnetToDhcpPort(String subnetId) {
- return InstanceIdentifier.builder(SubnetDhcpPortData.class)
- .child(SubnetToDhcpPort.class, new SubnetToDhcpPortKey(subnetId)).build();
- }
-
- public static java.util.Optional<SubnetToDhcpPort> getSubnetDhcpPortData(DataBroker broker, String subnetId) {
- InstanceIdentifier<SubnetToDhcpPort> id = buildSubnetToDhcpPort(subnetId);
- try {
- return java.util.Optional
- .ofNullable(SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.CONFIGURATION, id));
- } catch (ReadFailedException e) {
- LOG.warn("Failed to read SubnetToDhcpPort for DS due to error {}", e.getMessage());
- }
- return java.util.Optional.empty();
- }
-
static IpAddress convertIntToIp(int ipn) {
String[] array = IntStream.of(24, 16, 8, 0) //
.map(x -> (ipn >> x) & 0xFF).boxed() //
return result;
}
-
- static SubnetToDhcpPort getSubnetToDhcpPort(Port port, String subnetId, String ipAddress) {
- return new SubnetToDhcpPortBuilder()
- .setKey(new SubnetToDhcpPortKey(subnetId))
- .setSubnetId(subnetId).setPortName(port.getUuid().getValue())
- .setPortMacaddress(port.getMacAddress().getValue()).setPortFixedip(ipAddress).build();
- }
-
- static InterfaceInfo getInterfaceInfo(IInterfaceManager interfaceManager, String interfaceName) {
- return interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
- }
-
- static BigInteger getDpIdFromInterface(IInterfaceManager interfaceManager, String interfaceName) {
- return interfaceManager.getDpnForInterface(interfaceName);
- }
-
- public static java.util.Optional<String> getIpV4Address(Port port) {
- if (port.getFixedIps() == null) {
- return java.util.Optional.empty();
- }
- return port.getFixedIps().stream().filter(DhcpServiceUtils::isIpV4AddressAvailable)
- .map(v -> v.getIpAddress().getIpv4Address().getValue()).findFirst();
- }
-
- public static java.util.Optional<String> getNeutronSubnetId(Port port) {
- if (port.getFixedIps() == null) {
- return java.util.Optional.empty();
- }
- return port.getFixedIps().stream().filter(DhcpServiceUtils::isIpV4AddressAvailable)
- .map(v -> v.getSubnetId().getValue()).findFirst();
- }
-
- public static boolean isIpV4AddressAvailable(FixedIps fixedIp) {
- return fixedIp != null && fixedIp.getIpAddress() != null && fixedIp.getIpAddress().getIpv4Address() != null;
- }
-
}
\ No newline at end of file
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import org.opendaylight.netvirt.dhcpservice.DhcpManager;
import org.opendaylight.netvirt.dhcpservice.DhcpServiceUtils;
import org.opendaylight.netvirt.dhcpservice.api.DhcpMConstants;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput.ArpReponderInputBuilder;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
-import org.opendaylight.netvirt.elanmanager.api.IElanService;
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.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710._interface.name.mac.addresses.InterfaceNameMacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710._interface.name.mac.addresses.InterfaceNameMacAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710._interface.name.mac.addresses.InterfaceNameMacAddressKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
DhcpManager dhcpManager;
DhcpExternalTunnelManager dhcpExternalTunnelManager;
DataBroker dataBroker;
- private final Interface interfaceAdd;
+ String interfaceName;
BigInteger dpnId;
IInterfaceManager interfaceManager;
- private final IElanService elanService;
private static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
@Override
public void onSuccess(Void result) {
};
public DhcpInterfaceAddJob(DhcpManager dhcpManager, DhcpExternalTunnelManager dhcpExternalTunnelManager,
- DataBroker dataBroker, Interface interfaceAdd, BigInteger dpnId,
- IInterfaceManager interfaceManager, IElanService elanService) {
+ DataBroker dataBroker, String interfaceName, BigInteger dpnId,
+ IInterfaceManager interfaceManager) {
super();
this.dhcpManager = dhcpManager;
this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
this.dataBroker = dataBroker;
- this.interfaceAdd = interfaceAdd;
+ this.interfaceName = interfaceName;
this.dpnId = dpnId;
this.interfaceManager = interfaceManager;
- this.elanService = elanService;
}
@Override
public List<ListenableFuture<Void>> call() throws Exception {
List<ListenableFuture<Void>> futures = new ArrayList<>();
- String interfaceName = interfaceAdd.getName();
LOG.trace("Received add DCN for interface {}, dpid {}", interfaceName, dpnId);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
if (!dpnId.equals(DhcpMConstants.INVALID_DPID)) {
Port port = dhcpManager.getNeutronPort(interfaceName);
Subnet subnet = dhcpManager.getNeutronSubnet(port);
- if (null == subnet || !subnet.isEnableDhcp()) {
- LOG.debug("DHCP is not enabled for port {}", port.getName());
- return Collections.emptyList();
+ if (null != subnet && subnet.isEnableDhcp()) {
+ LOG.info("DhcpInterfaceEventListener add isEnableDhcp" + subnet.isEnableDhcp());
+ installDhcpEntries(interfaceName, dpnId, futures);
}
- LOG.info("DhcpInterfaceEventListener add isEnableDhcp:{}", subnet.isEnableDhcp());
- installDhcpEntries(interfaceAdd.getName(), dpnId, futures);
- LOG.trace("Checking ElanDpnInterface {} for dpn {} ", interfaceName, dpnId);
- String subnetId = subnet.getUuid().getValue();
- java.util.Optional<SubnetToDhcpPort> subnetToDhcp = DhcpServiceUtils
- .getSubnetDhcpPortData(dataBroker, subnetId);
- if (!subnetToDhcp.isPresent()) {
- return Collections.emptyList();
- }
- LOG.trace("Installing the Arp responder for interface {} with DHCP MAC {} & IP {}.", interfaceName,
- subnetToDhcp.get().getPortMacaddress(), subnetToDhcp.get().getPortFixedip());
- ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
- builder.setDpId(dpnId).setInterfaceName(interfaceName).setSpa(subnetToDhcp.get().getPortFixedip())
- .setSha(subnetToDhcp.get().getPortMacaddress()).setLportTag(interfaceAdd.getIfIndex());
- builder.setInstructions(ArpResponderUtil.getInterfaceInstructions(interfaceManager, interfaceName,
- subnetToDhcp.get().getPortFixedip(), subnetToDhcp.get().getPortMacaddress()));
- elanService.addArpResponderFlow(builder.buildForInstallFlow());
}
return futures;
}
import org.opendaylight.netvirt.dhcpservice.DhcpExternalTunnelManager;
import org.opendaylight.netvirt.dhcpservice.DhcpManager;
import org.opendaylight.netvirt.dhcpservice.DhcpServiceUtils;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput;
-import org.opendaylight.netvirt.elanmanager.api.IElanService;
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.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.InterfaceNameMacAddresses;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710._interface.name.mac.addresses.InterfaceNameMacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710._interface.name.mac.addresses.InterfaceNameMacAddressKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
DhcpManager dhcpManager;
DhcpExternalTunnelManager dhcpExternalTunnelManager;
DataBroker dataBroker;
- Interface interfaceDel;
+ String interfaceName;
BigInteger dpnId;
IInterfaceManager interfaceManager;
- private final IElanService elanService;
private static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
@Override
public void onSuccess(Void result) {
public DhcpInterfaceRemoveJob(DhcpManager dhcpManager, DhcpExternalTunnelManager dhcpExternalTunnelManager,
DataBroker dataBroker,
- Interface interfaceDel, BigInteger dpnId, IInterfaceManager interfaceManager,
- IElanService elanService) {
+ String interfaceName, BigInteger dpnId, IInterfaceManager interfaceManager) {
super();
this.dhcpManager = dhcpManager;
this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
this.dataBroker = dataBroker;
- this.interfaceDel = interfaceDel;
+ this.interfaceName = interfaceName;
this.dpnId = dpnId;
this.interfaceManager = interfaceManager;
- this.elanService = elanService;
}
@Override
public List<ListenableFuture<Void>> call() throws Exception {
List<ListenableFuture<Void>> futures = new ArrayList<>();
- String interfaceName = interfaceDel.getName();
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
if (iface != null) {
return futures;
}
}
- Port port = dhcpManager.getNeutronPort(interfaceName);
- java.util.Optional<String> subnetId = DhcpServiceUtils.getNeutronSubnetId(port);
- if (subnetId.isPresent()) {
- java.util.Optional<SubnetToDhcpPort> subnetToDhcp = DhcpServiceUtils.getSubnetDhcpPortData(dataBroker,
- subnetId.get());
- if (subnetToDhcp.isPresent()) {
- LOG.trace("Removing ArpResponder flow for last interface {} on DPN {}", interfaceName, dpnId);
- ArpResponderInput arpInput = new ArpResponderInput.ArpReponderInputBuilder().setDpId(dpnId)
- .setInterfaceName(interfaceName).setSpa(subnetToDhcp.get().getPortFixedip())
- .setLportTag(interfaceDel.getIfIndex()).buildForRemoveFlow();
- elanService.removeArpResponderFlow(arpInput);
- }
- }
- unInstallDhcpEntries(interfaceDel.getName(), dpnId, futures);
+ unInstallDhcpEntries(interfaceName, dpnId, futures);
return futures;
}
<dhcpservice-config xmlns="urn:opendaylight:params:xml:ns:yang:dhcpservice:config">
<controller-dhcp-enabled>false</controller-dhcp-enabled>
<dhcp-dynamic-allocation-pool-enabled>false</dhcp-dynamic-allocation-pool-enabled>
- <controller-dhcp-mode>use-odl-dhcp-neutron-port</controller-dhcp-mode>
</dhcpservice-config>
interface="org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager" />
<reference id="iInterfaceManager"
interface="org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager" />
- <reference id="elanService"
- interface="org.opendaylight.netvirt.elanmanager.api.IElanService" />
<odl:rpc-service id="odlInterfaceRpcService"
interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService" />
type boolean;
default false;
}
-
- leaf controller-dhcp-mode {
- description "Specify the controller DHCP mode to use Neutron port or Subnet gateway as DHCP server IP";
- type enumeration {
- enum "use-odl-dhcp-neutron-port";
- enum "use-subnet-gateway-ip";
- }
- default "use-odl-dhcp-neutron-port";
- }
-
}
}
<artifactId>idmanager-api</artifactId>
<version>${genius.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.genius</groupId>
- <artifactId>idmanager-api</artifactId>
- <version>${genius.version}</version>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>neutronvpn-api</artifactId>
+++ /dev/null
-/*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.elan.arp.responder;
-
-import com.google.common.base.Strings;
-
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.List;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-
-public class ArpResponderInput {
-
- private BigInteger dpId;
- private String interfaceName;
- private String spa;
- private String sha;
- private int lportTag;
- private List<Instruction> instructions;
-
-
- private ArpResponderInput() {}
-
- public BigInteger getDpId() {
- return dpId;
- }
-
- public String getInterfaceName() {
- return interfaceName;
- }
-
- public String getSpa() {
- return spa;
- }
-
- public String getSha() {
- return sha;
- }
-
- public int getLportTag() {
- return lportTag;
- }
-
- public List<Instruction> getInstructions() {
- if (instructions == null) {
- instructions = Collections.emptyList();
- }
- return instructions;
- }
-
- public static class ArpReponderInputBuilder {
-
- private ArpResponderInput input;
-
- public ArpReponderInputBuilder() {
- input = new ArpResponderInput();
- }
-
- public ArpResponderInput build() {
- return input;
- }
-
- public ArpResponderInput buildForInstallFlow() {
-
- if (input.dpId == null || Strings.isNullOrEmpty(input.interfaceName) || Strings.isNullOrEmpty(input.spa)
- || Strings.isNullOrEmpty(input.sha) || input.lportTag == 0 || input.instructions.isEmpty()) {
- throw new AssertionError("Missing mandatory fields for ARP Responder Install Flow");
- }
-
- return input;
- }
-
- public ArpResponderInput buildForRemoveFlow() {
-
- if (input.dpId == null || Strings.isNullOrEmpty(input.interfaceName) || Strings.isNullOrEmpty(input.spa)
- || input.lportTag == 0) {
- throw new AssertionError("Missing mandatory fields for ARP Responder Install Flow");
- }
-
- return input;
- }
-
- public ArpReponderInputBuilder(ArpResponderInput input) {
- super();
- this.input = input;
- }
-
- public ArpReponderInputBuilder setDpId(BigInteger dpId) {
- input.dpId = dpId;
- return this;
- }
-
- public ArpReponderInputBuilder setInterfaceName(String interfaceName) {
- input.interfaceName = interfaceName;
- return this;
- }
-
- public ArpReponderInputBuilder setSpa(String spa) {
- input.spa = spa;
- return this;
- }
-
- public ArpReponderInputBuilder setSha(String sha) {
- input.sha = sha;
- return this;
- }
-
- public ArpReponderInputBuilder setLportTag(int lportTag) {
- input.lportTag = lportTag;
- return this;
- }
-
- public ArpReponderInputBuilder setInstructions(List<Instruction> instructions) {
- input.instructions = instructions == null ? Collections.emptyList() : instructions;
- return this;
- }
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. 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.elan.arp.responder;
-
-import java.math.BigInteger;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.BiFunction;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
-import org.opendaylight.genius.mdsalutil.ActionInfo;
-import org.opendaylight.genius.mdsalutil.BucketInfo;
-import org.opendaylight.genius.mdsalutil.FlowEntity;
-import org.opendaylight.genius.mdsalutil.GroupEntity;
-import org.opendaylight.genius.mdsalutil.InstructionInfo;
-import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.genius.mdsalutil.MatchInfo;
-import org.opendaylight.genius.mdsalutil.MetaDataUtil;
-import org.opendaylight.genius.mdsalutil.NwConstants;
-import org.opendaylight.genius.mdsalutil.actions.ActionDrop;
-import org.opendaylight.genius.mdsalutil.actions.ActionLoadIpToSpa;
-import org.opendaylight.genius.mdsalutil.actions.ActionLoadMacToSha;
-import org.opendaylight.genius.mdsalutil.actions.ActionMoveShaToTha;
-import org.opendaylight.genius.mdsalutil.actions.ActionMoveSourceDestinationEth;
-import org.opendaylight.genius.mdsalutil.actions.ActionMoveSpaToTpa;
-import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
-import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
-import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
-import org.opendaylight.genius.mdsalutil.actions.ActionSetArpOp;
-import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
-import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
-import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
-import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.genius.mdsalutil.matches.MatchArpOp;
-import org.opendaylight.genius.mdsalutil.matches.MatchArpTpa;
-import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
-import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
-import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
-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.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.idmanager.rev160406.AllocateIdInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Arp Responder Utility Class.
- */
-public class ArpResponderUtil {
-
- private static final Logger LOG = LoggerFactory.getLogger(ArpResponderUtil.class);
-
- private static final long WAIT_TIME_FOR_SYNC_INSTALL = Long.getLong("wait.time.sync.install", 300L);
-
- /**
- * A Utility class.
- */
- private ArpResponderUtil() {
-
- }
-
- /**
- * Install Group flow on the DPN.
- *
- * @param mdSalManager
- * Reference of MDSAL API RPC that provides API for installing
- * group flow
- * @param dpnId
- * DPN on which group flow to be installed
- * @param groupdId
- * Uniquely identifiable Group Id for the group flow
- * @param groupName
- * Name of the group flow
- * @param buckets
- * List of the bucket actions for the group flow
- */
- public static void installGroup(IMdsalApiManager mdSalManager, BigInteger dpnId, long groupdId, String groupName,
- List<BucketInfo> buckets) {
- LOG.trace("Installing group flow on dpn {}", dpnId);
- GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupdId, groupName, GroupTypes.GroupAll, buckets);
- mdSalManager.syncInstallGroup(groupEntity, WAIT_TIME_FOR_SYNC_INSTALL);
- try {
- Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
- } catch (InterruptedException e1) {
- LOG.warn("Error while waiting for ARP Responder Group Entry to be installed on DPN {} ", dpnId);
- }
- }
-
- /**
- * Get Default ARP Responder Drop flow on the DPN.
- *
- * @param dpnId
- * DPN on which group flow to be installed
- */
- public static FlowEntity getArpResponderTableMissFlow(BigInteger dpnId) {
- return MDSALUtil.buildFlowEntity(dpnId, NwConstants.ARP_RESPONDER_TABLE,
- String.valueOf(NwConstants.ARP_RESPONDER_TABLE), NwConstants.TABLE_MISS_PRIORITY,
- ArpResponderConstant.DROP_FLOW_NAME.value(), 0, 0, NwConstants.COOKIE_ARP_RESPONDER,
- new ArrayList<MatchInfo>(),
- Collections.singletonList(new InstructionApplyActions(Collections.singletonList(new ActionDrop()))));
- }
-
- /**
- * Get Bucket Actions for ARP Responder Group Flow.
- *
- * <p>
- * Install Default Groups, Group has 3 Buckets
- * </p>
- * <ul>
- * <li>Punt to controller</li>
- * <li>Resubmit to Table {@link NwConstants#LPORT_DISPATCHER_TABLE}, for
- * ELAN flooding
- * <li>Resubmit to Table {@link NwConstants#ARP_RESPONDER_TABLE}, for ARP
- * Auto response from DPN itself</li>
- * </ul>
- *
- * @param resubmitTableId
- * Resubmit Flow Table Id
- * @param resubmitTableId2
- * Resubmit Flow Table Id
- * @return List of bucket actions
- */
- public static List<BucketInfo> getDefaultBucketInfos(short resubmitTableId, short resubmitTableId2) {
- return Arrays.asList(
- new BucketInfo(Collections.singletonList(new ActionPuntToController())),
- new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId))),
- new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId2))));
- }
-
- /**
- * Get Match Criteria for the ARP Responder Flow.
- *
- * <p>
- * List of Match Criteria for ARP Responder
- * </p>
- * <ul>
- * <li>Packet is ARP</li>
- * <li>Packet is ARP Request</li>
- * <li>The ARP packet is requesting for Gateway IP</li>
- * <li>Metadata which is generated by using Service
- * Index({@link NwConstants#L3VPN_SERVICE_INDEX}) Lport Tag
- * ({@link MetaDataUtil#METADATA_MASK_LPORT_TAG}) and VRF
- * ID({@link MetaDataUtil#METADATA_MASK_VRFID})</li>
- * </ul>
- *
- * @param lportTag
- * LPort Tag
- * @param elanInstance
- * Elan Instance
- * @param ipAddress
- * Ip Address to be matched to this flow
- * @return List of Match criteria
- */
- public static List<MatchInfo> getMatchCriteria(int lportTag, ElanInstance elanInstance,
- String ipAddress) {
-
- BigInteger metadata = ElanHelper.getElanMetadataLabel(elanInstance.getElanTag(), lportTag);
- BigInteger metadataMask = ElanHelper.getElanMetadataMask();
- return Arrays.asList(MatchEthernetType.ARP, MatchArpOp.REQUEST, new MatchArpTpa(ipAddress, "32"),
- new MatchMetadata(metadata, metadataMask));
-
- }
-
- /**
- * Get List of actions for ARP Responder Flows.
- *
- * <p>
- * Actions consists of all the ARP actions and Resubmit Action to table
- * {@link NwConstants#ELAN_BASE_TABLE} such that packets can flow ELAN Rule
- *
- * @param ipAddress
- * IP Address for which ARP Response packet is to be generated
- * @param macAddress
- * MacAddress for which ARP Response packet is to be generated
- * @return List of ARP Responder Actions actions
- */
- public static List<Action> getActions(IInterfaceManager ifaceMgrRpcService, String ifName, String ipAddress,
- String macAddress) {
-
- AtomicInteger actionCounter = new AtomicInteger();
- List<Action> actions = arpActions.apply(actionCounter, macAddress, ipAddress);
- actions.addAll(getEgressActionsForInterface(ifaceMgrRpcService, ifName, actionCounter.get()));
- LOG.trace("Total Number of actions is {}", actionCounter);
- return actions;
-
- }
-
- /**
- * A Interface that represent lambda TriFunction.
- *
- * @param <T>
- * Input type
- * @param <U>
- * Input type
- * @param <S>
- * Input type
- * @param <R>
- * Return Type
- */
- @SuppressWarnings("checkstyle:ParameterName")
- public interface TriFunction<T, U, S, R> {
- /**
- * Apply the Action.
- *
- * @param t
- * Input1
- * @param u
- * Input2
- * @param s
- * Input3
- * @return computed result
- */
- R apply(T t, U u, S s);
- }
-
- /**
- * Lambda to apply arpAction. Inputs action counter, mac address and ip
- * address
- */
- private static TriFunction<AtomicInteger, String, String, List<Action>> arpActions = (actionCounter, mac, ip) -> {
- List<Action> actions = new ArrayList<>();
- Collections.addAll(actions, new ActionMoveSourceDestinationEth().buildAction(actionCounter.getAndIncrement()),
- new ActionSetFieldEthernetSource(new MacAddress(mac)).buildAction(actionCounter.getAndIncrement()),
- new ActionSetArpOp(NwConstants.ARP_REPLY).buildAction(actionCounter.getAndIncrement()),
- new ActionMoveShaToTha().buildAction(actionCounter.getAndIncrement()),
- new ActionMoveSpaToTpa().buildAction(actionCounter.getAndIncrement()),
- new ActionLoadMacToSha(new MacAddress(mac)).buildAction(actionCounter.getAndIncrement()),
- new ActionLoadIpToSpa(ip).buildAction(actionCounter.getAndIncrement()),
- new ActionNxLoadInPort(BigInteger.ZERO).buildAction(actionCounter.getAndIncrement()));
- return actions;
-
- };
-
- /**
- * Get instruction list for ARP responder flows.
- */
- public static List<Instruction> getInterfaceInstructions(IInterfaceManager ifaceMgrRpcService, String interfaceName,
- String ipAddress, String macAddress) {
- List<Action> actions = ArpResponderUtil.getActions(ifaceMgrRpcService, interfaceName, ipAddress, macAddress);
- return Collections.singletonList(MDSALUtil.buildApplyActionsInstruction(actions));
- }
-
- /**
- * Get instruction list for ARP responder flows originated from ext-net e.g.
- * router-gw/fip.<br>
- * The split-horizon bit should be reset in order to allow traffic from
- * provider network to be routed back to flat/VLAN network and override the
- * egress table drop flow.<br>
- * In order to allow write-metadata in the ARP responder table the resubmit
- * action needs to be replaced with goto instruction.
- */
- public static List<Instruction> getExtInterfaceInstructions(IInterfaceManager ifaceMgrRpcService,
- String extInterfaceName, String ipAddress, String macAddress) {
- AtomicInteger tableId = new AtomicInteger(-1);
- List<Instruction> instructions = new ArrayList<>();
- List<Action> actions = getActions(ifaceMgrRpcService, extInterfaceName, ipAddress, macAddress);
- actions.removeIf(v -> {
- org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = v
- .getAction();
- if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
- tableId.set(((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable());
- return true;
- } else {
- return false;
- }
- });
-
- instructions.add(MDSALUtil.buildApplyActionsInstruction(actions, 0));
-
- if (tableId.get() != -1) {
- // replace resubmit action with goto so it can co-exist with
- // write-metadata
- if ((short) tableId.get() > NwConstants.ARP_RESPONDER_TABLE) {
- instructions.add(new InstructionGotoTable((short) tableId.get()).buildInstruction(2));
- } else {
- LOG.warn("Failed to insall responder flow for interface {}. Resubmit to {} can't be replaced with goto",
- extInterfaceName, tableId);
- }
- }
-
- return instructions;
- }
-
- /**
- * Install ARP Responder FLOW.
- *
- * @param mdSalManager
- * Reference of MDSAL API RPC that provides API for installing
- * flow
- * @param dpnId
- * DPN on which flow to be installed
- * @param flowId
- * Uniquely Identifiable Arp Responder Table flow Id
- * @param flowName
- * Readable flow name
- * @param priority
- * Flow Priority
- * @param cookie
- * Flow Cookie
- * @param matches
- * List of Match Criteria for the flow
- * @param instructions
- * List of Instructions for the flow
- */
- public static void installFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId, String flowName,
- int priority, BigInteger cookie, List<MatchInfo> matches, List<Instruction> instructions) {
- Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, priority, flowName, 0, 0,
- cookie, matches, instructions);
- mdSalManager.installFlow(dpnId, flowEntity);
- }
-
- /**
- * Remove flow form DPN.
- *
- * @param mdSalManager
- * Reference of MDSAL API RPC that provides API for installing
- * flow
- * @param dpnId
- * DPN form which flow to be removed
- * @param flowId
- * Uniquely Identifiable Arp Responder Table flow Id that is to
- * be removed
- */
- public static void removeFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId) {
- Flow flowEntity = MDSALUtil.buildFlow(NwConstants.ARP_RESPONDER_TABLE, flowId);
- mdSalManager.removeFlow(dpnId, flowEntity);
- }
-
- /**
- * Creates Uniquely Identifiable flow Id.
- *
- * @param lportTag
- * LportTag of the flow
- * @param ipAdress
- * Gateway IP for which ARP Response flow to be installed
- * @return Unique Flow Id
- *
- * @see ArpResponderConstant#FLOW_ID_FORMAT_WITH_LPORT
- * @see ArpResponderConstant#FLOW_ID_FORMAT_WITHOUT_LPORT
- */
- public static String getFlowId(int lportTag, String ipAdress) {
- return MessageFormat.format(ArpResponderConstant.FLOW_ID_FORMAT_WITH_LPORT.value(),
- NwConstants.ARP_RESPONDER_TABLE, lportTag, ipAdress);
- }
-
- /**
- * Generate Cookie per flow.
- *
- * <p>
- * Cookie is generated by Summation of
- * {@link NwConstants#COOKIE_ARP_RESPONDER} + 1 + lportTag + Gateway IP
- *
- * @param lportTag
- * Lport Tag of the flow
- * @param ipAddress
- * Gateway IP for which ARP Response flow to be installed
- * @return Cookie
- */
- public static BigInteger generateCookie(int lportTag, String ipAddress) {
- LOG.trace("IPAddress in long {}", ipAddress);
- BigInteger cookie = NwConstants.COOKIE_ARP_RESPONDER.add(BigInteger.valueOf(255))
- .add(BigInteger.valueOf(ipTolong(ipAddress)));
- return cookie.add(BigInteger.valueOf(lportTag));
- }
-
- private static BiFunction<Short, Integer, BigInteger> cookie = (tableId,
- arpOpType) -> NwConstants.COOKIE_ARP_RESPONDER.add(BigInteger.ONE).add(BigInteger.valueOf(tableId))
- .add(BigInteger.valueOf(arpOpType));
-
- private static BiFunction<Short, Integer, String> flowRef = (tableId,
- arpOpType) -> (tableId == NwConstants.ARP_CHECK_TABLE
- ? ArpResponderConstant.FLOWID_PREFIX_FOR_ARP_CHECK.value()
- : ArpResponderConstant.FLOWID_PREFIX_FOR_MY_GW_MAC.value()) + tableId + NwConstants.FLOWID_SEPARATOR
- + (arpOpType == NwConstants.ARP_REQUEST ? "arp.request" : "arp.replay");
-
- public static FlowEntity createArpDefaultFlow(BigInteger dpId, short tableId, int arpOpType,
- Supplier<List<MatchInfo>> matches, Supplier<List<ActionInfo>> actions) {
-
- List<InstructionInfo> instructions = Collections.singletonList(new InstructionApplyActions(actions.get()));
- return MDSALUtil.buildFlowEntity(dpId, tableId, flowRef.apply(tableId, arpOpType),
- NwConstants.DEFAULT_ARP_FLOW_PRIORITY, flowRef.apply(tableId, arpOpType), 0, 0,
- cookie.apply(tableId, arpOpType), matches.get(), instructions);
- }
-
- /**
- * Get IP Address in Long from String.
- *
- * @param address
- * IP Address that to be converted to long
- * @return Long value of the IP Address
- */
- private static long ipTolong(String address) {
-
- // Parse IP parts into an int array
- long[] ip = new long[4];
- String[] parts = address.split("\\.");
-
- for (int i = 0; i < 4; i++) {
- ip[i] = Long.parseLong(parts[i]);
- }
- // Add the above IP parts into an int number representing your IP
- // in a 32-bit binary form
- long ipNumbers = 0;
- for (int i = 0; i < 4; i++) {
- ipNumbers += ip[i] << (24 - (8 * i));
- }
- return ipNumbers;
-
- }
-
- /**
- * Get List of Egress Action for the VPN interface.
- *
- * @param ifaceMgrRpcService
- * Interface Manager RPC reference that invokes API to retrieve
- * Egress Action
- * @param ifName
- * VPN Interface for which Egress Action to be retrieved
- * @param actionCounter
- * Action Key
- * @return List of Egress Actions
- */
- public static List<Action> getEgressActionsForInterface(IInterfaceManager ifaceMgrRpcService, String ifName,
- int actionCounter) {
- List<ActionInfo> actionInfos = ifaceMgrRpcService.getInterfaceEgressActions(ifName);
- AtomicInteger counter = new AtomicInteger(actionCounter);
- return actionInfos.stream().map(v -> v.buildAction(counter.getAndIncrement())).collect(Collectors.toList());
- }
-
- /**
- * Uses the IdManager to retrieve ARP Responder GroupId from ELAN pool.
- *
- * @param idManager
- * the id manager
- * @return the integer
- */
- public static Long retrieveStandardArpResponderGroupId(IdManagerService idManager) {
-
- AllocateIdInput getIdInput = new AllocateIdInputBuilder()
- .setPoolName(ArpResponderConstant.ELAN_ID_POOL_NAME.value())
- .setIdKey(ArpResponderConstant.ARP_RESPONDER_GROUP_ID.value()).build();
-
- try {
- Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
- RpcResult<AllocateIdOutput> rpcResult = result.get();
- if (rpcResult.isSuccessful()) {
- LOG.trace("Retrieved Group Id is {}", rpcResult.getResult().getIdValue());
- return rpcResult.getResult().getIdValue();
- } else {
- LOG.warn("RPC Call to Allocate Id returned with Errors {}", rpcResult.getErrors());
- }
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Exception when Allocating Id", e);
- }
- return 0L;
- }
-
-}
*/
package org.opendaylight.netvirt.elanmanager.api;
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
-import org.opendaylight.genius.mdsalutil.MetaDataUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ElanHelper {
- private static final Logger LOG = LoggerFactory.getLogger(ElanHelper.class);
-
- private ElanHelper() {
- throw new AssertionError(ElanHelper.class.getName() + " cannot be initialized.");
- }
+public class ElanHelper {
public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
return InstanceIdentifier.builder(ElanInstances.class)
.child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
}
-
- public static BigInteger getElanMetadataLabel(long elanTag) {
- return MetaDataUtil.getElanTagMetadata(elanTag);
- }
-
- public static BigInteger getElanMetadataLabel(long elanTag, int lportTag) {
- return getElanMetadataLabel(elanTag).or(MetaDataUtil.getLportTagMetaData(lportTag));
- }
-
- public static BigInteger getElanMetadataMask() {
- return MetaDataUtil.METADATA_MASK_SERVICE.or(MetaDataUtil.METADATA_MASK_LPORT_TAG);
- }
-
- public static List<String> getDpnInterfacesInElanInstance(DataBroker broker, String elanInstanceName) {
-
- InstanceIdentifier<ElanDpnInterfacesList> elanDpnInterfaceId = getElanDpnOperationDataPath(elanInstanceName);
- try {
- ElanDpnInterfacesList existingElanDpnInterfaces = SingleTransactionDataBroker.syncRead(broker,
- LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
- if (existingElanDpnInterfaces != null) {
- return existingElanDpnInterfaces.getDpnInterfaces().stream().flatMap(v -> v.getInterfaces().stream())
- .collect(Collectors.toList());
- }
- } catch (ReadFailedException e) {
- LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
- }
- return Collections.emptyList();
- }
-
- public static InstanceIdentifier<ElanDpnInterfacesList> getElanDpnOperationDataPath(String elanInstanceName) {
- return InstanceIdentifier.builder(ElanDpnInterfaces.class)
- .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
-
- }
}
import java.util.List;
import org.opendaylight.genius.mdsalutil.MatchInfoBase;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput;
import org.opendaylight.netvirt.elanmanager.exceptions.MacNotFoundException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
Boolean isOpenStackVniSemanticsEnforced();
- /**
- * Add ARP Responder Flow on the given dpn for the ingress interface.
- *
- * @param arpResponderInput
- * ArpResponder Input parameters
- * @see ArpResponderInput
- */
- void addArpResponderFlow(ArpResponderInput arpResponderInput);
-
- /**
- * Remove ARP Responder flow from the given dpn for the ingress interface.
- *
- * @param arpResponderInput
- * ArpResponder Input parameters
- * @see ArpResponderInput
- */
- void removeArpResponderFlow(ArpResponderInput arpResponderInput);
-
}
<artifactId>interfacemanager-api</artifactId>
<version>${genius.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.genius</groupId>
+ <artifactId>idmanager-api</artifactId>
+ <version>${genius.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.genius</groupId>
<artifactId>itm-api</artifactId>
import org.opendaylight.netvirt.elan.utils.ElanConstants;
import org.opendaylight.netvirt.elan.utils.ElanForwardingEntriesHandler;
import org.opendaylight.netvirt.elan.utils.ElanUtils;
-import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
*/
private List<InstructionInfo> getInstructionsIntOrExtTunnelTable(Long elanTag) {
List<InstructionInfo> mkInstructions = new ArrayList<>();
- mkInstructions.add(new InstructionWriteMetadata(ElanHelper.getElanMetadataLabel(elanTag), ElanHelper
+ mkInstructions.add(new InstructionWriteMetadata(ElanUtils.getElanMetadataLabel(elanTag), ElanUtils
.getElanMetadataMask()));
/* applicable for EXTERNAL_TUNNEL_TABLE only
* TODO: We should point to SMAC or DMAC depending on a configuration property to enable mac learning
WriteTransaction tx) {
int instructionKey = 0;
List<Instruction> instructions = new ArrayList<>();
- instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanHelper.getElanMetadataLabel(elanTag),
+ instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanTag),
MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
List<Action> actions = new ArrayList<>();
elanTag).buildAction());
instructions.add(MDSALUtil.buildApplyActionsInstruction(actions, ++instructionKey));
- instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.ARP_CHECK_TABLE,
+ instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.ELAN_BASE_TABLE,
++instructionKey));
short elanServiceIndex = ServiceIndex.getIndex(NwConstants.ELAN_SERVICE_NAME, NwConstants.ELAN_SERVICE_INDEX);
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.mdsalutil.ActionInfo;
-import org.opendaylight.genius.mdsalutil.BucketInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfoBase;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.actions.ActionDrop;
-import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
import org.opendaylight.genius.mdsalutil.actions.ActionLearn;
import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.genius.mdsalutil.matches.MatchArpOp;
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination;
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderConstant;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
import org.opendaylight.netvirt.elan.utils.ElanConstants;
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.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
private final DataBroker broker;
private final IMdsalApiManager mdsalManager;
- private final IdManagerService idManagerService;
private final int tempSmacLearnTimeout;
private final boolean puntLldpToController;
- public ElanNodeListener(DataBroker dataBroker, IMdsalApiManager mdsalManager, ElanConfig elanConfig,
- IdManagerService idManagerService) {
+ public ElanNodeListener(DataBroker dataBroker, IMdsalApiManager mdsalManager, ElanConfig elanConfig) {
this.broker = dataBroker;
this.mdsalManager = mdsalManager;
this.tempSmacLearnTimeout = elanConfig.getTempSmacLearnTimeout();
this.puntLldpToController = elanConfig.isPuntLldpToController();
- this.idManagerService = idManagerService;
}
@Override
BigInteger dpId = new BigInteger(node[1]);
createTableMissEntry(dpId);
createMulticastFlows(dpId);
- createArpDefaultFlowsForArpCheckTable(dpId);
- }
-
- @SuppressWarnings("deprecation")
- private void createArpDefaultFlowsForArpCheckTable(BigInteger dpId) {
- DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("ARP_CHECK_TABLE-" + dpId.toString(), () -> {
- WriteTransaction writeFlowTx = broker.newWriteOnlyTransaction();
- LOG.debug("Received notification to install Arp Check Default entries for dpn {} ", dpId);
- createArpRequestMatchFlows(dpId, writeFlowTx);
- createArpResponseMatchFlows(dpId, writeFlowTx);
- return Arrays.asList(writeFlowTx.submit());
- });
}
public void createTableMissEntry(BigInteger dpnId) {
setupTableMissSmacFlow(dpnId);
setupTableMissDmacFlow(dpnId);
- setupTableMissArpCheckFlow(dpnId);
- setupTableMissApResponderFlow(dpnId);
}
private void createMulticastFlows(BigInteger dpId) {
@Override
protected ElanNodeListener getDataTreeChangeListener() {
+ // TODO Auto-generated method stub
return ElanNodeListener.this;
}
- private void setupTableMissApResponderFlow(final BigInteger dpnId) {
- mdsalManager.installFlow(dpnId, ArpResponderUtil.getArpResponderTableMissFlow(dpnId));
- }
-
- private void setupTableMissArpCheckFlow(BigInteger dpnId) {
- mdsalManager.installFlow(dpnId,
- MDSALUtil.buildFlowEntity(dpnId, NwConstants.ARP_CHECK_TABLE,
- String.valueOf("L2.ELAN." + NwConstants.ARP_CHECK_TABLE), NwConstants.TABLE_MISS_PRIORITY,
- ArpResponderConstant.DROP_FLOW_NAME.value(), 0, 0, NwConstants.COOKIE_ARP_RESPONDER,
- new ArrayList<MatchInfo>(),
- Collections.singletonList(new InstructionGotoTable(NwConstants.ELAN_BASE_TABLE))));
- }
-
- private void createArpRequestMatchFlows(BigInteger dpId, WriteTransaction writeFlowTx) {
-
- long arpRequestGroupId = ArpResponderUtil.retrieveStandardArpResponderGroupId(idManagerService);
- List<BucketInfo> buckets = ArpResponderUtil.getDefaultBucketInfos(NwConstants.ELAN_BASE_TABLE,
- NwConstants.ARP_RESPONDER_TABLE);
- ArpResponderUtil.installGroup(mdsalManager, dpId, arpRequestGroupId,
- ArpResponderConstant.GROUP_FLOW_NAME.value(), buckets);
-
- FlowEntity arpReqArpCheckTbl = ArpResponderUtil.createArpDefaultFlow(dpId, NwConstants.ARP_CHECK_TABLE,
- NwConstants.ARP_REQUEST, () -> Arrays.asList(MatchEthernetType.ARP, MatchArpOp.REQUEST),
- () -> Collections.singletonList(new ActionGroup(arpRequestGroupId)));
- LOG.trace("Invoking MDSAL to install Arp Rquest Match Flow for table {}", NwConstants.ARP_CHECK_TABLE);
- mdsalManager.addFlowToTx(arpReqArpCheckTbl, writeFlowTx);
-
- }
-
- private void createArpResponseMatchFlows(BigInteger dpId, WriteTransaction writeFlowTx) {
- FlowEntity arpRepArpCheckTbl = ArpResponderUtil.createArpDefaultFlow(dpId, NwConstants.ARP_CHECK_TABLE,
- NwConstants.ARP_REPLY, () -> Arrays.asList(MatchEthernetType.ARP, MatchArpOp.REPLY),
- () -> Arrays.asList(new ActionPuntToController(), new ActionNxResubmit(NwConstants.ELAN_BASE_TABLE)));
- LOG.trace("Invoking MDSAL to install Arp Reply Match Flow for Table {} ", NwConstants.ARP_CHECK_TABLE);
- mdsalManager.addFlowToTx(arpRepArpCheckTbl, writeFlowTx);
-
- }
-
-}
\ No newline at end of file
+}
import org.opendaylight.genius.utils.clustering.EntityOwnerUtils;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.infrautils.inject.AbstractLifecycle;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput;
import org.opendaylight.netvirt.elan.statusanddiag.ElanStatusMonitor;
import org.opendaylight.netvirt.elan.utils.ElanConstants;
import org.opendaylight.netvirt.elan.utils.ElanUtils;
}
}
- @Override
- public void addArpResponderFlow(ArpResponderInput arpResponderInput) {
- elanUtils.addArpResponderFlow(arpResponderInput.getDpId(), arpResponderInput.getInterfaceName(),
- arpResponderInput.getSpa(), arpResponderInput.getSha(), arpResponderInput.getLportTag(),
- arpResponderInput.getInstructions());
- }
-
- @Override
- public void removeArpResponderFlow(ArpResponderInput arpResponderInput) {
- elanUtils.removeArpResponderFlow(arpResponderInput.getDpId(), arpResponderInput.getInterfaceName(),
- arpResponderInput.getSpa(), arpResponderInput.getLportTag());
- }
-
}
import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
import org.opendaylight.genius.utils.batching.ResourceBatchingManager.ShardResource;
import org.opendaylight.netvirt.elan.ElanException;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
import org.opendaylight.netvirt.elan.internal.ElanInstanceManager;
import org.opendaylight.netvirt.elan.internal.ElanInterfaceManager;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
return ElanConstants.ELAN_GID_MIN + etreeLeafTag % ElanConstants.ELAN_GID_MIN * 2;
}
+ public static BigInteger getElanMetadataLabel(long elanTag) {
+ return MetaDataUtil.getElanTagMetadata(elanTag);
+ }
+
public static BigInteger getElanMetadataLabel(long elanTag, boolean isSHFlagSet) {
int shBit = isSHFlagSet ? 1 : 0;
return BigInteger.valueOf(elanTag).shiftLeft(24).or(BigInteger.valueOf(shBit));
}
+ public static BigInteger getElanMetadataLabel(long elanTag, int lportTag) {
+ return getElanMetadataLabel(elanTag).or(MetaDataUtil.getLportTagMetaData(lportTag));
+ }
+
+ public static BigInteger getElanMetadataMask() {
+ return MetaDataUtil.METADATA_MASK_SERVICE.or(MetaDataUtil.METADATA_MASK_LPORT_TAG);
+ }
+
/**
* Setting SMAC, DMAC, UDMAC in this DPN and optionally in other DPNs.
*
int lportTag = interfaceInfo.getInterfaceTag();
// Matching metadata and eth_src fields
List<MatchInfo> mkMatches = new ArrayList<>();
- mkMatches.add(new MatchMetadata(ElanHelper.getElanMetadataLabel(elanInfo.getElanTag(), lportTag),
- ElanHelper.getElanMetadataMask()));
+ mkMatches.add(new MatchMetadata(getElanMetadataLabel(elanInfo.getElanTag(), lportTag), getElanMetadataMask()));
mkMatches.add(new MatchEthernetSource(new MacAddress(macAddress)));
List<InstructionInfo> mkInstructions = new ArrayList<>();
mkInstructions.add(new InstructionGotoTable(NwConstants.ELAN_DMAC_TABLE));
ElanInstance elanInfo, long ifTag) {
List<MatchInfo> mkMatches = new ArrayList<>();
- mkMatches.add(new MatchMetadata(ElanHelper.getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
+ mkMatches.add(new MatchMetadata(getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
mkMatches.add(new MatchEthernetDestination(new MacAddress(macAddress)));
List<Instruction> mkInstructions = new ArrayList<>();
public Flow buildRemoteDmacFlowEntry(BigInteger srcDpId, BigInteger destDpId, long lportTagOrVni, long elanTag,
String macAddress, String displayName, ElanInstance elanInstance) throws ElanException {
List<MatchInfo> mkMatches = new ArrayList<>();
- mkMatches.add(new MatchMetadata(ElanHelper.getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
+ mkMatches.add(new MatchMetadata(getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
mkMatches.add(new MatchEthernetDestination(new MacAddress(macAddress)));
List<Instruction> mkInstructions = new ArrayList<>();
int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
int instructionKey = 0;
List<Instruction> instructions = new ArrayList<>();
- instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanHelper.getElanMetadataLabel(elanTag),
+ instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(getElanMetadataLabel(elanTag),
MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.ELAN_SMAC_TABLE, ++instructionKey));
public static FlowEntity buildDmacRedirectToDispatcherFlow(BigInteger dpId, String dstMacAddress,
String displayName, long elanTag) {
List<MatchInfo> matches = new ArrayList<>();
- matches.add(new MatchMetadata(ElanHelper.getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
+ matches.add(new MatchMetadata(getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE));
matches.add(new MatchEthernetDestination(new MacAddress(dstMacAddress)));
List<InstructionInfo> instructions = new ArrayList<>();
List<ActionInfo> actions = new ArrayList<>();
return removed != null ? removed : Collections.emptySet();
}
- public void addArpResponderFlow(BigInteger dpnId, String ingressInterfaceName, String ipAddress, String macAddress,
- int lportTag, List<Instruction> instructions) {
- LOG.info("Installing the ARP responder flow on DPN {} for Interface {} with MAC {} & IP {}", dpnId,
- ingressInterfaceName, macAddress, ipAddress);
- ElanInterface elanIface = getElanInterfaceByElanInterfaceName(broker, ingressInterfaceName);
- ElanInstance elanInstance = getElanInstanceByName(broker, elanIface.getElanInstanceName());
- String flowId = ArpResponderUtil.getFlowId(lportTag, ipAddress);
- ArpResponderUtil.installFlow(mdsalManager, dpnId, flowId, flowId, NwConstants.DEFAULT_ARP_FLOW_PRIORITY,
- ArpResponderUtil.generateCookie(lportTag, ipAddress),
- ArpResponderUtil.getMatchCriteria(lportTag, elanInstance, ipAddress), instructions);
- LOG.info("Installed the ARP Responder flow for Interface {}", ingressInterfaceName);
-
- }
-
- public void removeArpResponderFlow(BigInteger dpnId, String ingressInterfaceName, String ipAddress,
- int lportTag) {
- LOG.info("Removing the ARP responder flow on DPN {} of Interface {} with IP {}", dpnId, ingressInterfaceName,
- ipAddress);
- ArpResponderUtil.removeFlow(mdsalManager, dpnId, ArpResponderUtil.getFlowId(lportTag, ipAddress));
- }
-
private void buildEtreeDmacFlowForExternalRemoteMacWithBatch(
BigInteger dpnId, String extDeviceNodeId, Long vni, String macAddress, String displayName,
String interfaceName, EtreeLeafTagName etreeLeafTag)throws ElanException {
<argument ref="dataBroker" />
<argument ref="mdsalUtils" />
<argument ref="elanConfig" />
- <argument ref="idManagerService" />
</bean>
<bean id="elanPacketInHandler"
LOG.debug("vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, rd {} and floatingIp {}",
vpnName, dpnId, rd, externalIp);
List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
- if (ipAddressList != null && !ipAddressList.isEmpty()) {
+ if (ipAddressList.size() > 0) {
int floatingIpPresentCount = 0;
for (IpAddresses ipAddress: ipAddressList) {
if (!ipAddress.getIpAddress().equals(externalIp)
*/
package org.opendaylight.netvirt.neutronvpn.api.utils;
-import java.util.function.Predicate;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
-
public class NeutronConstants {
public static final String DEVICE_OWNER_GATEWAY_INF = "network:router_gateway";
public static final String VIF_TYPE_MACVTAP = "macvtap";
public static final String VNIC_TYPE_NORMAL = "normal";
- public static final Predicate<Port> IS_DHCP_PORT = port -> port != null
- && port.getDeviceOwner().equals(DEVICE_OWNER_DHCP);
-
- public static final Predicate<Port> IS_ODL_DHCP_PORT = port -> port != null
- && port.getDeviceOwner().equals(DEVICE_OWNER_DHCP) && port.getDeviceId() != null
- && port.getDeviceId().startsWith("OpenDaylight");
-
}
final Uuid portId = port.getUuid();
final Uuid subnetId = port.getFixedIps().get(0).getSubnetId();
final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- if (NeutronConstants.IS_ODL_DHCP_PORT.test(port)) {
- return;
- }
portDataStoreCoordinator.enqueueJob("PORT- " + portName, () -> {
WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
List<ListenableFuture<Void>> futures = new ArrayList<>();
final String portName = port.getUuid().getValue();
final Uuid portId = port.getUuid();
final Uuid subnetId = port.getFixedIps().get(0).getSubnetId();
- if (NeutronConstants.IS_ODL_DHCP_PORT.test(port)) {
- return;
- }
final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
portDataStoreCoordinator.enqueueJob("PORT- " + portName, () -> {
WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MetaDataUtil;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.config.rev161130.VpnConfig;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
private void processArpLearning(String srcInterface, IpAddress srcIP, PhysAddress srcMac, BigInteger metadata,
IpAddress dstIP) {
if (metadata != null && !Objects.equals(metadata, BigInteger.ZERO)) {
- Optional<String> vpn = VpnUtil.getVpnAssociatedWithInterface(dataBroker, srcInterface);
- if (vpn.isPresent()) {
- String vpnName = vpn.get();
- LOG.info("Received ARP for sender MAC {} and sender IP {} via interface {}",
+ long vpnId = MetaDataUtil.getVpnIdFromMetadata(metadata);
+ // Process ARP only if vpnservice is configured on the interface
+ InstanceIdentifier<VpnIds> vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId);
+ Optional<VpnIds> vpnIdsOptional
+ = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
+ if (!vpnIdsOptional.isPresent()) {
+ LOG.trace("ARP NO_RESOLVE: VPN {} not configured. Ignoring responding to ARP requests on this VPN",
+ vpnId);
+ return;
+ }
+ VpnIds vpnIds = vpnIdsOptional.get();
+ String vpnName = vpnIds.getVpnInstanceName();
+ if (VpnUtil.isInterfaceAssociatedWithVpn(dataBroker, vpnName, srcInterface)) {
+ LOG.debug("Received ARP for sender MAC {} and sender IP {} via interface {}",
srcMac.getValue(), srcIP.getIpv4Address().getValue(), srcInterface);
String ipToQuery = srcIP.getIpv4Address().getValue();
LOG.info("ARP being processed for Source IP {}", ipToQuery);
} else if (!isIpInArpMigrateCache(vpnName, ipToQuery)) {
learnMacFromArpPackets(vpnName, srcInterface, srcIP, srcMac, dstIP);
}
- } else {
- LOG.info("ARP NO_RESOLVE: VPN not configured. Ignoring responding to ARP requests from this"
- + " Interface {}.", srcInterface);
- return;
-
}
}
}
import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
-import org.opendaylight.netvirt.vpnmanager.arp.responder.ArpResponderHandler;
+import org.opendaylight.netvirt.vpnmanager.arp.responder.ArpResponderUtil;
import org.opendaylight.netvirt.vpnmanager.populator.input.L3vpnInput;
import org.opendaylight.netvirt.vpnmanager.populator.intfc.VpnPopulator;
import org.opendaylight.netvirt.vpnmanager.populator.registry.L3vpnRegistry;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
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.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
private final IInterfaceManager interfaceManager;
private final IVpnManager vpnManager;
private final IVpnLinkService ivpnLinkService;
- private final ArpResponderHandler arpResponderHandler;
private ConcurrentHashMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<>();
final VpnFootprintService vpnFootprintService,
final IInterfaceManager interfaceManager,
final IVpnManager vpnManager,
- final IVpnLinkService ivpnLnkSrvce,
- final ArpResponderHandler arpResponderHandler) {
+ final IVpnLinkService ivpnLnkSrvce) {
super(VpnInterface.class, VpnInterfaceManager.class);
this.dataBroker = dataBroker;
this.interfaceManager = interfaceManager;
this.vpnManager = vpnManager;
this.ivpnLinkService = ivpnLnkSrvce;
- this.arpResponderHandler = arpResponderHandler;
vpnInfUpdateTaskExecutor.scheduleWithFixedDelay(new VpnInterfaceUpdateTimerTask(),
0, VPN_INF_UPDATE_TIMER_TASK_DELAY, TIME_UNIT);
}
String gatewayMac = null;
long label = 0;
if (VpnUtil.isL3VpnOverVxLan(l3vni)) {
- final VpnPortipToPort gwPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker,
- vpnInstanceOpData.getVpnInstanceName(), nextHop.getIpAddress());
- gatewayMac = arpResponderHandler.getGatewayMacAddressForInterface(gwPort, intf.getName()).get();
+ gatewayMac = getGatewayMacAddressForInterface(vpnInstanceOpData.getVpnInstanceName(),
+ intf.getName(), nextHop.getIpAddress()).get();
} else {
label = nextHop.getLabel();
}
// Use this for programming ARP_RESPONDER table here. And save this
// info into vpnInterface operational, so it can used in VrfEntryProcessor
// to populate L3_GW_MAC_TABLE there.
- arpResponderHandler.addArpResponderFlow(dpnId, lportTag, vpnName, vpnId, interfaceName,
- subnetId, gatewayIp.get(), gwMac.get());
+ addArpResponderFlow(dpnId, lportTag, vpnName, vpnId, interfaceName, subnetId,
+ gwMac.get(), gatewayIp.get(), writeInvTxn);
vpnInterfaceSubnetGwMacAddress = gwMac.get();
} else {
// A valid mac-address is not available for this subnet-gateway-ip
if (gwMac.isPresent()) {
VpnUtil.setupGwMacIfExternalVpn(dataBroker, mdsalManager, dpnId, interfaceName,
vpnId, writeInvTxn, NwConstants.ADD_FLOW, interfaceState);
- arpResponderHandler.addArpResponderFlow(dpnId, lportTag, vpnName, vpnId, interfaceName,
- subnetId, gatewayIp.get(), gwMac.get());
+ addArpResponderFlow(dpnId, lportTag, vpnName, vpnId, interfaceName, subnetId,
+ gwMac.get(), gatewayIp.get(), writeInvTxn);
} else {
LOG.error("Gateway MAC for subnet ID {} could not be obtained, cannot create "
+ "ARP responder flow for interface name {}, vpnName {}, gwIp {}",
vpnId, writeInvTxn, NwConstants.DEL_FLOW, interfaceState);
}
- arpResponderHandler.removeArpResponderFlow(dpnId, lportTag, interfaceName, vpnName, vpnId,
- subnetId);
+ removeArpResponderFlow(dpnId, lportTag, subnetId, writeInvTxn);
}
if (!nhList.isEmpty()) {
}
}
+ private void addArpResponderFlow(final BigInteger dpId, final int lportTag, final String vpnName,
+ final long vpnId, final String ifName, final Uuid subnetId,
+ final String subnetGwMac, final String gwIp, final WriteTransaction writeInvTxn) {
+ LOG.trace("Creating the ARP Responder flow for VPN Interface {}",ifName);
+ final String flowId = ArpResponderUtil.getFlowID(lportTag, gwIp);
+ List<Action> actions = ArpResponderUtil.getActions(ifaceMgrRpcService, ifName, gwIp, subnetGwMac);
+ ArpResponderUtil.installFlow(mdsalManager, writeInvTxn, dpId, flowId, flowId,
+ NwConstants.DEFAULT_ARP_FLOW_PRIORITY, ArpResponderUtil.generateCookie(lportTag, gwIp),
+ ArpResponderUtil.getMatchCriteria(lportTag, vpnId, gwIp),
+ Collections.singletonList(MDSALUtil.buildApplyActionsInstruction(actions)));
+ LOG.trace("Installed the ARP Responder flow for VPN Interface {}", ifName);
+ }
+
+ private Optional<String> getGatewayMacAddressForInterface(String vpnName, String ifName, String ipAddress) {
+ VpnPortipToPort gwPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, ipAddress);
+ //Check if a router gateway interface is available for the subnet gw is so then use Router interface
+ // else use connected interface
+ return Optional.of((gwPort != null && gwPort.isSubnetIp())
+ ? gwPort.getMacAddress() : InterfaceUtils.getMacAddressForInterface(dataBroker, ifName).get());
+ }
+
private Optional<String> getMacAddressForSubnetIp(String vpnName, String ifName, String ipAddress) {
VpnPortipToPort gwPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, ipAddress);
//Check if a router gateway interface is available for the subnet gw is so then use Router interface
return Optional.absent();
}
+ private void removeArpResponderFlow(final BigInteger dpId, final int lportTag, final Uuid subnetUuid,
+ final WriteTransaction writeInvTxn) {
+ final Optional<String> gwIp = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetUuid);
+ if (gwIp.isPresent()) {
+ LOG.trace("VPNInterface adjacency Gsteway IP {} for ARP Responder removal", gwIp.get());
+ final String flowId = ArpResponderUtil.getFlowID(lportTag, gwIp.get());
+ ArpResponderUtil.removeFlow(mdsalManager, writeInvTxn, dpId, flowId);
+ }
+ }
+
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private void removePrefixFromBGP(String primaryRd, String rd, String vpnName, String prefix, String nextHop,
operationalAdjacency = populator.createOperationalAdjacency(input);
int label = operationalAdjacency.getLabel().intValue();
addExtraRoute(vpnName, adj.getIpAddress(), nh, rdToAllocate.get(),
- currVpnIntf.getVpnInstanceName(), label, l3vni, origin,
+ currVpnIntf.getVpnInstanceName(), (int) label, l3vni, origin,
currVpnIntf.getName(), operationalAdjacency, encapType, writeConfigTxn);
} else {
LOG.error("No rds to allocate extraroute {}", prefix);
package org.opendaylight.netvirt.vpnmanager;
import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MatchInfoBase;
import org.opendaylight.genius.mdsalutil.MetaDataUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
-import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput.ArpReponderInputBuilder;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
+import org.opendaylight.netvirt.vpnmanager.arp.responder.ArpResponderUtil;
import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
private final VpnInstanceListener vpnInstanceListener;
private final IdManagerService idManager;
private final IMdsalApiManager mdsalManager;
+ private final VpnFootprintService vpnFootprintService;
+ private final OdlInterfaceRpcService ifaceMgrRpcService;
private final IElanService elanService;
- private final IInterfaceManager interfaceManager;
private final VpnSubnetRouteHandler vpnSubnetRouteHandler;
public VpnManagerImpl(final DataBroker dataBroker,
final VpnInterfaceManager vpnInterfaceManager,
final IMdsalApiManager mdsalManager,
final VpnFootprintService vpnFootprintService,
+ final OdlInterfaceRpcService ifaceMgrRpcService,
final IElanService elanService,
- final IInterfaceManager interfaceManager,
final VpnSubnetRouteHandler vpnSubnetRouteHandler) {
this.dataBroker = dataBroker;
this.vpnInterfaceManager = vpnInterfaceManager;
this.vpnInstanceListener = vpnInstanceListener;
this.idManager = idManagerService;
this.mdsalManager = mdsalManager;
+ this.vpnFootprintService = vpnFootprintService;
+ this.ifaceMgrRpcService = ifaceMgrRpcService;
this.elanService = elanService;
- this.interfaceManager = interfaceManager;
this.vpnSubnetRouteHandler = vpnSubnetRouteHandler;
}
installArpResponderFlowsToExternalNetworkIp(macAddress, dpnId, extInterfaceName, lportTag, vpnId,
fixedIp, writeTx);
} else {
- removeArpResponderFlowsToExternalNetworkIp(dpnId, lportTag, fixedIp, writeTx,extInterfaceName);
+ removeArpResponderFlowsToExternalNetworkIp(dpnId, lportTag, fixedIp, writeTx);
}
}
}
private void installArpResponderFlowsToExternalNetworkIp(String macAddress, BigInteger dpnId,
- String extInterfaceName, int lportTag, long vpnId, String fixedIp, WriteTransaction writeTx) {
- // reset the split-horizon bit to allow traffic to be sent back to the
- // provider port
- List<Instruction> instructions = new ArrayList<>();
- instructions.add(
- new InstructionWriteMetadata(BigInteger.ZERO, MetaDataUtil.METADATA_MASK_SH_FLAG).buildInstruction(1));
- instructions.addAll(
- ArpResponderUtil.getExtInterfaceInstructions(interfaceManager, extInterfaceName, fixedIp, macAddress));
- ArpReponderInputBuilder builder = new ArpReponderInputBuilder().setDpId(dpnId)
- .setInterfaceName(extInterfaceName).setSpa(fixedIp).setSha(macAddress).setLportTag(lportTag);
- builder.setInstructions(instructions);
- elanService.addArpResponderFlow(builder.buildForInstallFlow());
+ String extInterfaceName, Integer lportTag, long vpnId, String fixedIp, WriteTransaction writeTx) {
+ String flowId = ArpResponderUtil.getFlowID(lportTag, fixedIp);
+ List<Instruction> instructions = ArpResponderUtil.getExtInterfaceInstructions(ifaceMgrRpcService,
+ extInterfaceName, fixedIp, macAddress);
+ ArpResponderUtil.installFlow(mdsalManager, writeTx, dpnId, flowId, flowId,
+ NwConstants.DEFAULT_ARP_FLOW_PRIORITY, ArpResponderUtil.generateCookie(lportTag, fixedIp),
+ ArpResponderUtil.getMatchCriteria(lportTag, vpnId, fixedIp), instructions);
}
private void removeArpResponderFlowsToExternalNetworkIp(BigInteger dpnId, Integer lportTag, String fixedIp,
- WriteTransaction writeTx,String extInterfaceName) {
- ArpResponderInput arpInput = new ArpReponderInputBuilder().setDpId(dpnId).setInterfaceName(extInterfaceName)
- .setSpa(fixedIp).setLportTag(lportTag).buildForRemoveFlow();
- elanService.removeArpResponderFlow(arpInput);
+ WriteTransaction writeTx) {
+ String flowId = ArpResponderUtil.getFlowID(lportTag, fixedIp);
+ ArpResponderUtil.removeFlow(mdsalManager, writeTx, dpnId, flowId);
}
private long getVpnIdFromExtNetworkId(Uuid extNetworkId) {
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.BucketInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.MatchInfo;
import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.genius.mdsalutil.matches.MatchArpOp;
import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
+import org.opendaylight.netvirt.vpnmanager.arp.responder.ArpResponderConstant;
+import org.opendaylight.netvirt.vpnmanager.arp.responder.ArpResponderUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
makeL3IntfTblMissFlow(writeFlowTx, dpId, NwConstants.ADD_FLOW);
makeSubnetRouteTableMissFlow(writeFlowTx, dpId, NwConstants.ADD_FLOW);
createTableMissForVpnGwFlow(writeFlowTx, dpId);
- createL3GwMacArpFlows(writeFlowTx, dpId);
+ createArpRequestMatchFlowForGwMacTable(writeFlowTx, dpId);
+ createArpResponseMatchFlowForGwMacTable(writeFlowTx, dpId);
programTableMissForVpnVniDemuxTable(writeFlowTx, dpId, NwConstants.ADD_FLOW);
List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
futures.add(writeFlowTx.submit());
.LPORT_DISPATCHER_TABLE));
List<InstructionInfo> instructions = Collections.singletonList(new InstructionApplyActions(actionsInfos));
List<MatchInfo> matches = new ArrayList<MatchInfo>();
- String flowRef = getTableMissFlowRef(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE,
+ String flowRef = getTableMissFlowRef(dpnId, (short)NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE,
NwConstants.TABLE_MISS_FLOW);
- FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE,
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, (short)NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE,
flowRef, NwConstants.TABLE_MISS_PRIORITY, "VPN-VNI Demux Table Miss", 0, 0,
new BigInteger("1080000", 16), matches, instructions);
instructions);
LOG.trace("Invoking MDSAL to install L3 Gw Mac Table Miss Entry");
mdsalManager.addFlowToTx(flowEntityMissforGw, writeFlowTx);
+ mdsalManager.addFlowToTx(ArpResponderUtil.getArpResponderTableMissFlow(dpId), writeFlowTx);
}
- private void createL3GwMacArpFlows(WriteTransaction writeFlowTx, BigInteger dpId) {
- FlowEntity arpReqGwMacTbl = ArpResponderUtil.createArpDefaultFlow(dpId, NwConstants.L3_GW_MAC_TABLE,
- NwConstants.ARP_REQUEST, () -> Arrays.asList(MatchEthernetType.ARP, MatchArpOp.REQUEST),
- () -> Collections.singletonList(new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE)));
- LOG.trace("Invoking MDSAL to install Arp Rquest Match Flow for table {}", NwConstants.L3_GW_MAC_TABLE);
- mdsalManager.addFlowToTx(arpReqGwMacTbl, writeFlowTx);
- FlowEntity arpRepGwMacTbl = ArpResponderUtil.createArpDefaultFlow(dpId, NwConstants.L3_GW_MAC_TABLE,
- NwConstants.ARP_REPLY, () -> Arrays.asList(MatchEthernetType.ARP, MatchArpOp.REPLY),
- () -> Collections.singletonList(new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE)));
- LOG.trace("Invoking MDSAL to install Arp Reply Match Flow for Table {} ", NwConstants.L3_GW_MAC_TABLE);
- mdsalManager.addFlowToTx(arpRepGwMacTbl, writeFlowTx);
+ private void createArpRequestMatchFlowForGwMacTable(WriteTransaction writeFlowTx, BigInteger dpId) {
+ final List<BucketInfo> buckets = ArpResponderUtil.getDefaultBucketInfos(
+ NwConstants.LPORT_DISPATCHER_TABLE,
+ NwConstants.ARP_RESPONDER_TABLE);
+ ArpResponderUtil.installGroup(mdsalManager, dpId,
+ ArpResponderUtil.retrieveStandardArpResponderGroupId(idManagerService),
+ ArpResponderConstant.GROUP_FLOW_NAME.value(), buckets);
+
+ final List<MatchInfo> matches = new ArrayList<>();
+ matches.add(MatchEthernetType.ARP);
+ matches.add(MatchArpOp.REQUEST);
+ final List<ActionInfo> actionInfos = Collections.singletonList(
+ new ActionGroup(ArpResponderUtil.retrieveStandardArpResponderGroupId(idManagerService)));
+ final List<InstructionInfo> instructions = Collections.singletonList(new InstructionApplyActions(actionInfos));
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_GW_MAC_TABLE,
+ getFlowRefForArpFlows(dpId, NwConstants.L3_GW_MAC_TABLE, NwConstants.ARP_REQUEST),
+ NwConstants.DEFAULT_ARP_FLOW_PRIORITY, "L3GwMac Arp Rquest", 0, 0, new BigInteger("1080000", 16), matches,
+ instructions);
+ LOG.trace("Invoking MDSAL to install L3 Gw Mac Arp Rquest Match Flow");
+ mdsalManager.addFlowToTx(flowEntity, writeFlowTx);
+ }
+
+ private void createArpResponseMatchFlowForGwMacTable(WriteTransaction writeFlowTx, BigInteger dpId) {
+ List<MatchInfo> matches = new ArrayList<>();
+ matches.add(MatchEthernetType.ARP);
+ matches.add(MatchArpOp.REPLY);
+ List<ActionInfo> actionsInfos = new ArrayList<>();
+ actionsInfos.add(new ActionPuntToController());
+ actionsInfos.add(new ActionNxResubmit(NwConstants.LPORT_DISPATCHER_TABLE));
+ List<InstructionInfo> instructions = Collections.singletonList(new InstructionApplyActions(actionsInfos));
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_GW_MAC_TABLE,
+ getFlowRefForArpFlows(dpId, NwConstants.L3_GW_MAC_TABLE, NwConstants.ARP_REPLY),
+ NwConstants.DEFAULT_ARP_FLOW_PRIORITY, "L3GwMac Arp Reply", 0, 0, new BigInteger("1080000", 16), matches,
+ instructions);
+ LOG.trace("Invoking MDSAL to install L3 Gw Mac Arp Reply Match Flow");
+ mdsalManager.addFlowToTx(flowEntity, writeFlowTx);
+ }
+
+ private String getFlowRefForArpFlows(BigInteger dpnId, short tableId, int arpRequestOrReply) {
+ return new StringBuffer().append(FLOWID_PREFIX_FOR_ARP).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
+ .append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(arpRequestOrReply)
+ .append(FLOWID_PREFIX).toString();
}
private String getTableMissFlowRef(BigInteger dpnId, short tableId, int tableMiss) {
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroutes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
new PrefixesKey(ipPrefix)).build();
}
- public static InstanceIdentifier<VpnIds> getPrefixToInterfaceIdentifier(long vpnId) {
+ static InstanceIdentifier<VpnIds> getPrefixToInterfaceIdentifier(long vpnId) {
return InstanceIdentifier.builder(PrefixToInterface.class)
.child(VpnIds.class, new VpnIdsKey(vpnId)).build();
}
return vpnId;
}
- public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance
- .to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(
- String vpnName) {
- return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
- .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
- .VpnInstance.class,
- new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn
- .id.VpnInstanceKey(
- vpnName))
- .build();
- }
-
/**
* Retrieves the VPN Route Distinguisher searching by its Vpn instance name.
*
return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
}
- static Optional<String> getVpnAssociatedWithInterface(DataBroker broker, String interfaceName) {
+ static boolean isInterfaceAssociatedWithVpn(DataBroker broker, String vpnName, String interfaceName) {
InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
- Optional<String> vpnOptional = Optional.absent();
- Optional<VpnInterface> optConfiguredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION,
- interfaceId);
+ Optional<VpnInterface> optConfiguredVpnInterface =
+ read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
+
if (optConfiguredVpnInterface.isPresent()) {
- vpnOptional = Optional.of(optConfiguredVpnInterface.get().getVpnInstanceName());
+ String configuredVpnName = optConfiguredVpnInterface.get().getVpnInstanceName();
+ if (configuredVpnName != null && configuredVpnName.equalsIgnoreCase(vpnName)) {
+ return true;
+ }
}
- return vpnOptional;
+ return false;
}
public static String getIpPrefix(String prefix) {
return id;
}
- public static VpnPortipToPort getNeutronPortFromVpnPortFixedIp(DataBroker broker, String vpnName, String fixedIp) {
+ static VpnPortipToPort getNeutronPortFromVpnPortFixedIp(DataBroker broker, String vpnName, String fixedIp) {
InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
Optional<VpnPortipToPort> vpnPortipToPortData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
if (vpnPortipToPortData.isPresent()) {
* 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.elan.arp.responder;
+package org.opendaylight.netvirt.vpnmanager.arp.responder;
public enum ArpResponderConstant {
* <p>Value:<b>Arp:tbl_{0}:lport_{1}:gw_{2}</b>
* <ul><li>0: Table Id</li>
* <li>1: LPort Tag</li>
- * <li>2: Target Protocol Address IP in String</li></ul>
+ * <li>2: Gateway IP in String</li></ul>
*/
- FLOW_ID_FORMAT_WITH_LPORT("Arp:tbl_{0}:lport_{1}:tpa_{2}"),
- /**
- * ARP Responder Flow ID.
- *
- * <p>Value:<b>Arp:tbl_{0}:lport_{1}:gw_{2}</b>
- * <ul><li>0: Table Id</li>
- * <li>1: LPort Tag</li>
- * <li>2: Target Protocol Address IP in String</li></ul>
- */
- FLOW_ID_FORMAT_WITHOUT_LPORT("Arp:tbl_{0}:tpa_{1}"),
+ FLOW_ID_FORMAT("Arp:tbl_{0}:lport_{1}:gw_{2}"),
/**
* Pool name from which group id to be generated.
*
*
* <p>Value:<b>arp.responder.group.id</b>
*/
- ARP_RESPONDER_GROUP_ID("arp.responder.group.id"),
- /**
- * Prefix for arp check table.
- *
- * <p>Value:<b>arp.check.table.</b>
- */
- FLOWID_PREFIX_FOR_ARP_CHECK("arp.check.table."),
- /**
- * Prefix for l3 gateway mac table.
- *
- * <p>Value:<b>arp.l3.gwmac.table.</b>
- */
- FLOWID_PREFIX_FOR_MY_GW_MAC("arp.l3.gwmac.table.");
+ ARP_RESPONDER_GROUP_ID("arp.responder.group.id");
/**
* enum value holder.
+++ /dev/null
-/*
- * Copyright (c) 2016 - 2017 Ericsson India Global Services Pvt Ltd. 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.arp.responder;
-
-import com.google.common.base.Optional;
-
-import java.math.BigInteger;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderInput.ArpReponderInputBuilder;
-import org.opendaylight.netvirt.elan.arp.responder.ArpResponderUtil;
-import org.opendaylight.netvirt.elanmanager.api.IElanService;
-import org.opendaylight.netvirt.vpnmanager.VpnUtil;
-import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
-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.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Class that is responsible for handling ARP Responder flows which involves to
- * differentiate between router and connected mac cases, identify DPNs and
- * installation and uninstallation of flows.
- *
- */
-public class ArpResponderHandler {
-
- private static final Logger LOG = LoggerFactory.getLogger(ArpResponderHandler.class);
- /**
- * MDSAL DataBroker reference.
- */
- private final DataBroker dataBroker;
- /**
- * Elan RPC service reference.
- */
- private final IElanService elanService;
-
- /**
- * RPC to access InterfaceManager APIs.
- */
- private final IInterfaceManager interfaceManager;
-
- /**
- * Constructor.
- *
- * @param dataBroker
- * {@link #dataBroker}
- * @param elanService
- * {@link #elanService}
- * @param interfaceManager
- * {@link #interfaceManager}
- *
- */
- public ArpResponderHandler(DataBroker dataBroker, IElanService elanService, IInterfaceManager interfaceManager) {
- super();
- this.dataBroker = dataBroker;
- this.elanService = elanService;
- this.interfaceManager = interfaceManager;
- }
-
- /**
- * Add ARP Responder flow, by invoking ELan RPC service.
- *
- * @param dpnId
- * dpn Id on which ARP responder flow to be added
- * @param lportTag
- * lport tag of the interface
- * @param vpnName
- * vpnname of the interface
- * @param vpnId
- * vpn id that interface belongs to
- * @param interfaceName
- * interface to which ARP responder flow to be added
- * @param subnetId
- * subnet Id of the interface
- * @param gatewayIp
- * gateway ip of the interface
- * @param mac
- * mac address
- */
-
- public void addArpResponderFlow(BigInteger dpnId, int lportTag, String vpnName, long vpnId, String interfaceName,
- Uuid subnetId, String gatewayIp, String mac) {
-
- LOG.trace("Creating the ARP Responder flow for VPN Interface {}", interfaceName);
- ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
- builder.setDpId(dpnId).setInterfaceName(interfaceName).setSpa(gatewayIp).setSha(mac).setLportTag(lportTag);
- builder.setInstructions(
- ArpResponderUtil.getInterfaceInstructions(interfaceManager, interfaceName, gatewayIp, mac));
- elanService.addArpResponderFlow(builder.buildForInstallFlow());
- }
-
- /**
- * Remove ARP Responder flow when VM interface is removed, by invoking ELan
- * RPC service.
- *
- * @param dpId
- * dpn Id on which ARP responder flow to be removed
- * @param lportTag
- * lport tag of the interface
- * @param ifName
- * interface to which ARP responder flow to be removed
- * @param vpnName
- * vpnname of the interface
- * @param vpnId
- * vpn id that interface belongs to
- *
- * @param subnetUuid
- * subnet Id of the interface
- */
- public void removeArpResponderFlow(BigInteger dpId, int lportTag, String ifName, String vpnName, long vpnId,
- Uuid subnetUuid) {
- Optional<String> gwIp = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetUuid);
- if (gwIp.isPresent()) {
- ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
- builder.setDpId(dpId).setInterfaceName(ifName).setSpa(gwIp.get()).setLportTag(lportTag);
- elanService.removeArpResponderFlow(builder.buildForRemoveFlow());
- }
- }
-
- /**
- * Get Mac address from given gateway port and interface name.
- *
- * @param gwPort
- * gateway port
- * @param ifName
- * interface for which gateway to be retrieved
- * @return mac address if present else optional absent value
- */
- public Optional<String> getGatewayMacAddressForInterface(VpnPortipToPort gwPort, String ifName) {
- // Check if a router gateway interface is available for the subnet gw is
- // so then use Router interface
- // else use connected interface
- return Optional.of((gwPort != null && gwPort.isSubnetIp()) ? gwPort.getMacAddress()
- : InterfaceUtils.getMacAddressForInterface(dataBroker, ifName).get());
- }
-
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. 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.arp.responder;
+
+import java.math.BigInteger;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.genius.mdsalutil.BucketInfo;
+import org.opendaylight.genius.mdsalutil.FlowEntity;
+import org.opendaylight.genius.mdsalutil.GroupEntity;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MatchInfo;
+import org.opendaylight.genius.mdsalutil.MetaDataUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionDrop;
+import org.opendaylight.genius.mdsalutil.actions.ActionLoadIpToSpa;
+import org.opendaylight.genius.mdsalutil.actions.ActionLoadMacToSha;
+import org.opendaylight.genius.mdsalutil.actions.ActionMoveShaToTha;
+import org.opendaylight.genius.mdsalutil.actions.ActionMoveSourceDestinationEth;
+import org.opendaylight.genius.mdsalutil.actions.ActionMoveSpaToTpa;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
+import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
+import org.opendaylight.genius.mdsalutil.actions.ActionSetArpOp;
+import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
+import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
+import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
+import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.mdsalutil.matches.MatchArpOp;
+import org.opendaylight.genius.mdsalutil.matches.MatchArpTpa;
+import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
+import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
+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.action.types.rev131112.action.list.ActionKey;
+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.idmanager.rev160406.AllocateIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Arp Responder Utility Class.
+ */
+public class ArpResponderUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ArpResponderUtil.class);
+
+ private static final long WAIT_TIME_FOR_SYNC_INSTALL = Long.getLong("wait.time.sync.install", 300L);
+
+ /**
+ * A Utility class.
+ */
+ private ArpResponderUtil() {
+
+ }
+
+ /**
+ * Install Group flow on the DPN.
+ *
+ * @param mdSalManager Reference of MDSAL API RPC that provides API for installing group flow
+ * @param dpnId DPN on which group flow to be installed
+ * @param groupdId Uniquely identifiable Group Id for the group flow
+ * @param groupName Name of the group flow
+ * @param buckets List of the bucket actions for the group flow
+ */
+ public static void installGroup(final IMdsalApiManager mdSalManager,
+ final BigInteger dpnId, final long groupdId, final String groupName,
+ final List<BucketInfo> buckets) {
+ LOG.trace("Installing group flow on dpn {}", dpnId);
+ final GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId,
+ groupdId, groupName, GroupTypes.GroupAll, buckets);
+ mdSalManager.syncInstallGroup(groupEntity, WAIT_TIME_FOR_SYNC_INSTALL);
+ try {
+ Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
+ } catch (InterruptedException e1) {
+ LOG.warn("Error while waiting for ARP Responder Group Entry to be installed on DPN {} ", dpnId);
+ }
+ }
+
+ /**
+ * Get Default ARP Responder Drop flow on the DPN.
+ *
+ * @param dpnId DPN on which group flow to be installed
+ */
+ public static FlowEntity getArpResponderTableMissFlow(final BigInteger dpnId) {
+ return MDSALUtil.buildFlowEntity(dpnId, NwConstants.ARP_RESPONDER_TABLE,
+ String.valueOf(NwConstants.ARP_RESPONDER_TABLE),
+ NwConstants.TABLE_MISS_PRIORITY,
+ ArpResponderConstant.DROP_FLOW_NAME.value(), 0, 0,
+ NwConstants.COOKIE_ARP_RESPONDER,
+ new ArrayList<MatchInfo>(),
+ Collections.singletonList(new InstructionApplyActions(Collections.singletonList(new ActionDrop()))));
+ }
+
+ /**
+ * Get Bucket Actions for ARP Responder Group Flow.
+ *
+ * <p>Install Default Groups, Group has 3 Buckets
+ * </p>
+ * <ul>
+ * <li>Punt to controller</li>
+ * <li>Resubmit to Table {@link NwConstants#LPORT_DISPATCHER_TABLE}, for
+ * ELAN flooding
+ * <li>Resubmit to Table {@link NwConstants#ARP_RESPONDER_TABLE}, for ARP
+ * Auto response from DPN itself</li>
+ * </ul>
+ *
+ * @param resubmitTableId Resubmit Flow Table Id
+ * @param resubmitTableId2 Resubmit Flow Table Id
+ * @return List of bucket actions
+ */
+ public static List<BucketInfo> getDefaultBucketInfos(
+ final short resubmitTableId, final short resubmitTableId2) {
+ final List<BucketInfo> buckets = new ArrayList<>();
+ buckets.add(new BucketInfo(Collections.singletonList(new ActionPuntToController())));
+ buckets.add(new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId))));
+ buckets.add(new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId2))));
+ return buckets;
+ }
+
+ /**
+ * Get Match Criteria for the ARP Responder Flow.
+ *
+ * <p>List of Match Criteria for ARP Responder
+ * </p>
+ * <ul>
+ * <li>Packet is ARP</li>
+ * <li>Packet is ARP Request</li>
+ * <li>The ARP packet is requesting for Gateway IP</li>
+ * <li>Metadata which is generated by using Service
+ * Index({@link NwConstants#L3VPN_SERVICE_INDEX}) Lport Tag
+ * ({@link MetaDataUtil#METADATA_MASK_LPORT_TAG}) and VRF
+ * ID({@link MetaDataUtil#METADATA_MASK_VRFID})</li>
+ * </ul>
+ *
+ * @param lportTag LPort Tag
+ * @param vpnId VPN ID
+ * @param ipAddress Gateway IP
+ * @return List of Match criteria
+ */
+ public static List<MatchInfo> getMatchCriteria(final int lportTag,
+ final long vpnId, final String ipAddress) {
+
+ final List<MatchInfo> matches = new ArrayList<>();
+ short matchIndex = NwConstants.L3VPN_SERVICE_INDEX;
+ final BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(
+ lportTag, ++matchIndex, MetaDataUtil.getVpnIdMetadata(vpnId));
+ final BigInteger metadataMask = MetaDataUtil
+ .getMetaDataMaskForLPortDispatcher(
+ MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
+ MetaDataUtil.METADATA_MASK_LPORT_TAG,
+ MetaDataUtil.METADATA_MASK_VRFID);
+
+ // Matching Arp request flows
+ matches.add(MatchEthernetType.ARP);
+ matches.add(new MatchMetadata(metadata, metadataMask));
+ matches.add(MatchArpOp.REQUEST);
+ matches.add(new MatchArpTpa(ipAddress, "32"));
+ return matches;
+
+ }
+
+ /**
+ * Get List of actions for ARP Responder Flows.
+ *
+ * <p>Actions consists of all the ARP actions from
+ * and Egress Actions Retrieved
+ *
+ * @param ifaceMgrRpcService Interface manager RPC reference to invoke RPC to get Egress actions for the interface
+ * @param vpnInterface VPN Interface for which flow to be installed
+ * @param ipAddress Gateway IP Address
+ * @param macAddress Gateway MacAddress
+ * @return List of ARP Responder Actions actions
+ */
+ public static List<Action> getActions(
+ final OdlInterfaceRpcService ifaceMgrRpcService,
+ final String vpnInterface, final String ipAddress,
+ final String macAddress) {
+
+ final List<Action> actions = new ArrayList<>();
+ int actionCounter = 0;
+ actions.add(new ActionMoveSourceDestinationEth().buildAction(actionCounter++));
+ actions.add(new ActionSetFieldEthernetSource(new MacAddress(macAddress)).buildAction(actionCounter++));
+ actions.add(new ActionSetArpOp(NwConstants.ARP_REPLY).buildAction(actionCounter++));
+ actions.add(new ActionMoveShaToTha().buildAction(actionCounter++));
+ actions.add(new ActionMoveSpaToTpa().buildAction(actionCounter++));
+ actions.add(new ActionLoadMacToSha(new MacAddress(macAddress)).buildAction(actionCounter++));
+ actions.add(new ActionLoadIpToSpa(ipAddress).buildAction(actionCounter++));
+ // A temporary fix until to send packet to incoming port by loading IN_PORT with zero, until in_port is
+ // overridden in table=0
+ actions.add(new ActionNxLoadInPort(BigInteger.ZERO).buildAction(actionCounter++));
+
+ actions.addAll(getEgressActionsForInterface(ifaceMgrRpcService, vpnInterface, actionCounter));
+ LOG.trace("Total Number of actions is {}", actionCounter);
+ return actions;
+
+ }
+
+ /**
+ * Get instruction list for ARP responder flows originated from ext-net e.g.
+ * router-gw/fip.<br>
+ * The split-horizon bit should be reset in order to allow traffic from
+ * provider network to be routed back to flat/VLAN network and override the
+ * egress table drop flow.<br>
+ * In order to allow write-metadata in the ARP responder table the resubmit
+ * action needs to be replaced with goto instruction.
+ */
+ public static List<Instruction> getExtInterfaceInstructions(final OdlInterfaceRpcService ifaceMgrRpcService,
+ final String extInterfaceName, final String ipAddress, final String macAddress) {
+ Short tableId = null;
+ List<Instruction> instructions = new ArrayList<>();
+ List<Action> actions = getActions(ifaceMgrRpcService, extInterfaceName, ipAddress, macAddress);
+ for (Iterator<Action> iterator = actions.iterator(); iterator.hasNext();) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = iterator
+ .next().getAction();
+ if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
+ tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
+ iterator.remove();
+ break;
+ }
+ }
+
+ instructions.add(MDSALUtil.buildApplyActionsInstruction(actions, 0));
+ // reset the split-horizon bit to allow traffic to be sent back to the
+ // provider port
+ instructions.add(
+ new InstructionWriteMetadata(BigInteger.ZERO, MetaDataUtil.METADATA_MASK_SH_FLAG).buildInstruction(1));
+
+ if (tableId != null) {
+ // replace resubmit action with goto so it can co-exist with
+ // write-metadata
+ if (tableId > NwConstants.ARP_RESPONDER_TABLE) {
+ instructions.add(new InstructionGotoTable(tableId).buildInstruction(2));
+ } else {
+ LOG.warn("Failed to insall responder flow for interface {}. Resubmit to {} can't be replaced with goto",
+ extInterfaceName, tableId);
+ }
+ }
+
+ return instructions;
+ }
+
+ /**
+ * Install ARP Responder FLOW.
+ *
+ * @param mdSalManager
+ * Reference of MDSAL API RPC that provides API for installing
+ * flow
+ * @param writeInvTxn
+ * Write Transaction to write the flow
+ * @param dpnId
+ * DPN on which flow to be installed
+ * @param flowId
+ * Uniquely Identifiable Arp Responder Table flow Id
+ * @param flowName
+ * Readable flow name
+ * @param priority
+ * Flow Priority
+ * @param cookie
+ * Flow Cookie
+ * @param matches
+ * List of Match Criteria for the flow
+ * @param instructions
+ * List of Instructions for the flow
+ */
+ public static void installFlow(final IMdsalApiManager mdSalManager,
+ final WriteTransaction writeInvTxn, final BigInteger dpnId,
+ final String flowId, final String flowName,
+ final int priority, final BigInteger cookie,
+ List<MatchInfo> matches, List<Instruction> instructions) {
+ final Flow flowEntity = MDSALUtil.buildFlowNew(
+ NwConstants.ARP_RESPONDER_TABLE, flowId, priority, flowName, 0,
+ 0, cookie, matches, instructions);
+ mdSalManager.addFlowToTx(dpnId, flowEntity, writeInvTxn);
+ }
+
+ /**
+ * Remove flow form DPN.
+ *
+ * @param mdSalManager Reference of MDSAL API RPC that provides API for installing flow
+ * @param writeInvTxn Write Transaction to write the flow
+ * @param dpnId DPN form which flow to be removed
+ * @param flowId Uniquely Identifiable Arp Responder Table flow Id that is to be removed
+ */
+ public static void removeFlow(final IMdsalApiManager mdSalManager,
+ final WriteTransaction writeInvTxn,
+ final BigInteger dpnId, final String flowId) {
+ final Flow flowEntity = MDSALUtil
+ .buildFlow(NwConstants.ARP_RESPONDER_TABLE, flowId);
+ mdSalManager.removeFlowToTx(dpnId, flowEntity, writeInvTxn);
+ }
+
+ /**
+ * Creates Uniquely Identifiable flow Id.
+ *
+ * <p><b>Refer:</b> {@link ArpResponderConstant#FLOW_ID_FORMAT}
+ *
+ * @param lportTag LportTag of the flow
+ * @param gwIp Gateway IP for which ARP Response flow to be installed
+ * @return Unique Flow Id
+ */
+ public static String getFlowID(final int lportTag, final String gwIp) {
+ return MessageFormat.format(ArpResponderConstant.FLOW_ID_FORMAT.value(),
+ NwConstants.ARP_RESPONDER_TABLE, lportTag, gwIp);
+ }
+
+ /**
+ * Generate Cookie per flow.
+ *
+ * <p>Cookie is generated by Summation of
+ * {@link NwConstants#COOKIE_ARP_RESPONDER} + 1 + lportTag + Gateway IP
+ *
+ * @param lportTag Lport Tag of the flow
+ * @param gwIp Gateway IP for which ARP Response flow to be installed
+ * @return Cookie
+ */
+ public static BigInteger generateCookie(final long lportTag,
+ final String gwIp) {
+ LOG.trace("IPAddress in long {}", gwIp);
+ return NwConstants.COOKIE_ARP_RESPONDER.add(BigInteger.ONE)
+ .add(BigInteger.valueOf(lportTag))
+ .add(BigInteger.valueOf(ipTolong(gwIp)));
+ }
+
+ /**
+ * Get IP Address in Long from String.
+ *
+ * @param address IP Address that to be converted to long
+ * @return Long value of the IP Address
+ */
+ private static long ipTolong(String address) {
+
+ // Parse IP parts into an int array
+ long[] ip = new long[4];
+ String[] parts = address.split("\\.");
+
+ for (int i = 0; i < 4; i++) {
+ ip[i] = Long.parseLong(parts[i]);
+ }
+ // Add the above IP parts into an int number representing your IP
+ // in a 32-bit binary form
+ long ipNumbers = 0;
+ for (int i = 0; i < 4; i++) {
+ ipNumbers += ip[i] << (24 - (8 * i));
+ }
+ return ipNumbers;
+
+ }
+
+ /**
+ * Get List of Egress Action for the VPN interface.
+ *
+ * @param ifaceMgrRpcService Interface Manager RPC reference that invokes API to retrieve Egress Action
+ * @param ifName VPN Interface for which Egress Action to be retrieved
+ * @param actionCounter Action Key
+ * @return List of Egress Actions
+ */
+ public static List<Action> getEgressActionsForInterface(
+ final OdlInterfaceRpcService ifaceMgrRpcService, String ifName,
+ int actionCounter) {
+ final List<Action> listActions = new ArrayList<>();
+ try {
+ final RpcResult<GetEgressActionsForInterfaceOutput> result = ifaceMgrRpcService
+ .getEgressActionsForInterface(
+ new GetEgressActionsForInterfaceInputBuilder()
+ .setIntfName(ifName).build())
+ .get();
+ if (result.isSuccessful()) {
+ final List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action>
+ actions = result
+ .getResult().getAction();
+ for (final Action action : actions) {
+
+ listActions
+ .add(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list
+ .ActionBuilder(
+ action).setKey(new ActionKey(actionCounter))
+ .setOrder(actionCounter++).build());
+
+ }
+ } else {
+ LOG.warn(
+ "RPC Call to Get egress actions for interface {} returned with Errors {}",
+ ifName, result.getErrors());
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Exception when egress actions for interface {}", ifName,
+ e);
+ }
+ return listActions;
+ }
+
+ /**
+ * Uses the IdManager to retrieve ARP Responder GroupId from ELAN pool.
+ *
+ * @param idManager the id manager
+ * @return the integer
+ */
+ public static Long retrieveStandardArpResponderGroupId(IdManagerService idManager) {
+
+ AllocateIdInput getIdInput =
+ new AllocateIdInputBuilder().setPoolName(ArpResponderConstant.ELAN_ID_POOL_NAME.value())
+ .setIdKey(ArpResponderConstant.ARP_RESPONDER_GROUP_ID.value()).build();
+
+ try {
+ Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
+ RpcResult<AllocateIdOutput> rpcResult = result.get();
+ if (rpcResult.isSuccessful()) {
+ LOG.trace("Retrieved Group Id is {}", rpcResult.getResult().getIdValue());
+ return rpcResult.getResult().getIdValue();
+ } else {
+ LOG.warn("RPC Call to Allocate Id returned with Errors {}", rpcResult.getErrors());
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("Exception when Allocating Id", e);
+ }
+ return 0L;
+ }
+
+}
<service ref="vpnFootprintService"
interface="org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService" />
- <bean id="arpResponderHandler" class="org.opendaylight.netvirt.vpnmanager.arp.responder.ArpResponderHandler">
- <argument ref="dataBroker" />
- <argument ref="elanService" />
- <argument ref="interfaceManager" />
- </bean>
-
<bean id="vpnInterfaceManager"
class="org.opendaylight.netvirt.vpnmanager.VpnInterfaceManager"
init-method="start" destroy-method="close">
<argument ref="interfaceManager" />
<argument ref="vpnManager" />
<argument ref="interVpnLinkService" />
- <argument ref="arpResponderHandler" />
</bean>
<bean id="interfaceStateChangeListener"
<argument ref="vpnInterfaceManager" />
<argument ref="mdsalUtils" />
<argument ref="vpnFootprintService" />
+ <argument ref="odlInterfaceRpcService" />
<argument ref="elanService" />
- <argument ref="interfaceManager" />
<argument ref="vpnSubnetRouteHandler" />
+
</bean>
<service ref="vpnManagerImpl"
interface="org.opendaylight.netvirt.vpnmanager.api.IVpnManager" />