The NFIP to FIP traffic is failing when there are multiple route 19/72019/8
authorAswin Suryanarayanan <asuryana@redhat.com>
Tue, 15 May 2018 15:29:38 +0000 (20:59 +0530)
committerAswin Suryanarayanan <asuryana@redhat.com>
Wed, 30 May 2018 04:55:24 +0000 (10:25 +0530)
The issue occurs when the FIP vm is atached to router1, NFIP is attached
router 2, and there is no port in router2 subnet present in FIP vm
compute node.

NETVIRT-1238 failure in Ping Vm Instance1 Floating IP From SNAT VM
Instance1

Change-Id: Id427f9dba79cc8f3f0ca6e3cbaf03cfd0f19f478
Signed-off-by: Aswin Suryanarayanan <asuryana@redhat.com>
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/AbstractSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ConntrackBasedSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/FlatVlanConntrackBasedSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/SnatServiceImplFactory.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/VxlanGreConntrackBasedSnatService.java

index b63e987ff8da0cf973f06c3c3a84144843cb6808..e5939d1518fe01657f5e51c7bee1e3e76b9d5c77 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.netvirt.natservice.internal;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -35,6 +36,8 @@ import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
 import org.opendaylight.netvirt.natservice.api.SnatServiceListener;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -50,6 +53,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.G
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -71,12 +76,14 @@ public abstract class AbstractSnatService implements SnatServiceListener {
     protected final OdlInterfaceRpcService odlInterfaceRpcService;
     protected final IInterfaceManager interfaceManager;
     protected final IVpnFootprintService vpnFootprintService;
+    protected final IFibManager fibManager;
 
     protected AbstractSnatService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
                                   final ItmRpcService itmManager, final OdlInterfaceRpcService odlInterfaceRpcService,
                                   final IdManagerService idManager, final NAPTSwitchSelector naptSwitchSelector,
                                   final IInterfaceManager interfaceManager,
-                                  final IVpnFootprintService vpnFootprintService) {
+                                  final IVpnFootprintService vpnFootprintService,
+                                  final IFibManager fibManager) {
         this.dataBroker = dataBroker;
         this.mdsalManager = mdsalManager;
         this.itmManager = itmManager;
@@ -85,6 +92,7 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         this.naptSwitchSelector = naptSwitchSelector;
         this.odlInterfaceRpcService = odlInterfaceRpcService;
         this.vpnFootprintService = vpnFootprintService;
+        this.fibManager = fibManager;
     }
 
     protected DataBroker getDataBroker() {
@@ -148,12 +156,14 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         }
         //The logic now handle only one external IP per router, others if present will be ignored.
         String externalIp = externalIps.get(0).getIpAddress();
+        String externalGwMac = routers.getExtGwMacAddress();
         Uuid externalSubnetId = externalIps.get(0).getSubnetId();
         long extSubnetId = NatConstants.INVALID_ID;
         if (addOrRemove == NwConstants.ADD_FLOW) {
             extSubnetId = NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
         }
-        installInboundFibEntry(dpnId, externalIp, routerId, extSubnetId, addOrRemove);
+        installInboundFibEntry(dpnId, externalIp, routerId, extSubnetId, routers.getNetworkId()
+                .getValue(), externalSubnetId.getValue(), externalGwMac, addOrRemove);
         installInboundTerminatingServiceTblEntry(dpnId, routerId, extSubnetId, addOrRemove);
     }
 
@@ -161,22 +171,8 @@ public abstract class AbstractSnatService implements SnatServiceListener {
             BigInteger dpnId, int addOrRemove) {
         String routerName = routers.getRouterName();
         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
-        List<ExternalIps> externalIps = routers.getExternalIps();
-        if (externalIps.isEmpty()) {
-            LOG.error("AbstractSnatService: installSnatCommonEntriesForNaptSwitch no externalIP present"
-                    + " for routerId {}",
-                    routerId);
-            return;
-        }
-        String externalIp = externalIps.get(0).getIpAddress();
-        Uuid externalSubnetId = externalIps.get(0).getSubnetId();
-        long extSubnetId = NatConstants.INVALID_ID;
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            extSubnetId = NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
-        }
-
         installDefaultFibRouteForSNAT(dpnId, routerId, addOrRemove);
-        installSnatMissEntry(dpnId, routerId, routerName, primarySwitchId, externalIp, extSubnetId, addOrRemove);
+        installSnatMissEntry(dpnId, routerId, routerName, primarySwitchId, addOrRemove);
     }
 
     protected abstract void installSnatSpecificEntriesForNaptSwitch(Routers routers, BigInteger dpnId,
@@ -186,7 +182,7 @@ public abstract class AbstractSnatService implements SnatServiceListener {
             int addOrRemove);
 
     protected void installInboundFibEntry(BigInteger dpnId, String externalIp, Long routerId,
-            long extSubnetId, int addOrRemove) {
+            long extSubnetId, String externalNetId, String subNetId, String routerMac, int addOrRemove) {
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         if (addOrRemove == NwConstants.ADD_FLOW) {
@@ -208,10 +204,24 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         flowRef = flowRef + "inbound" + externalIp;
         syncFlow(dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef,
                 NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo, addOrRemove);
+        String rd = NatUtil.getVpnRd(dataBroker, subNetId);
+        String nextHopIp = NatUtil.getEndpointIpAddressForDPN(dataBroker, dpnId);
+        String ipPrefix = externalIp + "/32";
+        if (addOrRemove == NwConstants.ADD_FLOW) {
+            NatUtil.addPrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId),
+                    null, ipPrefix, dpnId, new Uuid(subNetId), Prefixes.PrefixCue.Nat);
+
+            fibManager.addOrUpdateFibEntry(rd, routerMac, ipPrefix,
+                    Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, extSubnetId,
+                    0, null, externalNetId, RouteOrigin.STATIC, null);
+        } else {
+            fibManager.removeFibEntry(rd, ipPrefix, null);
+            NatUtil.deletePrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId), ipPrefix);
+        }
     }
 
     protected void installSnatMissEntry(BigInteger dpnId, Long routerId, String routerName, BigInteger primarySwitchId,
-            String externalIp, long extSubnetId, int addOrRemove) {
+            int addOrRemove) {
         LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
         List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
         String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
@@ -248,28 +258,6 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
         syncFlow(dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
-        //Install the FIB entry for traffic destined to SNAT IP in Non-NAPT switch.
-        matches = new ArrayList<>();
-        actionsInfo = new ArrayList<>();
-        matches.add(new MatchEthernetType(0x0800L));
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            if (extSubnetId == NatConstants.INVALID_ID) {
-                LOG.error("installSnatMissEntry : external subnet id is invalid.");
-                return;
-            }
-            actionsInfo.add(new ActionSetFieldTunnelId(BigInteger.valueOf(extSubnetId)));
-            matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId),
-                    MetaDataUtil.METADATA_MASK_VRFID));
-        }
-        matches.add(new MatchIpv4Destination(externalIp, "32"));
-        LOG.debug("installSnatMissEntry : Setting the tunnel to the list of action infos {}", actionsInfo);
-        actionsInfo.add(new ActionGroup(groupId));
-        instructions = new ArrayList<>();
-        instructions.add(new InstructionApplyActions(actionsInfo));
-        flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, routerId);
-        flowRef = flowRef + "inboundmiss" + externalIp;
-        syncFlow(dpnId, NwConstants.L3_FIB_TABLE, flowRef,  NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
     }
 
     protected void installInboundTerminatingServiceTblEntry(BigInteger dpnId, Long routerId,
@@ -392,4 +380,4 @@ public abstract class AbstractSnatService implements SnatServiceListener {
     static int mostSignificantBit(int value) {
         return 31 - Integer.numberOfLeadingZeros(value);
     }
-}
+}
\ No newline at end of file
index 2ebc9f629fe8a1260a452dc56ae5ec5f70822044..49e1f39c09471578a8785198a46458c21fd90bea 100644 (file)
@@ -34,6 +34,7 @@ import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 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;
@@ -63,9 +64,10 @@ public abstract class ConntrackBasedSnatService extends AbstractSnatService {
     public ConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager, ItmRpcService itmManager,
                                      IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
                                      OdlInterfaceRpcService odlInterfaceRpcService,
-                                     IInterfaceManager interfaceManager, IVpnFootprintService vpnFootprintService) {
+                                     IInterfaceManager interfaceManager, IVpnFootprintService vpnFootprintService,
+                                     IFibManager fibManager) {
         super(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService, idManager, naptSwitchSelector,
-                interfaceManager, vpnFootprintService);
+                interfaceManager, vpnFootprintService, fibManager);
     }
 
     @Override
index e20b5d0c90b2bbf3f1938903290219433214e175..e38d9d106b495ebadd9fbe8a362f25033b226926 100644 (file)
@@ -12,6 +12,7 @@ import java.math.BigInteger;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
@@ -29,9 +30,10 @@ public class FlatVlanConntrackBasedSnatService extends ConntrackBasedSnatService
                                              ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
                                              IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
                                              IInterfaceManager interfaceManager,
-                                             IVpnFootprintService vpnFootprintService) {
+                                             IVpnFootprintService vpnFootprintService,
+                                             IFibManager fibManager) {
         super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector,
-                odlInterfaceRpcService, interfaceManager, vpnFootprintService);
+                odlInterfaceRpcService, interfaceManager, vpnFootprintService, fibManager);
     }
 
     @Override
index bc528356d9ca62f0ae9e544bc4dae38f035de2cb..3c4f16f1813a0a5945b390b095f3d4617f0d04b0 100644 (file)
@@ -679,6 +679,20 @@ public final class NatUtil {
         }
     }
 
+    public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
+        try {
+            SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
+                    InstanceIdentifier.builder(PrefixToInterface.class)
+                    .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
+                            .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
+                            .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
+                    .build());
+        } catch (TransactionCommitFailedException e) {
+            LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
+                    vpnId, e);
+        }
+    }
+
     static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
         InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
             .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
index 73c8b81cb56d61868839f7582ce5f3f55fe2b05e..2ddb1095d9b3cfeae3aaf6a87349f34c6fde3a69 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.infrautils.inject.AbstractLifecycle;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
@@ -41,6 +42,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
     private final IElanService elanManager;
     private final IInterfaceManager interfaceManager;
     private final IVpnFootprintService vpnFootprintService;
+    protected final IFibManager fibManager;
 
     @Inject
     public SnatServiceImplFactory(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
@@ -53,7 +55,8 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
                                   final ExternalRoutersListener externalRouterListener,
                                   final IElanService elanManager,
                                   final IInterfaceManager interfaceManager,
-                                  final IVpnFootprintService vpnFootprintService) {
+                                  final IVpnFootprintService vpnFootprintService,
+                                  final IFibManager fibManager) {
         this.dataBroker = dataBroker;
         this.mdsalManager = mdsalManager;
         this.itmManager = itmManager;
@@ -70,6 +73,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
         this.elanManager = elanManager;
         this.interfaceManager = interfaceManager;
         this.vpnFootprintService = vpnFootprintService;
+        this.fibManager = fibManager;
     }
 
     @Override
@@ -86,7 +90,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
 
         if (natMode == NatMode.Conntrack) {
             return new FlatVlanConntrackBasedSnatService(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService,
-                    idManager, naptSwitchSelector, interfaceManager, vpnFootprintService);
+                    idManager, naptSwitchSelector, interfaceManager, vpnFootprintService, fibManager);
         }
         return null;
     }
@@ -98,7 +102,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
                     NatConstants.ODL_VNI_POOL_NAME);
             return new VxlanGreConntrackBasedSnatService(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService,
                     idManager, naptSwitchSelector, externalRouterListener, elanManager, interfaceManager,
-                    vpnFootprintService);
+                    vpnFootprintService, fibManager);
         }
         return null;
     }
index 15cf6b2d7b72054b33342126a5375e30e222c24e..dbfaa55a6026788bbc989ac28d2b68f8e858d6f5 100644 (file)
@@ -41,6 +41,7 @@ import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 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;
@@ -68,9 +69,10 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
                                              IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
                                              ExternalRoutersListener externalRouterListener, IElanService elanManager,
                                              IInterfaceManager interfaceManager,
-                                             IVpnFootprintService vpnFootprintService) {
+                                             IVpnFootprintService vpnFootprintService,
+                                             IFibManager fibManager) {
         super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
-                interfaceManager, vpnFootprintService);
+                interfaceManager, vpnFootprintService, fibManager);
         this.externalRouterListener = externalRouterListener;
         this.elanManager = elanManager;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);