NETVIRT-1171:IPv4 entries appearing in FIB though not associated to Router 63/70363/11
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 5 Apr 2018 06:57:57 +0000 (12:27 +0530)
committerSam Hague <shague@redhat.com>
Tue, 1 May 2018 19:04:24 +0000 (19:04 +0000)
Problem Description:
====================
IPv4 entries are appearing in FIB when subnet is not associated to router
in a dualstack network

Solution Description:
=====================
Dual Stack VM has both IPv4 and IPv6 Address, IPv6 or IPv4 subnet only
associated to router means it should show only IPv6 or IPv4 address based
on the subnet address family. To do this behaviour we need to create the
VPN-Interface adjacency based on the subnet associated to router. Have
done the code changes accordingly in VPN-Interface adjacency.

Change-Id: Id1a4712dc1b8be0713fe7dcb526555c5e5021e39
Signed-off-by: Karthikeyan Krishnan <karthikeyangceb007@gmail.com>
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceOpListener.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java

index 0a9557b3d84ba8cfb4f3b1a7129a4afc5a3a21ba..d4a2887069aaf049dd3a0e2240bf866c01c1c43f 100644 (file)
@@ -774,19 +774,20 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             if (sn != null && !FibHelper.doesPrefixBelongToSubnet(ipPrefix, sn.getSubnetIp(), false)) {
                 continue;
             }
-            Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
-                    .setMacAddress(port.getMacAddress().getValue()).setAdjacencyType(AdjacencyType.PrimaryAdjacency)
-                    .setSubnetId(ip.getSubnetId()).build();
-            if (!adjList.contains(vmAdj)) {
-                adjList.add(vmAdj);
-            }
             Subnetmap snTemp = sn != null ? sn : neutronvpnUtils.getSubnetmap(ip.getSubnetId());
-            Uuid routerId = snTemp != null ? snTemp.getRouterId() : null;
             Uuid vpnId = snTemp != null ? snTemp.getVpnId() : null;
             if (vpnId != null) {
                 neutronvpnUtils.createVpnPortFixedIpToPort(vpnId.getValue(), ipValue,
-                    infName, port.getMacAddress().getValue(), isRouterInterface, wrtConfigTxn);
+                        infName, port.getMacAddress().getValue(), isRouterInterface, wrtConfigTxn);
+                //Create Neutron port adjacency if VPN presence is existing for subnet
+                Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
+                        .setMacAddress(port.getMacAddress().getValue()).setAdjacencyType(AdjacencyType.PrimaryAdjacency)
+                        .setSubnetId(ip.getSubnetId()).build();
+                if (!adjList.contains(vmAdj)) {
+                    adjList.add(vmAdj);
+                }
             }
+            Uuid routerId = snTemp != null ? snTemp.getRouterId() : null;
             if (snTemp != null && snTemp.getInternetVpnId() != null) {
                 neutronvpnUtils.createVpnPortFixedIpToPort(sn.getInternetVpnId().getValue(),
                     ipValue, infName, port.getMacAddress().getValue(), isRouterInterface, wrtConfigTxn);
index 008819fa5c5ed561e386b1f7ce3da2b20200ef63..13269a1f0491f0e66845b2dedf9ab4850197e54f 100755 (executable)
@@ -1514,8 +1514,29 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                         }
                         for (Adjacency adj : copyOldAdjs) {
                             if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(dataBroker, adj)) {
-                                delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
-                                       writeOperTxn, writeConfigTxn);
+                                if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency
+                                        && !adj.isPhysNetworkFunc()) {
+                                    delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+                                            writeOperTxn, writeConfigTxn);
+                                    Optional<VpnInterfaceOpDataEntry> optVpnInterface = VpnUtil.read(dataBroker,
+                                            LogicalDatastoreType.OPERATIONAL, vpnInterfaceOpIdentifier);
+                                    VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry = optVpnInterface.get();
+                                    long vpnId = VpnUtil.getVpnId(dataBroker, newVpnName);
+                                    VpnUtil.removePrefixToInterfaceAdj(dataBroker, adj, vpnId, vpnInterfaceOpDataEntry,
+                                            writeOperTxn);
+                                    //remove FIB entry
+                                    String vpnRd = VpnUtil.getVpnRd(dataBroker, newVpnName);
+                                    LOG.debug("update: remove prefix {} from the FIB and BGP entry "
+                                            + "for the Vpn-Rd {} ", adj.getIpAddress(), vpnRd);
+                                    //remove BGP entry
+                                    fibManager.removeFibEntry(vpnRd, adj.getIpAddress(), writeConfigTxn);
+                                    if (vpnRd != null && !vpnRd.equalsIgnoreCase(newVpnName)) {
+                                        bgpManager.withdrawPrefix(vpnRd, adj.getIpAddress());
+                                    }
+                                } else {
+                                    delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+                                            writeOperTxn, writeConfigTxn);
+                                }
                             }
                             LOG.info("update: Adjacency {} with nextHop {} label {} subnet {} removed from"
                                 + " vpn interface {} on vpn {}", adj.getIpAddress(), adj.getNextHopIpList(),
@@ -1660,7 +1681,20 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
             L3vpnInput input = new L3vpnInput().setNextHop(adj).setVpnName(vpnName)
                     .setInterfaceName(currVpnIntf.getName()).setPrimaryRd(primaryRd).setRd(primaryRd);
             Adjacency operationalAdjacency = null;
-            if (adj.getNextHopIpList() != null && !adj.getNextHopIpList().isEmpty()) {
+            //Handling dual stack neutron port primary adjacency
+            if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency && !adj.isPhysNetworkFunc()) {
+                LOG.trace("addNewAdjToVpnInterface: Adding prefix {} to existing interface {} for vpn {}", prefix,
+                        currVpnIntf.getName(), vpnName);
+                Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(dataBroker,
+                        currVpnIntf.getName());
+                if (interfaceState != null) {
+                    processVpnInterfaceAdjacencies(dpnId, currVpnIntf.getLportTag().intValue(), vpnName, primaryRd,
+                            currVpnIntf.getName(),
+                            vpnId, writeConfigTxn, writeOperTxn, null, interfaceState);
+                }
+            }
+            if (adj.getNextHopIpList() != null && !adj.getNextHopIpList().isEmpty()
+                    && adj.getAdjacencyType() != AdjacencyType.PrimaryAdjacency) {
                 RouteOrigin origin = adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency ? RouteOrigin.LOCAL
                         : RouteOrigin.STATIC;
                 String nh = adj.getNextHopIpList().get(0);
index 43913e862bfa5e0b665bdbf3bfe8381679494e88..97bf738efdc82bdac3a55ac58c7ecb908244b30a 100644 (file)
@@ -166,7 +166,7 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
                  *
                  */
                 for (Prefixes pref : prefixToInterface) {
-                    if (isMatchedPrefixToInterface(pref, del)) {
+                    if (VpnUtil.isMatchedPrefixToInterface(pref, del)) {
                         if (writeOperTxn != null) {
                             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
                                     VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
@@ -193,18 +193,6 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
         notifyTaskIfRequired(interfaceName);
     }
 
-    private boolean isMatchedPrefixToInterface(Prefixes prefix, VpnInterfaceOpDataEntry vpnInterface) {
-        if (prefix != null && vpnInterface != null) {
-            if (prefix.getDpnId() != null && vpnInterface.getDpnId() != null) {
-                if (prefix.getVpnInterfaceName() != null && vpnInterface.getName() != null) {
-                    return prefix.getDpnId().equals(vpnInterface.getDpnId())
-                            && prefix.getVpnInterfaceName().equalsIgnoreCase(vpnInterface.getName());
-                }
-            }
-        }
-        return false;
-    }
-
     private void notifyTaskIfRequired(String intfName) {
         Runnable notifyTask = vpnInterfaceManager.isNotifyTaskQueued(intfName);
         if (notifyTask == null) {
index 45aeb85c8f0e01e3d35813a31eb9324a8321de17..31e85de7a5576a98b446c58ea1809e2e8b8457a1 100755 (executable)
@@ -2249,4 +2249,54 @@ public final class VpnUtil {
                 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
                 .build();
     }
+
+    public static boolean isMatchedPrefixToInterface(Prefixes prefix, VpnInterfaceOpDataEntry vpnInterface) {
+        if (prefix != null && vpnInterface != null) {
+            if (prefix.getDpnId() != null && vpnInterface.getDpnId() != null) {
+                if (prefix.getVpnInterfaceName() != null && vpnInterface.getName() != null) {
+                    return prefix.getDpnId().equals(vpnInterface.getDpnId())
+                            && prefix.getVpnInterfaceName().equalsIgnoreCase(vpnInterface.getName());
+                }
+            }
+        }
+        return false;
+    }
+
+    public static void removePrefixToInterfaceAdj(DataBroker dataBroker, Adjacency adj, long vpnId,
+                                                  VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry,
+                                                  WriteTransaction writeOperTxn) {
+        Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                VpnUtil.getPrefixToInterfaceIdentifier(vpnId,
+                        VpnUtil.getIpPrefix(adj.getIpAddress())));
+        List<Prefixes> prefixToInterface = new ArrayList<>();
+        List<Prefixes> prefixToInterfaceLocal = new ArrayList<>();
+        if (prefix.isPresent()) {
+            prefixToInterfaceLocal.add(prefix.get());
+        }
+        if (prefixToInterfaceLocal.isEmpty()) {
+            for (String nh : adj.getNextHopIpList()) {
+                prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                        VpnUtil.getPrefixToInterfaceIdentifier(vpnId,
+                                VpnUtil.getIpPrefix(nh)));
+                if (prefix.isPresent()) {
+                    prefixToInterfaceLocal.add(prefix.get());
+                }
+            }
+        }
+        if (!prefixToInterfaceLocal.isEmpty()) {
+            prefixToInterface.addAll(prefixToInterfaceLocal);
+        }
+        for (Prefixes pref : prefixToInterface) {
+            if (VpnUtil.isMatchedPrefixToInterface(pref, vpnInterfaceOpDataEntry)) {
+                if (writeOperTxn != null) {
+                    writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
+                            VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()));
+                } else {
+                    VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                            VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()),
+                            VpnUtil.DEFAULT_CALLBACK);
+                }
+            }
+        }
+    }
 }