import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.ExecutionException;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
import org.opendaylight.netvirt.vpnmanager.api.ICentralizedSwitchProvider;
import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
+import org.opendaylight.netvirt.vpnmanager.iplearn.ipv4.ArpUtils;
import org.opendaylight.netvirt.vpnmanager.utilities.VpnManagerCounters;
import org.opendaylight.openflowplugin.libraries.liblldp.BitBufferHelper;
import org.opendaylight.openflowplugin.libraries.liblldp.BufferException;
import org.opendaylight.openflowplugin.libraries.liblldp.HexEncode;
-import org.opendaylight.openflowplugin.libraries.liblldp.NetUtils;
import org.opendaylight.openflowplugin.libraries.liblldp.Packet;
import org.opendaylight.openflowplugin.libraries.liblldp.PacketException;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
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.natservice.rev160111.ext.routers.Routers;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
+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.neutronvpn.rev150602.subnetmaps.Subnetmap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
private final IInterfaceManager interfaceManager;
private final VpnManagerCounters vpnManagerCounters;
private final Ipv6NdUtilService ipv6NdUtilService;
+ private final VpnUtil vpnUtil;
@Inject
public SubnetRoutePacketInHandler(final DataBroker dataBroker, final PacketProcessingService packetService,
final OdlInterfaceRpcService odlInterfaceRpcService,
final ICentralizedSwitchProvider centralizedSwitchProvider, final IInterfaceManager interfaceManager,
- VpnManagerCounters vpnManagerCounters, final Ipv6NdUtilService ipv6NdUtilService) {
+ VpnManagerCounters vpnManagerCounters, final Ipv6NdUtilService ipv6NdUtilService, VpnUtil vpnUtil) {
this.dataBroker = dataBroker;
this.packetService = packetService;
this.odlInterfaceRpcService = odlInterfaceRpcService;
this.interfaceManager = interfaceManager;
this.vpnManagerCounters = vpnManagerCounters;
this.ipv6NdUtilService = ipv6NdUtilService;
+ this.vpnUtil = vpnUtil;
}
@Override
short tableId = notification.getTableId().getValue();
LOG.trace("{} onPacketReceived: Packet punted from table {}", LOGGING_PREFIX, tableId);
+ if (!vpnUtil.isArpLearningEnabled()) {
+ LOG.trace("Not handling packet as ARP Based Learning is disabled");
+ return;
+ }
byte[] data = notification.getPayload();
if (notification.getMatch() == null || notification.getMatch().getMetadata() == null) {
LOG.error("{} onPacketReceived: Received from table {} where the match or metadata are null",
if (tableId == NwConstants.L3_SUBNET_ROUTE_TABLE) {
LOG.trace("{} onPacketReceived: Some packet received as {}", LOGGING_PREFIX, notification);
try {
- res.deserialize(data, 0, data.length * NetUtils.NUM_BITS_IN_A_BYTE);
+ res.deserialize(data, 0, data.length * Byte.SIZE);
} catch (PacketException e) {
LOG.error("{} onPacketReceived: Failed to decode Packet ", LOGGING_PREFIX, e);
vpnManagerCounters.subnetRoutePacketFailed();
}
String vpnIdVpnInstanceName = vpnIdsOptional.get().getVpnInstanceName();
- if (VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnIdVpnInstanceName, dstIpStr) != null) {
+ VpnPortipToPort persistedIP =
+ vpnUtil.getNeutronPortFromVpnPortFixedIp(vpnIdVpnInstanceName, dstIpStr);
+ if (persistedIP != null && !persistedIP.isLearntIp()) {
vpnManagerCounters.subnetRoutePacketIgnored();
LOG.info("{} onPacketReceived: IP Packet received with Target IP {} source IP {} vpnId {} "
+ "is a valid Neutron port,ignoring subnet route processing", LOGGING_PREFIX, dstIpStr,
return;
}
- if (VpnUtil.getLearntVpnVipToPort(dataBroker, vpnIdVpnInstanceName, dstIpStr) != null) {
+ if (vpnUtil.getLearntVpnVipToPort(vpnIdVpnInstanceName, dstIpStr) != null) {
vpnManagerCounters.subnetRoutePacketIgnored();
LOG.info("{} onPacketReceived: IP Packet received with Target IP {} source Ip {} vpnId {}"
+ " is an already discovered IPAddress, ignoring subnet route processing",
LOG.info("{} handleBgpVpnSubnetRoute: Processing IP Packet received with Source IP {} and Target IP {}"
+ " and elan Tag {}", LOGGING_PREFIX, srcIpStr, dstIpStr, elanTag);
SubnetOpDataEntry targetSubnetForPacketOut =
- getTargetSubnetForPacketOut(dataBroker, elanTag, dstIpStr);
-
+ getTargetSubnetForPacketOut(elanTag, dstIpStr);
if (targetSubnetForPacketOut != null) {
// Handle subnet routes ip requests
transmitArpOrNsPacket(targetSubnetForPacketOut.getNhDpnId(), srcIpStr, srcMac, dstIp, dstIpStr, elanTag);
private void handleInternalVpnSubnetRoutePacket(BigInteger metadata, byte[] dstIp, String srcIpStr, String dstIpStr,
String vpnIdVpnInstanceName, long elanTag)
throws InterruptedException, ExecutionException, UnknownHostException {
- String vmVpnInterfaceName = VpnUtil.getVpnInterfaceName(odlInterfaceRpcService, metadata);
+ String vmVpnInterfaceName = vpnUtil.getVpnInterfaceName(metadata);
if (isTunnel(vmVpnInterfaceName)) {
handlePacketFromTunnelToExternalNetwork(vpnIdVpnInstanceName, srcIpStr, dstIp, dstIpStr, elanTag);
}
- VpnInterface vmVpnInterface = VpnUtil.getVpnInterface(dataBroker, vmVpnInterfaceName);
+ VpnInterface vmVpnInterface = vpnUtil.getVpnInterface(vmVpnInterfaceName);
if (vmVpnInterface == null) {
LOG.error("Vpn interface {} doesn't exist.", vmVpnInterfaceName);
vpnManagerCounters.subnetRoutePacketFailed();
}
if (VpnHelper.doesVpnInterfaceBelongToVpnInstance(vpnIdVpnInstanceName,
vmVpnInterface.getVpnInstanceNames())
- && !VpnUtil.isBgpVpnInternet(dataBroker, vpnIdVpnInstanceName)) {
+ && !vpnUtil.isBgpVpnInternet(vpnIdVpnInstanceName)) {
LOG.trace("Unknown IP is in internal network");
handlePacketToInternalNetwork(dstIp, dstIpStr, elanTag);
} else {
LOG.trace("Unknown IP is in external network");
- String vpnName =
- VpnUtil.getInternetVpnFromVpnInstanceList(dataBroker, vmVpnInterface.getVpnInstanceNames());
+ String vpnName = vpnUtil.getInternetVpnFromVpnInstanceList(vmVpnInterface.getVpnInstanceNames());
if (vpnName != null) {
handlePacketToExternalNetwork(new Uuid(vpnIdVpnInstanceName), vpnName, dstIp, dstIpStr, elanTag);
} else {
String dstIpAddress, long elanTag) throws UnknownHostException {
long groupid = VpnUtil.getRemoteBCGroup(elanTag);
if (NWUtil.isIpv4Address(dstIpAddress)) {
- LOG.debug("Sending ARP: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}", sourceIpAddress, sourceMac,
- dstIpAddress, dpnId, elanTag);
+ LOG.debug("Sending ARP: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}, groupid={}", sourceIpAddress,
+ sourceMac, dstIpAddress, dpnId, elanTag, groupid);
vpnManagerCounters.subnetRoutePacketArpSent();
TransmitPacketInput packetInput =
JdkFutures.addErrorLogging(packetService.transmitPacket(packetInput), LOG, "Transmit packet");
} else {
// IPv6 case
- LOG.debug("Sending NS: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}", sourceIpAddress, sourceMac,
- dstIpAddress, dpnId, elanTag);
+ LOG.debug("Sending NS: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}, groupid={}", sourceIpAddress,
+ sourceMac, dstIpAddress, dpnId, elanTag, groupid);
vpnManagerCounters.subnetRoutePacketNsSent();
VpnUtil.sendNeighborSolicationToOfGroup(this.ipv6NdUtilService, new Ipv6Address(sourceIpAddress),
throws UnknownHostException {
try {
SubnetOpDataEntry targetSubnetForPacketOut =
- getTargetSubnetForPacketOut(dataBroker, elanTag, dstIpStr);
+ getTargetSubnetForPacketOut(elanTag, dstIpStr);
if (targetSubnetForPacketOut == null) {
LOG.debug("Couldn't find matching subnet for elan tag {} and destination ip {}", elanTag, dstIpStr);
}
private void handlePacketFromTunnelToExternalNetwork(String vpnIdVpnInstanceName, String srcIpStr, byte[] dstIp,
- String dstIpStr, long elanTag) throws UnknownHostException {
- String routerId = VpnUtil.getAssociatedExternalRouter(dataBroker, srcIpStr);
+ String dstIpStr, long elanTag) throws UnknownHostException {
+ String routerId = vpnUtil.getAssociatedExternalRouter(srcIpStr);
if (null == routerId) {
LOG.debug("This ip is not associated with any external router: {}", srcIpStr);
+ return;
}
handlePacketToExternalNetwork(new Uuid(vpnIdVpnInstanceName), routerId, dstIp, dstIpStr, elanTag);
}
private void handlePacketToExternalNetwork(Uuid vpnInstanceNameUuid, String routerId, byte[] dstIp, String dstIpStr,
long elanTag) throws UnknownHostException {
- Routers externalRouter = VpnUtil.getExternalRouter(dataBroker, routerId);
+ Routers externalRouter = vpnUtil.getExternalRouter(routerId);
if (externalRouter == null) {
vpnManagerCounters.subnetRoutePacketFailed();
LOG.debug("{} handlePacketToExternalNetwork: Can't find external router with id {}", LOGGING_PREFIX,
}
// return only the first VPN subnetopdataentry
- private static SubnetOpDataEntry getTargetSubnetForPacketOut(DataBroker broker, long elanTag, String ipAddress) {
- ElanTagName elanInfo = VpnUtil.getElanInfoByElanTag(broker, elanTag);
+ @Nullable
+ private SubnetOpDataEntry getTargetSubnetForPacketOut(long elanTag, String ipAddress) {
+ ElanTagName elanInfo = vpnUtil.getElanInfoByElanTag(elanTag);
if (elanInfo == null) {
LOG.error("{} getTargetDpnForPacketOut: Unable to retrieve ElanInfo for elanTag {}", LOGGING_PREFIX,
elanTag);
return null;
}
try {
- Optional<NetworkMap> optionalNetworkMap = SingleTransactionDataBroker.syncReadOptional(broker,
+ Optional<NetworkMap> optionalNetworkMap = SingleTransactionDataBroker.syncReadOptional(dataBroker,
LogicalDatastoreType.CONFIGURATION, VpnUtil.buildNetworkMapIdentifier(new Uuid(
elanInfo.getName())));
if (!optionalNetworkMap.isPresent()) {
List<Uuid> subnetList = optionalNetworkMap.get().getSubnetIdList();
LOG.debug("{} getTargetDpnForPacketOut: Obtained subnetList as {} for network {}", LOGGING_PREFIX,
subnetList, elanInfo.getName());
- for (Uuid subnetId : subnetList) {
- String vpnName = null;
- Subnetmap sn = VpnUtil.getSubnetmapFromItsUuid(broker, subnetId);
- if (sn != null && sn.getVpnId() != null) {
- vpnName = sn.getVpnId().getValue();
- }
- if (vpnName == null) {
- continue;
- }
- Optional<SubnetOpDataEntry> optionalSubs;
- optionalSubs = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.buildSubnetOpDataEntryInstanceIdentifier(subnetId));
- if (!optionalSubs.isPresent()) {
- continue;
- }
- SubnetOpDataEntry subOpEntry = optionalSubs.get();
- if (subOpEntry.getNhDpnId() != null) {
- LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {}", LOGGING_PREFIX, subnetId.getValue());
- IpPrefix cidr = new IpPrefix(subOpEntry.getSubnetCidr().toCharArray());
- boolean match = NWUtil.isIpAddressInRange(new IpAddress(ipAddress.toCharArray()), cidr);
- LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {} matching {}", LOGGING_PREFIX,
+ if (subnetList != null) {
+ for (Uuid subnetId : subnetList) {
+ String vpnName = null;
+ Subnetmap sn = vpnUtil.getSubnetmapFromItsUuid(subnetId);
+ if (sn != null && sn.getVpnId() != null) {
+ vpnName = sn.getVpnId().getValue();
+ }
+ if (vpnName == null) {
+ continue;
+ }
+ Optional<SubnetOpDataEntry> optionalSubs = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, VpnUtil.buildSubnetOpDataEntryInstanceIdentifier(subnetId));
+ if (!optionalSubs.isPresent()) {
+ continue;
+ }
+ SubnetOpDataEntry subOpEntry = optionalSubs.get();
+ if (subOpEntry.getNhDpnId() != null) {
+ LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {}", LOGGING_PREFIX,
+ subnetId.getValue());
+ IpPrefix cidr = IpPrefixBuilder.getDefaultInstance(subOpEntry.getSubnetCidr());
+ boolean match = NWUtil.isIpAddressInRange(IpAddressBuilder.getDefaultInstance(ipAddress), cidr);
+ LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {} matching {}", LOGGING_PREFIX,
subnetId.getValue(), match);
- if (match) {
- return subOpEntry;
+ if (match) {
+ return subOpEntry;
+ }
}
}
}
}
public boolean isTunnel(String interfaceName) {
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
- .ietf.interfaces.rev140508.interfaces.Interface configIface =
- interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
- return configIface.augmentation(IfTunnel.class) != null;
+ return interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName).augmentation(IfTunnel.class) != null;
}
}