IPv4 entries appear in FIB though not asso to Rout 26/75226/5
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 16 Aug 2018 12:31:01 +0000 (18:01 +0530)
committerSam Hague <shague@redhat.com>
Fri, 7 Sep 2018 22:45:43 +0000 (22:45 +0000)
Issue:
=======
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.

Currently once ARP response message from the
dual-stack VM interface received to ArpNotificationHandler
it is checking in the VPN DS "vpn-portip-to-port" for
IPv4 address and it won't find any entries for IPv4 subnet
Since IPv4 subnet is not part of router.As a result it will
return empty result and this will be considering as a learning
of that interface port. Which is causing this problem.

As part of this fix have properly added the check
for whether IPv4 subnet is part of vpn or not.

Issue: NETVIRT-1171

Change-Id: I0e67343557ecc887f8c4d5397890c1ceaf069ad0
Signed-off-by: Karthikeyan Krishnan <karthikeyangceb007@gmail.com>
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/iplearn/AbstractIpLearnNotificationHandler.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/iplearn/ipv4/ArpNotificationHandler.java

index ddbc4bc22eda598934f3334be5054812095f043e..6591b2742444b740d71a6bd2acca9c500eb5c1fb 100644 (file)
@@ -1689,7 +1689,7 @@ public final class VpnUtil {
      * @param subnetUuid the subnet's Uuid
      * @return the Subnetmap of Uuid or null if it is not found
      */
-    Subnetmap getSubnetmapFromItsUuid(Uuid subnetUuid) {
+    public Subnetmap getSubnetmapFromItsUuid(Uuid subnetUuid) {
         Subnetmap sn = null;
         InstanceIdentifier<Subnetmap> id = buildSubnetmapIdentifier(subnetUuid);
         Optional<Subnetmap> optionalSn = read(LogicalDatastoreType.CONFIGURATION, id);
index 33d13e1169f5cdce26f0e3ca786d12983fac4f30..ab1b8d6bfd3f655bb85294e20070c2586f7dbd4b 100644 (file)
@@ -20,16 +20,19 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.NWUtil;
+import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
 import org.opendaylight.netvirt.vpnmanager.VpnUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortEventAction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.config.rev161130.VpnConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -65,22 +68,29 @@ public abstract class AbstractIpLearnNotificationHandler {
     protected void validateAndProcessIpLearning(String srcInterface, IpAddress srcIP, MacAddress srcMac,
             IpAddress targetIP, BigInteger metadata) {
         List<Adjacency> adjacencies = vpnUtil.getAdjacenciesForVpnInterfaceFromConfig(srcInterface);
+        IpVersionChoice srcIpVersion = vpnUtil.getIpVersionFromString(srcIP.stringValue());
+        Uuid srcIpSubnetId = null;
         if (adjacencies != null) {
             for (Adjacency adj : adjacencies) {
                 IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(adj.getIpAddress());
+                // If extra/static route is configured, we should ignore for learning process
                 if (NWUtil.isIpAddressInRange(srcIP, ipPrefix)) {
                     return;
                 }
+                IpVersionChoice currentAdjIpVersion = vpnUtil.getIpVersionFromString(adj.getIpAddress());
+                if (srcIpVersion.isIpVersionChosen(currentAdjIpVersion)) {
+                    srcIpSubnetId = adj.getSubnetId();
+                }
             }
         }
 
         LOG.trace("ARP/NA Notification Response Received from interface {} and IP {} having MAC {}, learning MAC",
                 srcInterface, srcIP.stringValue(), srcMac.getValue());
-        processIpLearning(srcInterface, srcIP, srcMac, metadata, targetIP);
+        processIpLearning(srcInterface, srcIP, srcMac, metadata, targetIP, srcIpSubnetId);
     }
 
     protected void processIpLearning(String srcInterface, IpAddress srcIP, MacAddress srcMac, BigInteger metadata,
-            IpAddress dstIP) {
+            IpAddress dstIP, Uuid srcIpSubnetId) {
         if (metadata != null && !Objects.equals(metadata, BigInteger.ZERO)) {
             Optional<List<String>> vpnList = vpnUtil.getVpnHandlingIpv4AssociatedWithInterface(srcInterface);
             if (vpnList.isPresent()) {
@@ -97,6 +107,16 @@ public abstract class AbstractIpLearnNotificationHandler {
                          */
                         continue;
                     }
+                    if (srcIpSubnetId != null) {
+                        Subnetmap snMap = vpnUtil.getSubnetmapFromItsUuid(srcIpSubnetId);
+                        if (snMap != null && snMap.getVpnId() == null) {
+                            /* If the subnet is not part of vpn then it should be ignored
+                             * from being discovered. This use case will come for dual stack
+                             * network. i.e V6 or V4 subnet only part of VPN.
+                             */
+                            continue;
+                        }
+                    }
                     LearntVpnVipToPort learntVpnVipToPort = vpnUtil.getLearntVpnVipToPort(vpnName, srcIpToQuery);
                     if (learntVpnVipToPort != null) {
                         String oldPortName = learntVpnVipToPort.getPortName();
index c36fad20be59da85a893409fc3bed15d24f6f8a7..610b116926b047c4505b039aad0e22dad94da99f 100644 (file)
@@ -61,7 +61,7 @@ public class ArpNotificationHandler extends AbstractIpLearnNotificationHandler i
                         + "target destination {}, learning MAC",
                 srcInterface, srcIP.stringValue(), srcMac.getValue(), targetIP.stringValue());
 
-        processIpLearning(srcInterface, srcIP, srcMac, metadata, targetIP);
+        processIpLearning(srcInterface, srcIP, srcMac, metadata, targetIP, null);
     }
 
     @Override