From: Surendar Raju Date: Fri, 12 Jul 2019 07:12:32 +0000 (+0530) Subject: ARP Responder stale flow after undeployment X-Git-Tag: release/magnesium~15 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=346bce87ca9f1283839c45c48a3fe9f7099fa0ae;p=netvirt.git ARP Responder stale flow after undeployment Issue: ====== At scale, its possible that after all ports are deleted , even if subnet is deleted later , during VpnInterface remove processing , backpull of Neutron DS like subnets is bound to fail. Due to this , ArpResponder flow deletion might fail. Fix: === Subnet-Gateway-IP which is read from Neutron Subnet DS, will be stored in VpnInterface oper DS, thus avoiding backpull. Change-Id: I703091e6cde2f7b8b31488178d72eee703aa712d Signed-off-by: Surendar Raju --- diff --git a/vpnmanager/api/src/main/yang/odl-l3vpn.yang b/vpnmanager/api/src/main/yang/odl-l3vpn.yang index 2d49cffa57..7cfe015185 100644 --- a/vpnmanager/api/src/main/yang/odl-l3vpn.yang +++ b/vpnmanager/api/src/main/yang/odl-l3vpn.yang @@ -223,6 +223,9 @@ module odl-l3vpn { leaf gateway-mac-address { type string; } + leaf gateway-ip-address { + type string; + } leaf lport-tag { type uint32; } diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java index 72601a369c..38ebd0326f 100644 --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java @@ -152,10 +152,17 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> { - VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd) - .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete); - InstanceIdentifier id = - VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd); + VpnInstanceOpDataEntryBuilder builder = null; + InstanceIdentifier id = null; + if (primaryRd != null) { + builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd) + .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete); + id = VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd); + } else { + builder = new VpnInstanceOpDataEntryBuilder().setVrfId(vpnName) + .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete); + id = VpnUtil.getVpnInstanceOpDataIdentifier(vpnName); + } tx.merge(id, builder.build()); LOG.info("{} call: Operational status set to PENDING_DELETE for vpn {} with rd {}", diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java index 52eefcc04d..ac63cae8f6 100755 --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java @@ -758,12 +758,13 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase gatewayIpOptional = vpnUtil.getVpnSubnetGatewayIp(subnetId); if (gatewayIpOptional.isPresent()) { @@ -906,7 +907,7 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase writeOperTxn) { VpnInterfaceOpDataEntry opInterface = - VpnUtil.getVpnInterfaceOpDataEntry(interfaceName, vpnName, aug, dpnId, lportTag, gwMac); + VpnUtil.getVpnInterfaceOpDataEntry(interfaceName, vpnName, aug, dpnId, lportTag, gwMac, gwIp); InstanceIdentifier interfaceId = VpnUtil .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName); writeOperTxn.put(interfaceId, opInterface, CREATE_MISSING_PARENTS); @@ -1385,16 +1386,22 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase identifier = VpnUtil .getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName); - InstanceIdentifier path = identifier.augmentation(AdjacenciesOp.class); - Optional adjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker, - LogicalDatastoreType.OPERATIONAL, path); - boolean isLearntIP = false; + Optional vpnInterfaceOpDataEnteryOptional = + SingleTransactionDataBroker.syncReadOptional(dataBroker, + LogicalDatastoreType.OPERATIONAL, identifier); + boolean isLearntIP = Boolean.FALSE; String primaryRd = vpnUtil.getVpnRd(vpnName); LOG.info("removeAdjacenciesFromVpn: For interface {} on dpn {} RD recovered for vpn {} as rd {}", interfaceName, dpnId, vpnName, primaryRd); - if (adjacencies.isPresent() && adjacencies.get().getAdjacency() != null - && !adjacencies.get().getAdjacency().isEmpty()) { - List nextHops = adjacencies.get().getAdjacency(); + if (!vpnInterfaceOpDataEnteryOptional.isPresent()) { + LOG.error("removeAdjacenciesFromVpn: VpnInterfaceOpDataEntry-Oper DS is absent for Interface {} " + + "on vpn {} dpn {}", interfaceName, vpnName, dpnId); + return; + } + AdjacenciesOp adjacencies = vpnInterfaceOpDataEnteryOptional.get().augmentation(AdjacenciesOp.class); + + if (adjacencies != null && !adjacencies.getAdjacency().isEmpty()) { + List nextHops = adjacencies.getAdjacency(); LOG.info("removeAdjacenciesFromVpn: NextHops for interface {} on dpn {} for vpn {} are {}", interfaceName, dpnId, vpnName, nextHops); for (Adjacency nextHop : nextHops) { @@ -1414,6 +1421,7 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase writeInvTxn) throws ExecutionException, InterruptedException { final Uuid subnetId = nextHop.getSubnetId(); @@ -1541,7 +1549,7 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase getVpnInterfaceOpDataEntry(String vpnInterfaceName, String vpnName) { diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/arp/responder/ArpResponderHandler.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/arp/responder/ArpResponderHandler.java index a98d999dd7..81ecb31f03 100644 --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/arp/responder/ArpResponderHandler.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/arp/responder/ArpResponderHandler.java @@ -137,6 +137,8 @@ public class ArpResponderHandler { ArpReponderInputBuilder builder = new ArpReponderInputBuilder(); builder.setDpId(dpId.toJava()).setInterfaceName(ifName).setSpa(gatewayIp).setLportTag(lportTag); elanService.removeArpResponderFlow(builder.buildForRemoveFlow()); + } else { + LOG.error("Subnet-Gateway-IP is null for interface {}, arpResponderFlow not removed", ifName); } }