Handle VPN Instance Update for dual router case 73/76473/11
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 27 Sep 2018 08:53:22 +0000 (14:23 +0530)
committerSam Hague <shague@redhat.com>
Thu, 25 Oct 2018 16:19:36 +0000 (16:19 +0000)
Problem:
========
VPN Instance update is not properly handled for
dual router use case where single vpn interface
is part of two router. This configuration is
existing in the dual stack network where V4
subnet is part of one router and V6 subnet is
part of different router.

Solution:
============
This patch is addressing the following VPN instance update
scenario.

+1st VPN Instance : router VPN or external BGP-VPN-1.
+2nd VPN Instance : router VPN or external BGP-VPN-2.
+3rd VPN Instance : Internet BGP-VPN(router-gw update/delete) for public
network access.

Issue: NETVIRT-1394

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

index f94ea5d9e0de42fda43799afb89c7a46ca8efd3c..4695f30c582a182a71cf4b67e6c11393827ecdc8 100755 (executable)
@@ -1574,6 +1574,8 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
         List<String> oldVpnListCopy = new ArrayList<>();
         oldVpnListCopy.addAll(oldVpnList);
         List<String> newVpnList = vpnUtil.getVpnListForVpnInterface(update);
+        List<String> newVpnListCopy = new ArrayList<>();
+        newVpnListCopy.addAll(newVpnList);
 
         oldVpnList.removeAll(newVpnList);
         newVpnList.removeAll(oldVpnListCopy);
@@ -1601,11 +1603,67 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
              * oldVpnList = 1 and newVpnList = 1 (router VPN to Ext-BGPVPN)
              * oldVpnList = 1 and newVpnList = 1 (Ext-BGPVPN to router VPN)
              *
-             * TODO Two router VPN instance update use case will be addressed in separate patch
+             * Dual Router VPN Instance Update:
+             * ================================
+             * In this case single VPN interface will be part of maximum 3 VPN Instance only.
+             *
+             * 1st VPN Instance : router VPN or external BGP-VPN-1.
+             * 2nd VPN Instance : router VPN or external BGP-VPN-2.
+             * 3rd VPN Instance : Internet BGP-VPN(router-gw update/delete) for public network access.
+             *
+             * Dual Router --> Associated with common external BGP-VPN Instance.
+             * 1st router and 2nd router are getting associated with single External BGP-VPN
+             * 1) add 1st router to external bgpvpn --> oldVpnList=1, newVpnList=1;
+             * 2) add 2nd router to the same external bgpvpn --> oldVpnList=1, newVpnList=0
+             * In this case, we need to call removeVpnInterfaceCall() followed by addVpnInterfaceCall()
+             *
+             *
              */
             isVpnInstanceUpdate = Boolean.TRUE;
-            updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList,
-                    oldVpnListCopy, futures);
+            if (vpnUtil.isDualRouterVpnUpdate(oldVpnListCopy, newVpnListCopy)) {
+                if ((oldVpnListCopy.size() == 2 || oldVpnListCopy.size() == 3)
+                        && (oldVpnList.size() == 1 && newVpnList.size() == 0)) {
+                    //Identify the external BGP-VPN Instance and pass that value as newVpnList
+                    List<String> externalBgpVpnList = new ArrayList<>();
+                    for (String newVpnName : newVpnListCopy) {
+                        String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
+                        VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(primaryRd);
+                        if (vpnInstanceOpDataEntry.getBgpvpnType() == VpnInstanceOpDataEntry
+                                .BgpvpnType.BGPVPNExternal) {
+                            externalBgpVpnList.add(newVpnName);
+                            break;
+                        }
+                    }
+                    //This call will execute removeVpnInterfaceCall() followed by addVpnInterfaceCall()
+                    updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList,
+                            externalBgpVpnList, oldVpnListCopy, futures);
+
+                } else if ((oldVpnListCopy.size() == 2 || oldVpnListCopy.size() == 3)
+                        && (oldVpnList.size() == 0 && newVpnList.size() == 1)) {
+                    //Identify the router VPN Instance and pass that value as oldVpnList
+                    List<String> routerVpnList = new ArrayList<>();
+                    for (String newVpnName : newVpnListCopy) {
+                        String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
+                        VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(primaryRd);
+                        if (vpnInstanceOpDataEntry.getBgpvpnType() == VpnInstanceOpDataEntry
+                                .BgpvpnType.VPN) {
+                            routerVpnList.add(newVpnName);
+                            break;
+                        }
+                    }
+                    //This call will execute removeVpnInterfaceCall() followed by addVpnInterfaceCall()
+                    updateVpnInstanceChange(identifier, interfaceName, original, update, routerVpnList,
+                            newVpnList, oldVpnListCopy, futures);
+
+                } else {
+                    //Handle remaining use cases.
+                    updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList,
+                            oldVpnListCopy, futures);
+                }
+            } else {
+                updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList,
+                        oldVpnListCopy, futures);
+            }
         }
         return isVpnInstanceUpdate;
     }
index c14d526c6dbd674fdc2953f38c87586e81ddfef4..a74ebbd4b79a20523dcc5d62704612ba8d306174 100644 (file)
@@ -2330,4 +2330,12 @@ public final class VpnUtil {
     public static <T> T requireNonNullElse(@Nullable T obj, @Nonnull T defaultObj) {
         return obj != null ? obj : requireNonNull(defaultObj);
     }
+
+    public boolean isDualRouterVpnUpdate(List<String> oldVpnListCopy, List<String> newVpnListCopy) {
+        if ((oldVpnListCopy.size() == 2 && newVpnListCopy.size() == 3)
+                || (oldVpnListCopy.size() == 3 && newVpnListCopy.size() == 2)) {
+            return true;
+        }
+        return false;
+    }
 }