Dual Stack feature support for router interface 90/79090/10
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Mon, 31 Dec 2018 08:19:34 +0000 (13:49 +0530)
committerSam Hague <shague@redhat.com>
Fri, 25 Jan 2019 21:20:09 +0000 (21:20 +0000)
We create a dual-stack neutron port and attach this
port to the router.
This single neutron port is then responsible for
handling both IPv4 and IPv6 subnets in that network.
The advantage of this approach is that it reduces
the number of Neutron router ports.

Issue: NETVIRT-1543

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

index 4822b948452824c8021468a5bf9f287ca88b9582..e8584cd78e247f1a67c0a75cc0308375f789b5f0 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.netvirt.ipv6service;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import com.google.common.net.InetAddresses;
@@ -236,6 +237,17 @@ public class IfMgr implements ElementCache, AutoCloseable {
                               String deviceOwner) {
         LOG.debug("addRouterIntf portId {}, rtrId {}, snetId {}, networkId {}, ip {}, mac {}",
                 portId, rtrId, snetId, networkId, fixedIp, macAddress);
+        /* Added the below logic for supporting neutron router interface creation.
+         * Since when neutron port is created with fixed Ipv6 address, that time it will be
+         * treated as a host port and it will be added into the vintfs map through
+         * NeutronPortChangeListener ADD() event.
+         * Later the same neutron port is added to router this time it will be treated as
+         * a router_interface through NeutronPortChangeListener UPDATE() event.
+         */
+        VirtualPort virInterface = vintfs.get(portId);
+        if (virInterface != null && Strings.isNullOrEmpty(virInterface.getDeviceOwner())) {
+            vintfs.remove(portId);
+        }
         //Save the interface ipv6 address in its fully expanded format
         Ipv6Address addr = new Ipv6Address(InetAddresses
                 .forString(fixedIp.getIpv6Address().getValue()).getHostAddress());
index 5ba8456c387aa6e0f1c7d877a78febc94b477465..33d2a206568ec4bc7981e77bb4e011954bd1fd88 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.netvirt.ipv6service;
 
 import static org.opendaylight.netvirt.ipv6service.utils.Ipv6ServiceUtils.nullToEmpty;
 
+import com.google.common.base.Strings;
+
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -132,6 +134,16 @@ public class NeutronPortChangeListener extends AsyncClusteredDataTreeChangeListe
                 ifMgr.updateHostIntf(update.getUuid(), portIncludesV6Address);
             }
         }
+        //Neutron Port update with proper device owner information
+        if ((Strings.isNullOrEmpty(original.getDeviceOwner()) || Strings.isNullOrEmpty(original.getDeviceId()))
+                && !Strings.isNullOrEmpty(update.getDeviceOwner()) && !Strings.isNullOrEmpty(update.getDeviceId())) {
+            for (FixedIps fixedip : nullToEmpty(update.getFixedIps())) {
+                if (fixedip.getIpAddress().getIpv4Address() != null) {
+                    continue;
+                }
+                addInterfaceInfo(update, fixedip);
+            }
+        }
     }
 
     protected void addInterfaceInfo(Port port, FixedIps fixedip) {
index cb943282bdd575366907e210ea85d4639bba01aa..65713f693d850a86a1870f67d263d1d890365fa8 100644 (file)
@@ -827,10 +827,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         for (FixedIps ip : requireNonNullElse(port.getFixedIps(), Collections.<FixedIps>emptyList())) {
             String ipValue = ip.getIpAddress().stringValue();
             String ipPrefix = ip.getIpAddress().getIpv4Address() != null ? ipValue + "/32" : ipValue + "/128";
-            if (sn != null && !FibHelper.doesPrefixBelongToSubnet(ipPrefix, sn.getSubnetIp(), false)) {
+            Subnetmap snTemp = neutronvpnUtils.getSubnetmap(ip.getSubnetId());
+            if (snTemp != null && !FibHelper.doesPrefixBelongToSubnet(ipPrefix,
+                    snTemp.getSubnetIp(), false)) {
                 continue;
             }
-            Subnetmap snTemp = sn != null ? sn : neutronvpnUtils.getSubnetmap(ip.getSubnetId());
             Uuid vpnId = snTemp != null ? snTemp.getVpnId() : null;
             if (vpnId != null) {
                 neutronvpnUtils.createVpnPortFixedIpToPort(vpnId.getValue(), ipValue,
index b332d6963201ead4bbd691e8a0a43eacf48e0c3f..1070411cb70ca3ef0b1926c5ad33aac07bced107 100755 (executable)
@@ -2121,12 +2121,12 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                 LOG.info("createFibEntryForRouterInterface: Router interface {} for vpn {} rd {} prefix {} label {}"
                         + " macAddress {} processed successfully;", interfaceName, vpnName, primaryRd, prefix, label,
                         macAddress);
-                return;
+            } else {
+                LOG.error("createFibEntryForRouterInterface: VPN Interface {} of router addition failed as primary"
+                                + " adjacency for this vpn interface could not be obtained. rd {} vpnName {}",
+                        interfaceName, primaryRd, vpnName);
             }
         }
-        LOG.error("createFibEntryForRouterInterface: VPN Interface {} of router addition failed as primary"
-                + " adjacency for this vpn interface could not be obtained. rd {} vpnName {}", interfaceName,
-                primaryRd, vpnName);
     }
 
     protected void deleteFibEntryForRouterInterface(VpnInterface vpnInterface,