leaf port-name { type string;}
leaf mac-address { type string;}
leaf subnet-ip { type boolean;}
+ leaf learnt-ip { type boolean; default false;}
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
+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.router.interfaces.map.RouterInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
Optional<LearntVpnVipToPort> optionalVpnVipToPort =
SingleTransactionDataBroker.syncReadOptional(dataBroker,
LogicalDatastoreType.OPERATIONAL, id);
- if (optionalVpnVipToPort.isPresent()) {
+ if (optionalVpnVipToPort.isPresent()
+ && optionalVpnVipToPort.get().getPortName().equals(infName)) {
LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} "
+ "from VPN {}", infName, vpnId, oldVpnId);
adjacencyIter.remove();
neutronvpnUtils.removeLearntVpnVipToPort(oldVpnId.getValue(), mipToQuery);
LOG.trace(
- "Entry for fixedIP {} for port {} on VPN {} removed from VpnPortFixedIPToPortData",
+ "Entry for fixedIP {} for port {} on VPN {} removed from LearntVpnVipToPort",
+ mipToQuery, infName, vpnId.getValue());
+ }
+ InstanceIdentifier<VpnPortipToPort> build =
+ neutronvpnUtils.buildVpnPortipToPortIdentifier(oldVpnId.getValue(), mipToQuery);
+ Optional<VpnPortipToPort> persistedIp = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, build);
+ if (persistedIp.isPresent() && persistedIp.get().getPortName().equals(infName)) {
+ neutronvpnUtils.removeVpnPortFixedIpToPort(oldVpnId.getValue(), mipToQuery, null);
+ LOG.trace("Entry for fixedIP {} for port {} on VPN {} removed from VpnPortipToPort",
mipToQuery, infName, vpnId.getValue());
}
}
} else {
MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
}
- LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from LearntVpnPortipToPort DS", fixedIp,
+ LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from VpnPortipToPort DS", fixedIp,
vpnName);
} catch (Exception e) {
LOG.error("Failure while removing VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp,
}
}
}
+
+ rpc apply-arp-config {
+ description "To apply ARP/GARP related configuration per PL";
+ input {
+ leaf enable-arp-learning {
+ description "Enable (or) Disable arp based learning dynamically";
+ type boolean;
+ }
+ }
+ output {
+ leaf enable-arp-learning {
+ type boolean;
+ }
+ }
+ }
}
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;
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",
}
String vpnIdVpnInstanceName = vpnIdsOptional.get().getVpnInstanceName();
- if (vpnUtil.getNeutronPortFromVpnPortFixedIp(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,
InstanceIdentifier<AdjacenciesOp> path = identifier.augmentation(AdjacenciesOp.class);
Optional<AdjacenciesOp> adjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker,
LogicalDatastoreType.OPERATIONAL, path);
+ boolean isNonPrimaryAdjIp = Boolean.FALSE;
String primaryRd = vpnUtil.getVpnRd(vpnName);
LOG.info("removeAdjacenciesFromVpn: For interface {} on dpn {} RD recovered for vpn {} as rd {}",
interfaceName, dpnId, vpnName, primaryRd);
List<String> nhList;
if (nextHop.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
nhList = getNextHopForNonPrimaryAdjacency(nextHop, vpnName, dpnId, interfaceName);
+ isNonPrimaryAdjIp = Boolean.TRUE;
} else {
// This is a primary adjacency
nhList = nextHop.getNextHopIpList() != null ? nextHop.getNextHopIpList()
}
String ip = nextHop.getIpAddress().split("/")[0];
LearntVpnVipToPort vpnVipToPort = vpnUtil.getLearntVpnVipToPort(vpnName, ip);
- if (vpnVipToPort != null) {
+ if (vpnVipToPort != null && vpnVipToPort.getPortName().equals(interfaceName)) {
vpnUtil.removeLearntVpnVipToPort(vpnName, ip, null);
LOG.info("removeAdjacenciesFromVpn: VpnInterfaceManager removed LearntVpnVipToPort entry"
+ " for Interface {} ip {} on dpn {} for vpn {}",
vpnVipToPort.getPortName(), ip, dpnId, vpnName);
}
+ // Remove the MIP-IP from VpnPortIpToPort.
+ if (isNonPrimaryAdjIp) {
+ VpnPortipToPort persistedIp = vpnUtil.getVpnPortipToPort(vpnName, ip);
+ if (persistedIp != null && persistedIp.isLearntIp()
+ && persistedIp.getPortName().equals(interfaceName)) {
+ VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, ip, null);
+ LOG.info(
+ "removeAdjacenciesFromVpn: Learnt-IP: {} interface {} of vpn {} removed "
+ + "from VpnPortipToPort",
+ persistedIp.getPortFixedip(), persistedIp.getPortName(), vpnName);
+ }
+ }
VpnPortipToPort vpnPortipToPort = vpnUtil.getNeutronPortFromVpnPortFixedIp(vpnName, ip);
if (vpnPortipToPort != null) {
VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, ip, null);
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.ApplyArpConfigInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.ApplyArpConfigOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.ApplyArpConfigOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.GenerateVpnLabelInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.GenerateVpnLabelOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.GenerateVpnLabelOutputBuilder;
logger.accept(message);
return message;
}
+
+ @Override
+ public ListenableFuture<RpcResult<ApplyArpConfigOutput>> applyArpConfig(ApplyArpConfigInput input) {
+ Boolean isArpLearningEnabled = input.isEnableArpLearning();
+ LOG.info("isArpLearningEnabled {}", isArpLearningEnabled);
+ SettableFuture<RpcResult<ApplyArpConfigOutput>> result = SettableFuture.create();
+ ApplyArpConfigOutputBuilder output = new ApplyArpConfigOutputBuilder();
+ VpnUtil.enableArpLearning(isArpLearningEnabled);
+ output.setEnableArpLearning(VpnUtil.isArpLearningEnabled());
+ result.set(RpcResultBuilder.success(output).build());
+ return result;
+ }
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
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.neutron.vpn.portip.port.data.VpnPortipToPortBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
private static final Logger LOG = LoggerFactory.getLogger(VpnUtil.class);
public static final int SINGLE_TRANSACTION_BROKER_NO_RETRY = 1;
+ private static Boolean arpLearningEnabled = Boolean.TRUE;
private final DataBroker dataBroker;
private final IdManagerService idManager;
}
+ // TODO Clean up the exception handling
+ @SuppressWarnings("checkstyle:IllegalCatch")
public void removeMipAdjAndLearntIp(String vpnName, String vpnInterface, String prefix) {
synchronized ((vpnName + prefix).intern()) {
- InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, prefix);
- MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
- LOG.info("removeMipAdjAndLearntIp: Delete learned ARP for fixedIp: {}, vpn {} removed from"
- + "VpnPortipToPort DS", prefix, vpnName);
- String ip = VpnUtil.getIpPrefix(prefix);
- InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpId = VpnUtil
- .getVpnInterfaceOpDataEntryIdentifier(vpnInterface, vpnName);
- InstanceIdentifier<AdjacenciesOp> path = vpnInterfaceOpId.augmentation(AdjacenciesOp.class);
- Optional<AdjacenciesOp> adjacenciesOp = read(LogicalDatastoreType.OPERATIONAL, path);
- if (adjacenciesOp.isPresent()) {
- InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
- .child(VpnInterface.class, new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class)
- .child(Adjacency.class, new AdjacencyKey(ip)).build();
- MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
- LOG.info("removeMipAdjAndLearntIp: Successfully Deleted Adjacency {} from interface {} vpn {}", ip,
- vpnInterface, vpnName);
+ try {
+ String ip = VpnUtil.getIpPrefix(prefix);
+ InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpId = VpnUtil
+ .getVpnInterfaceOpDataEntryIdentifier(vpnInterface, vpnName);
+ InstanceIdentifier<AdjacenciesOp> path = vpnInterfaceOpId.augmentation(AdjacenciesOp.class);
+ Optional<AdjacenciesOp> adjacenciesOp = read(LogicalDatastoreType.OPERATIONAL, path);
+ if (adjacenciesOp.isPresent()) {
+ InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
+ .child(VpnInterface.class, new VpnInterfaceKey(vpnInterface))
+ .augmentation(Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ip)).build();
+ MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
+ LOG.info("removeMipAdjAndLearntIp: Successfully Deleted Adjacency {} from interface {} vpn {}", ip,
+ vpnInterface, vpnName);
+ }
+ InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, prefix);
+ MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+ LOG.info("removeMipAdjAndLearntIp: Delete learned ARP for fixedIp: {}, vpn {} removed from"
+ + "VpnPortipToPort DS", prefix, vpnName);
+ } catch (Exception e) {
+ LOG.error("removeMipAdjAndLearntIp: Exception Deleting learned Ip: {} interface {} vpn {} from "
+ + "LearntVpnPortipToPort DS", prefix, vpnInterface, vpnName, e);
}
+ VpnUtil.removeVpnPortFixedIpToPort(dataBroker, vpnName, prefix, null);
}
}
return oldVpnListCopy.size() == 2 && newVpnListCopy.size() == 3
|| oldVpnListCopy.size() == 3 && newVpnListCopy.size() == 2;
}
+
+ // TODO Clean up the exception handling
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ public void createVpnPortFixedIpToPort(String vpnName, String fixedIp,
+ String portName, boolean isLearntIp, String macAddress,
+ WriteTransaction writeConfigTxn) {
+ InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
+ VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder().withKey(new VpnPortipToPortKey(fixedIp, vpnName))
+ .setVpnName(vpnName).setPortFixedip(fixedIp).setPortName(portName)
+ .setLearntIp(isLearntIp).setSubnetIp(false).setMacAddress(macAddress.toLowerCase(Locale.getDefault()));
+ try {
+ if (writeConfigTxn != null) {
+ writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, id, builder.build());
+ } else {
+ syncWrite(LogicalDatastoreType.CONFIGURATION, id, builder.build());
+ }
+ LOG.trace("Port with Ip: {}, vpn {}, interface {}, learntIp {} added to VpnPortipToPort DS",
+ fixedIp, vpnName, portName, isLearntIp);
+ } catch (Exception e) {
+ LOG.error("Failure while creating VpnPortIpToPort map for vpn {} learnIp{}", vpnName, fixedIp, e);
+ }
+ }
+
+ protected VpnPortipToPort getVpnPortipToPort(String vpnName, String fixedIp) {
+ InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
+ Optional<VpnPortipToPort> vpnPortipToPortData = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (vpnPortipToPortData.isPresent()) {
+ return vpnPortipToPortData.get();
+ }
+ LOG.error("getVpnPortipToPort: Failed as vpnPortipToPortData DS is absent for VPN {} and fixed IP {}",
+ vpnName, fixedIp);
+ return null;
+ }
+
+ public static void enableArpLearning(Boolean isArpLearningEnabled) {
+ arpLearningEnabled = isArpLearningEnabled;
+ }
+
+ public static Boolean isArpLearningEnabled() {
+ return arpLearningEnabled;
+ }
}
protected final VpnConfig config;
protected final VpnUtil vpnUtil;
protected final INeutronVpnManager neutronVpnManager;
+ private long bootupTime = 0L;
public AbstractIpLearnNotificationHandler(VpnConfig vpnConfig, VpnUtil vpnUtil,
INeutronVpnManager neutronVpnManager) {
migrateIpCache =
CacheBuilder.newBuilder().maximumSize(cacheSize).expireAfterWrite(duration,
TimeUnit.MILLISECONDS).build();
+ this.bootupTime = System.currentTimeMillis();
}
protected void validateAndProcessIpLearning(String srcInterface, IpAddress srcIP, MacAddress srcMac,
protected void processIpLearning(String srcInterface, IpAddress srcIP, MacAddress srcMac, BigInteger metadata,
IpAddress dstIP) {
+ if (!VpnUtil.isArpLearningEnabled()) {
+ LOG.trace("Not handling packet as ARP Based Learning is disabled");
+ return;
+ }
if (metadata == null || Objects.equals(metadata, BigInteger.ZERO)) {
return;
}
String srcIpToQuery = srcIP.stringValue();
String destIpToQuery = dstIP.stringValue();
for (String vpnName : vpnList.get()) {
- LOG.info("Received ARP/NA for sender MAC {} and sender IP {} via interface {}",
- srcMac.getValue(), srcIpToQuery, srcInterface);
- VpnPortipToPort vpnPortipToPort =
- vpnUtil.getNeutronPortFromVpnPortFixedIp(vpnName, srcIpToQuery);
- // Check if this IP belongs to external network
- if (vpnPortipToPort == null) {
- String extSubnetId = vpnUtil.getAssociatedExternalSubnet(srcIpToQuery);
- if (extSubnetId != null) {
- vpnPortipToPort =
- vpnUtil.getNeutronPortFromVpnPortFixedIp(extSubnetId, srcIpToQuery);
- }
- }
- if (vpnPortipToPort != null) {
- /* This is a well known neutron port and so should be ignored
- * from being discovered...unless it is an Octavia VIP
- */
- String portName = vpnPortipToPort.getPortName();
- Port neutronPort = neutronVpnManager.getNeutronPort(portName);
-
- if (neutronPort == null) {
- LOG.warn("{} should have been a neutron port but could not retrieve it. Aborting processing",
- portName);
- continue;
+ LOG.info("Received ARP/NA for sender MAC {} and sender IP {} via interface {}", srcMac.getValue(),
+ srcIpToQuery, srcInterface);
+ synchronized ((vpnName + srcIpToQuery).intern()) {
+ VpnPortipToPort vpnPortipToPort = vpnUtil.getNeutronPortFromVpnPortFixedIp(vpnName, srcIpToQuery);
+ // Check if this IP belongs to external network
+ if (vpnPortipToPort == null) {
+ String extSubnetId = vpnUtil.getAssociatedExternalSubnet(srcIpToQuery);
+ if (extSubnetId != null) {
+ vpnPortipToPort =
+ vpnUtil.getNeutronPortFromVpnPortFixedIp(extSubnetId, srcIpToQuery);
+ }
}
+ if (vpnPortipToPort != null && !vpnPortipToPort.isLearntIp()) {
+ /*
+ * This is a well known neutron port and so should be ignored from being
+ * discovered...unless it is an Octavia VIP
+ */
+ String portName = vpnPortipToPort.getPortName();
+ Port neutronPort = neutronVpnManager.getNeutronPort(portName);
+
+ if (neutronPort == null) {
+ LOG.warn("{} should have been a neutron port but could not retrieve it. Aborting processing",
+ portName);
+ continue;
+ }
- if (!"Octavia".equals(neutronPort.getDeviceOwner())) {
- LOG.debug("Neutron port {} is not an Octavia port, ignoring", portName);
- continue;
+ if (!"Octavia".equals(neutronPort.getDeviceOwner())) {
+ LOG.debug("Neutron port {} is not an Octavia port, ignoring", portName);
+ continue;
+ }
}
- }
-
- LearntVpnVipToPort learntVpnVipToPort = vpnUtil.getLearntVpnVipToPort(vpnName, srcIpToQuery);
- if (learntVpnVipToPort != null) {
- String oldPortName = learntVpnVipToPort.getPortName();
- String oldMac = learntVpnVipToPort.getMacAddress();
- if (!oldMac.equalsIgnoreCase(srcMac.getValue())) {
- //MAC has changed for requested IP
- LOG.info("ARP/NA Source IP/MAC data modified for IP {} with MAC {} and Port {}",
- srcIpToQuery, srcMac, srcInterface);
- synchronized ((vpnName + srcIpToQuery).intern()) {
- vpnUtil.createLearntVpnVipToPortEvent(vpnName, srcIpToQuery, destIpToQuery,
- oldPortName, oldMac, LearntVpnVipToPortEventAction.Delete, null);
+ // For IPs learnt before cluster-reboot/upgrade, GARP/ArpResponse is received
+ // within 300sec
+ // after reboot, it would be ignored.
+ if (vpnPortipToPort != null && vpnPortipToPort.isLearntIp()) {
+ if (System.currentTimeMillis() < this.bootupTime + config.getBootDelayArpLearning() * 1000) {
+ LOG.trace("GARP/Arp Response not handled for IP {} vpnName {} for time {}s",
+ vpnPortipToPort.getPortFixedip(), vpnName, config.getBootDelayArpLearning());
+ continue;
+ }
+ }
+ LearntVpnVipToPort learntVpnVipToPort = vpnUtil.getLearntVpnVipToPort(vpnName, srcIpToQuery);
+ if (learntVpnVipToPort != null) {
+ String oldPortName = learntVpnVipToPort.getPortName();
+ String oldMac = learntVpnVipToPort.getMacAddress();
+ if (!oldMac.equalsIgnoreCase(srcMac.getValue())) {
+ // MAC has changed for requested IP
+ LOG.info("ARP/NA Source IP/MAC data modified for IP {} with MAC {} and Port {}", srcIpToQuery,
+ srcMac, srcInterface);
+ vpnUtil.createLearntVpnVipToPortEvent(vpnName, srcIpToQuery, destIpToQuery, oldPortName, oldMac,
+ LearntVpnVipToPortEventAction.Delete, null);
putVpnIpToMigrateIpCache(vpnName, srcIpToQuery, srcMac);
}
+ } else if (!isIpInMigrateCache(vpnName, srcIpToQuery)) {
+ if (vpnPortipToPort != null && !vpnPortipToPort.getPortName().equals(srcInterface)) {
+ LOG.trace(
+ "LearntIp: {} vpnName {} is already present in VpnPortIpToPort with " + "PortName {} ",
+ srcIpToQuery, vpnName, vpnPortipToPort.getPortName());
+ vpnUtil.createLearntVpnVipToPortEvent(vpnName, srcIpToQuery, destIpToQuery,
+ vpnPortipToPort.getPortName(), vpnPortipToPort.getMacAddress(),
+ LearntVpnVipToPortEventAction.Delete, null);
+ continue;
+ }
+ learnMacFromIncomingPacket(vpnName, srcInterface, srcIP, srcMac, dstIP);
}
- } else if (!isIpInMigrateCache(vpnName, srcIpToQuery)) {
- learnMacFromIncomingPacket(vpnName, srcInterface, srcIP, srcMac, dstIP);
}
}
}
return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
Datastore.OPERATIONAL, operTx -> {
addMipAdjacency(vpnName, interfaceName, srcIpAddress, macAddress, destIpAddress);
+ vpnUtil.createVpnPortFixedIpToPort(vpnName, srcIpAddress,
+ interfaceName, Boolean.TRUE, macAddress, null);
vpnUtil.createLearntVpnVipToPort(vpnName, srcIpAddress, interfaceName, macAddress, operTx);
}));
}
type uint32;
default 2000;
}
+ leaf boot-delay-arp-learning {
+ description "Boot delay (in seconds) to be enforced for arp learning";
+ type uint32;
+ default 300;
+ }
leaf subnet-route-punt-timeout {
description "hard timeout value for learnt flows for subnet route punts (unit - seconds).
To turn off the rate limiting and installation of learnt flows, it should be set to 0";