IPv6 loopback ip is not displaying in fib entry 04/92004/4
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Mon, 10 Aug 2020 09:49:13 +0000 (15:19 +0530)
committerKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Tue, 15 Sep 2020 03:22:33 +0000 (03:22 +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 dc16b71c498f594909b2f51533362ad6b4f51bdc..397e8c644e223c7b2b927be511a79e6237191891 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 5027a91e98e9774f51731fe1041bad60da46ddfd..600a48b36781a14c4db8d2602c67a347d940565b 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();
+    }
 }