IPv6 loopback ip is not displaying in fib entry 73/91973/2
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Mon, 10 Aug 2020 09:49:13 +0000 (15:19 +0530)
committerKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Fri, 18 Sep 2020 04:17:05 +0000 (04:17 +0000)
Issue:
======
IPv6 address family type is not added to BGP VRF table
if external network is already been set with router-gw
before external network to Internet BGPVPN instance.

Solution:
=========
Added one more extra check when external network to
Internet BGPVPN association event call to check whether
external network is already been set with router-gw and
if that router has V6 subnet then set IPv6 address family
in the Internet BGPVPN instance. This logic will trigger
the subsequent event to update the BGP VRF table.

Signed-off-by: Karthikeyan Krishnan <karthikeyangceb007@gmail.com>
Change-Id: Ib382ac062c65ac3c974f72c125c8eb37c6f64f9d

neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java

index a105aa44c62ce7aae62c633e1aefbb93eb0b19fd..b3e6e098fd3fadbcd2802900bb3ea79bc53b7739 100644 (file)
@@ -2447,6 +2447,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             }
             Set<VpnTarget> routeTargets = vpnManager.getRtListForVpn(vpnId.getValue());
             boolean isIpFamilyUpdated = false;
+            IpVersionChoice ipVersion = IpVersionChoice.UNDEFINED;
             for (Uuid nw : networkList) {
                 Network network = neutronvpnUtils.getNeutronNetwork(nw);
                 if (network == null) {
@@ -2476,9 +2477,21 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                  */
                 if (neutronvpnUtils.getIsExternal(network)) {
                     extNwMap.put(nw, network);
-                }
-                if (NeutronvpnUtils.getIsExternal(network)) {
                     isExternalNetwork = true;
+                    //Check whether router-gw is set with external network before external network to BGPVPN association
+                    List<Uuid> routerList = neutronvpnUtils.getRouterIdsForExtNetwork(nw);
+                    if (!routerList.isEmpty()) {
+                        for (Uuid routerId : routerList) {
+                            //If v6 subnet was already added to router means it requires IPv6 AddrFamily in VpnInstance
+                            if (neutronvpnUtils.isV6SubnetPartOfRouter(routerId)) {
+                                ipVersion = ipVersion.addVersion(IpVersionChoice.IPV6);
+                                LOG.debug("associateNetworksToVpn: External network {} is already associated with "
+                                        + "router(router-gw) {} and V6 subnet is part of that router. Hence Set IPv6 "
+                                        + "address family type in Internet VPN Instance {}", network, routerId, vpnId);
+                                break;
+                            }
+                        }
+                    }
                 }
                 List<Subnetmap> subnetmapList = neutronvpnUtils.getSubnetmapListFromNetworkId(nw);
                 if (subnetmapList == null || subnetmapList.isEmpty()) {
@@ -2488,7 +2501,6 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 if (vpnManager.checkForOverlappingSubnets(nw, subnetmapList, vpnId, routeTargets, failedNwList)) {
                     continue;
                 }
-                IpVersionChoice ipVersion = IpVersionChoice.UNDEFINED;
                 for (Subnetmap subnetmap : subnetmapList) {
                     IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(subnetmap.getSubnetIp());
                     if (!ipVersion.isIpVersionChosen(ipVers)) {
@@ -2602,6 +2614,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         List<String> failedNwList = new ArrayList<>();
         HashSet<Uuid> passedNwList = new HashSet<>();
         ConcurrentMap<Uuid, Network> extNwMap = new ConcurrentHashMap<>();
+        IpVersionChoice ipVersion = IpVersionChoice.UNDEFINED;
         if (networkList.isEmpty()) {
             LOG.error("dissociateNetworksFromVpn: Failed as networks list is empty");
             failedNwList.add(String.format("Failed to disassociate networks from VPN %s as networks list is empty",
@@ -2641,8 +2654,21 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
              */
             if (neutronvpnUtils.getIsExternal(network)) {
                 extNwMap.put(nw, network);
+                //Handle external-Nw to BGPVPN Disassociation and still ext-router is being set with external-Nw
+                List<Uuid> routerList = neutronvpnUtils.getRouterIdsForExtNetwork(nw);
+                if (!routerList.isEmpty()) {
+                    for (Uuid routerId : routerList) {
+                        //If v6 subnet was already added to router means it requires IPv6 AddrFamily in VpnInstance
+                        if (neutronvpnUtils.isV6SubnetPartOfRouter(routerId)) {
+                            ipVersion = ipVersion.addVersion(IpVersionChoice.IPV6);
+                            LOG.debug("dissociateNetworksFromVpn: External network {} is still associated with "
+                                    + "router(router-gw) {} and V6 subnet is part of that router. Hence Set IPv6 "
+                                    + "address family type in Internet VPN Instance {}", network, routerId, vpnId);
+                            break;
+                        }
+                    }
+                }
             }
-            IpVersionChoice ipVersion = IpVersionChoice.UNDEFINED;
             for (Uuid subnet : networkSubnets) {
                 Subnetmap subnetmap = neutronvpnUtils.getSubnetmap(subnet);
                 if (subnetmap == null) {
index 9b7411e1fed0716a38471c6a223c3405523fe861..4332243ac5087bdffae5a8f454440f424870ff03 100644 (file)
@@ -95,6 +95,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neu
 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.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
@@ -1812,5 +1813,27 @@ public class NeutronvpnUtils {
             settableFuture.setException(throwable);
         }
     }
+
+    public List<Uuid> getRouterIdsForExtNetwork(Uuid extNetwork) {
+        InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
+        Optional<ExternalNetworks> externalNwData;
+        try {
+            externalNwData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.warn("getRouterIdsForExtNetwork: Exception while reading External-Network DS for the network {}",
+                    extNetwork.getValue(), e);
+            return Collections.emptyList();
+        }
+        if (externalNwData.isPresent()) {
+            for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
+                    .networks.Networks externalNw : externalNwData.get().getNetworks().values()) {
+                if (externalNw.getId().equals(extNetwork)) {
+                    return externalNw.getRouterIds();
+                }
+            }
+        }
+        return Collections.emptyList();
+    }
 }