VNI based L3 forwarding support for BGPVPN 97/70897/24
authorxcheara <chetan.arakere@altencalsoftlabs.com>
Fri, 13 Apr 2018 08:16:07 +0000 (13:46 +0530)
committerSam Hague <shague@redhat.com>
Mon, 23 Jul 2018 01:07:30 +0000 (01:07 +0000)
Description: As part of this spec implementation earlier, VNI based
forwarding for BGPVPN was kept out of scope. This Change addresses to
support VNI based forwarding of packet over VXLAN tunnel covering Router
associated and Network Associated BGPVPN and iRT/eRT use-cases.

Additional changes to preventing backpulling of neutron subnet-map to
retieve network-related attributes in vpn-engine is been addressed.

Handled missing destination mac address in the remote fib flow for
iRT/eRT use-cases.

Issue : NETVIRT-1209

Change-Id: Ib61d0c02129de980348436cdeba7939488c2da6e
Signed-off-by: xcheara <chetan.arakere@altencalsoftlabs.com>
18 files changed:
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/BaseVrfEntryHandler.java
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/EvpnVrfEntryHandler.java
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibUtil.java
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/NexthopManager.java
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/AbstractSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/EvpnDnatFlowProgrammer.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/EvpnSnatFlowProgrammer.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ExternalRoutersListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatEvpnUtil.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatTunnelInterfaceStateListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
vpnmanager/api/src/main/yang/l3vpn.yang
vpnmanager/api/src/main/yang/odl-l3vpn.yang
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnSubnetRouteHandler.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java

index d02272020d1d9e47c74349873d9a52844b67cd48..506d32dccd73c84dbe5745ef0a2bbea75a78843b 100644 (file)
@@ -335,7 +335,19 @@ public class BaseVrfEntryHandler implements AutoCloseable {
             LOG.debug("Failed to get VPN name for vpnId {}", vpnId);
             return;
         }
-        String macAddress = fibUtil.getMacAddressFromPrefix(ifName, vpnName, ipPrefix);
+        String macAddress = null;
+        if (vrfEntry.getParentVpnRd() != null) {
+            // Handling iRT/eRT use-case for missing destination mac address in Remote FIB flow
+            Optional<VpnInstanceOpDataEntry> vpnInstance = fibUtil.getVpnInstanceOpData(vrfEntry.getParentVpnRd());
+            if (vpnInstance.isPresent()) {
+                macAddress = fibUtil.getMacAddressFromPrefix(ifName, vpnInstance.get().getVpnInstanceName(), ipPrefix);
+            } else {
+                LOG.warn("VpnInstance missing for Parent Rd {} value for prefix {}", vrfEntry.getParentVpnRd(),
+                        vrfEntry.getDestPrefix());
+            }
+        } else {
+            macAddress = fibUtil.getMacAddressFromPrefix(ifName, vpnName, ipPrefix);
+        }
         if (macAddress == null) {
             LOG.warn("No MAC address found for VPN interface {} prefix {}", ifName, ipPrefix);
             return;
@@ -383,16 +395,11 @@ public class BaseVrfEntryHandler implements AutoCloseable {
                     tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
                 }
             } else {
-                if (fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(prefixInfo.getSubnetId(), vpnId,
-                        rd)) {
-                    java.util.Optional<Long> optionalVni = fibUtil.getVniForVxlanNetwork(prefixInfo.getSubnetId());
-                    if (!optionalVni.isPresent()) {
-                        LOG.error("VNI not found for nexthop {} vrfEntry {} with subnetId {}", nextHopIp,
-                                vrfEntry, prefixInfo.getSubnetId());
-                        return;
-                    }
-                    tunnelId = BigInteger.valueOf(optionalVni.get());
+                if (FibUtil.isVxlanNetwork(prefixInfo.getNetworkType())) {
+                    tunnelId = BigInteger.valueOf(prefixInfo.getSegmentationId());
                 } else {
+                    LOG.warn("Network is not of type VXLAN for prefix {}."
+                            + "Going with default Lport Tag.", prefixInfo.toString());
                     tunnelId = BigInteger.valueOf(label);
                 }
             }
index 2fcb3da8433e435d08e46459d87ae04f47b11792..667ac5e7dee7ca249bce4c6ebafdae576dd8b482 100644 (file)
@@ -230,8 +230,8 @@ public class EvpnVrfEntryHandler extends BaseVrfEntryHandler implements IVrfEntr
             String interfaceName = prefixInfo.getVpnInterfaceName();
             if (vrfEntry.getOrigin().equals(RouteOrigin.BGP.getValue()) || isNatPrefix) {
                 tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
-            } else if (elanManager.isOpenStackVniSemanticsEnforced()) {
-                tunnelId = BigInteger.valueOf(getFibUtil().getVniForVxlanNetwork(prefixInfo.getSubnetId()).get());
+            } else if (FibUtil.isVxlanNetwork(prefixInfo.getNetworkType())) {
+                tunnelId = BigInteger.valueOf(prefixInfo.getSegmentationId());
             } else {
                 Interface interfaceState = getFibUtil().getInterfaceStateFromOperDS(interfaceName);
                 tunnelId = BigInteger.valueOf(interfaceState.getIfIndex());
index 9b524f62299e8b0fd72b0201f91ee456760afdbc..7fb4da33aaa50b67fdd4aaab2296dc53a1eacfdd 100644 (file)
@@ -43,7 +43,6 @@ import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
-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.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
@@ -110,9 +109,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
@@ -665,12 +662,6 @@ public class FibUtil {
         }
     }
 
-    public Subnetmap getSubnetMap(Uuid subnetId) {
-        InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
-            .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
-        return MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
-    }
-
     public static String getGreLbGroupKey(List<String> availableDcGws) {
         Preconditions.checkNotNull(availableDcGws, "AvailableDcGws is null");
         return "gre-" + availableDcGws.stream().sorted().collect(joining(":"));
@@ -746,35 +737,13 @@ public class FibUtil {
         return MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
     }
 
-    boolean isVxlanNetworkAndInternalRouterVpn(Uuid subnetId, String
-            vpnInstanceName, String rd) {
-        if (rd.equals(vpnInstanceName)) {
-            Subnetmap subnetmap = getSubnetMap(subnetId);
-            if (subnetmap != null) {
-                return subnetmap.getNetworkType() == NetworkAttributes.NetworkType.VXLAN;
-            }
+    static boolean isVxlanNetwork(NetworkType networkType) {
+        if (networkType != null) {
+            return networkType == NetworkAttributes.NetworkType.VXLAN;
         }
         return false;
     }
 
-    java.util.Optional<Long> getVniForVxlanNetwork(Uuid subnetId) {
-        Subnetmap subnetmap = getSubnetMap(subnetId);
-        if (subnetmap != null && subnetmap.getNetworkType() == NetworkAttributes.NetworkType.VXLAN) {
-            return java.util.Optional.of(subnetmap.getSegmentationId());
-        }
-        return java.util.Optional.empty();
-    }
-
-    boolean enforceVxlanDatapathSemanticsforInternalRouterVpn(Uuid subnetId, long vpnId, String rd) {
-        return elanManager.isOpenStackVniSemanticsEnforced()
-                && isVxlanNetworkAndInternalRouterVpn(subnetId, getVpnNameFromId(vpnId), rd);
-    }
-
-    boolean enforceVxlanDatapathSemanticsforInternalRouterVpn(Uuid subnetId, String vpnName, String rd) {
-        return elanManager.isOpenStackVniSemanticsEnforced()
-                && isVxlanNetworkAndInternalRouterVpn(subnetId, vpnName, rd);
-    }
-
     static NodeRef buildNodeRef(BigInteger dpId) {
         return new NodeRef(InstanceIdentifier.builder(Nodes.class)
                 .child(Node.class, new NodeKey(new NodeId("openflow:" + dpId))).build());
index 29a84788b1efdc38852983eb746cd6d85b21fddd..1b6434570aed97fd57c7660702827678f83438a3 100644 (file)
@@ -59,7 +59,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
 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.action.types.rev131112.action.action.OutputActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
@@ -124,7 +123,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpi
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.l3vpn.lb.nexthops.Nexthops;
 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.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
@@ -755,12 +753,8 @@ public class NexthopManager implements AutoCloseable {
         ElanInstance elanInstance = null;
         Prefixes prefix = fibUtil.getPrefixToInterface(vpnId, prefixIp);
         if (prefix != null) {
-            Uuid subnetId = prefix.getSubnetId();
-            if (subnetId != null) {
-                Subnetmap subnetMap = fibUtil.getSubnetMap(subnetId);
-                if (subnetMap != null && subnetMap.getNetworkId() != null) {
-                    elanInstance = elanService.getElanInstance(subnetMap.getNetworkId().getValue());
-                }
+            if (prefix.getNetworkId() != null) {
+                elanInstance = elanService.getElanInstance(prefix.getNetworkId().getValue());
             }
         }
 
@@ -942,16 +936,11 @@ public class NexthopManager implements AutoCloseable {
                 return;
             }
             BigInteger tunnelId;
-            if (fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(prefixInfo.getSubnetId(), vpnId,
-                    rd)) {
-                java.util.Optional<Long> optionalVni = fibUtil.getVniForVxlanNetwork(prefixInfo.getSubnetId());
-                if (!optionalVni.isPresent()) {
-                    LOG.error("VNI not found for nexthop {} vrfEntry {} with subnetId {}", nextHopIp,
-                            vrfEntry, prefixInfo.getSubnetId());
-                    return;
-                }
-                tunnelId = BigInteger.valueOf(optionalVni.get());
+            if (FibUtil.isVxlanNetwork(prefixInfo.getNetworkType())) {
+                tunnelId = BigInteger.valueOf(prefixInfo.getSegmentationId());
             } else {
+                LOG.warn("Network is not of type VXLAN for prefix {}."
+                        + "Going with default Lport Tag.", prefixInfo.toString());
                 tunnelId = BigInteger.valueOf(label);
             }
             List<ActionInfo> actionInfos = new ArrayList<>();
index b1c513f75195539cde6c07ff8917953d0b98b518..1a42ff738ad02f106b9afe81c18f3cb511fb387e 100755 (executable)
@@ -885,8 +885,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
                     baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, instructions,
                             NwConstants.ADD_FLOW, tx, null);
-                    if (!fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(localNextHopInfo.getSubnetId(),
-                            vpnName, rd)) {
+                    if  (!FibUtil.isVxlanNetwork(localNextHopInfo.getNetworkType())) {
                         optLabel.ifPresent(label -> {
                             if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) {
                                 LOG.debug(
@@ -1133,8 +1132,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
                     baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null,
                             NwConstants.DEL_FLOW, tx, null);
-                    if (!fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(localNextHopInfo.getSubnetId(),
-                            vpnId, rd)) {
+                    if  (!FibUtil.isVxlanNetwork(localNextHopInfo.getNetworkType())) {
                         if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) {
                             FibUtil.getLabelFromRoutePaths(vrfEntry).ifPresent(label -> {
                                 makeLFibTableEntry(dpnId, label, null /* instructions */, DEFAULT_FIB_FLOW_PRIORITY,
index 5b602b057a5e8e10f01527990574e37194e1f4c5..fe0da69a665043697ac2406199cf04c1023bfa9b 100644 (file)
@@ -318,7 +318,7 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         String nextHopIp = NatUtil.getEndpointIpAddressForDPN(dataBroker, dpnId);
         String ipPrefix = externalIp + "/32";
         NatUtil.addPrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId),
-                null, ipPrefix, dpnId, new Uuid(subNetId), Prefixes.PrefixCue.Nat);
+                null, ipPrefix, externalNetId, new Uuid(subNetId), dpnId, Prefixes.PrefixCue.Nat);
 
         fibManager.addOrUpdateFibEntry(rd, routerMac, ipPrefix,
                 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, extSubnetId,
index 34abd2c0849dc02ceea80fdee5adb619b4ecad25..3b0cec734ef0c778484bae089ef32c3e54390faa 100644 (file)
@@ -145,7 +145,8 @@ public class EvpnDnatFlowProgrammer {
         String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
         //Inform to FIB and BGP
         NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, vpnName, rd, fibExternalIp,
-                nextHopIp, l3Vni, floatingIpInterface, floatingIpPortMacAddress, confTx, RouteOrigin.STATIC, dpnId);
+                nextHopIp, l3Vni, floatingIpInterface, floatingIpPortMacAddress,
+                confTx, RouteOrigin.STATIC, dpnId, networkId);
 
         /* Install the flow table L3_FIB_TABLE (table=21)-> PDNAT_TABLE (table=25)
          * (SNAT to DNAT reverse traffic: If the DPN has both SNAT and  DNAT configured )
index 6693b5a392d633476e55d9f5344b8691ef00a598..a283d45d315ee01c5108df279fba227d57254340 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
+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.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
@@ -82,7 +83,8 @@ public class EvpnSnatFlowProgrammer {
 
     public void evpnAdvToBgpAndInstallFibAndTsFlows(final BigInteger dpnId, final short tableId,
         final String externalIp, final String vpnName, final String rd, final String nextHopIp,
-        final long routerId, final String routerName, TypedWriteTransaction<Configuration> confTx) {
+        final long routerId, final String routerName, final Uuid extNetworkId,
+        TypedWriteTransaction<Configuration> confTx) {
      /*
       * 1) Install the flow INTERNAL_TUNNEL_TABLE (table=36)-> INBOUND_NAPT_TABLE (table=44)
       *    (FIP VM on DPN1 is responding back to external fixed IP on DPN2) {DNAT to SNAT traffic on
@@ -127,7 +129,8 @@ public class EvpnSnatFlowProgrammer {
          */
         //Inform to BGP
         NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, vpnName, rd, externalIp,
-                nextHopIp, l3Vni, null /*InterfaceName*/, gwMacAddress, confTx, RouteOrigin.STATIC, dpnId);
+                nextHopIp, l3Vni, null /*InterfaceName*/, gwMacAddress, confTx, RouteOrigin.STATIC,
+                dpnId, extNetworkId);
 
         //Install custom FIB routes - FIB table.
         List<Instruction> customInstructions = new ArrayList<>();
index 27968cd4415dfe13f38df95f00b2a67416bfca7b..b26a36d6c99f555dc06e455bc002a8ee6daf060d 100644 (file)
@@ -1073,7 +1073,7 @@ public class ExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Rou
         }
         if (extNwProvType == ProviderTypes.VXLAN) {
             evpnSnatFlowProgrammer.evpnAdvToBgpAndInstallFibAndTsFlows(dpnId, tableId, externalIp, vpnName, rd,
-                nextHopIp, routerId, routerName, confTx);
+                nextHopIp, routerId, routerName, extNetworkId, confTx);
             return;
         }
         //Generate VPN label for the external IP
index fddcaf39eb3ffaa3ea931de464a9eeff91192dc2..5cdaa7bf27905c74030858ba59a91afa6582201d 100644 (file)
@@ -172,7 +172,8 @@ public final class NatEvpnUtil {
                                                  String interfaceName,
                                                  String gwMacAddress,
                                                  TypedWriteTransaction<Configuration> writeTx,
-                                                 RouteOrigin origin, BigInteger dpId) {
+                                                 RouteOrigin origin, BigInteger dpId,
+                                                 Uuid networkId) {
         try {
             LOG.info("addRoutesForVxLanProvType : Adding Fib entry rd {} prefix {} nextHop {} l3Vni {}",
                     rd, prefix, nextHopIp, l3Vni);
@@ -181,8 +182,8 @@ public final class NatEvpnUtil {
                         prefix);
                 return;
             }
-            NatUtil.addPrefixToInterface(broker, NatUtil.getVpnId(broker, vpnName), interfaceName, prefix, dpId,
-                    null /* subnet-id */, Prefixes.PrefixCue.Nat);
+            NatUtil.addPrefixToInterface(broker, NatUtil.getVpnId(broker, vpnName), interfaceName, prefix,
+                    networkId.getValue(), null, dpId, Prefixes.PrefixCue.Nat);
 
             fibManager.addOrUpdateFibEntry(rd, null /*macAddress*/, prefix,
                     Collections.singletonList(nextHopIp), VrfEntry.EncapType.Vxlan, NatConstants.DEFAULT_LABEL_VALUE,
index 06a287c90954370e5fa36980d27dc4e42a2955d9..0abce428a950ccd8e6a43868c34f831270594e21 100644 (file)
@@ -726,7 +726,8 @@ public class NatTunnelInterfaceStateListener
                 LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Advertise the route to the externalIp {} "
                         + "having nextHopIp {}", externalIp, nextHopIp);
                 NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, externalVpnName, rd,
-                        externalIp, nextHopIp, l3Vni, tunnelName, gwMacAddress, confTx, RouteOrigin.STATIC, srcDpnId);
+                        externalIp, nextHopIp, l3Vni, tunnelName, gwMacAddress, confTx, RouteOrigin.STATIC,
+                        srcDpnId, networkId);
                 serviceId = l3Vni;
             } else {
 
@@ -875,7 +876,7 @@ public class NatTunnelInterfaceStateListener
                             + "having nextHopIp {}", externalIp, nextHopIp);
                     NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, vpnName, rd,
                         externalIp, nextHopIp, l3Vni, interfaceName, gwMacAddress, confTx, RouteOrigin.STATIC,
-                        fipCfgdDpnId);
+                        fipCfgdDpnId, extNwId);
                     serviceId = l3Vni;
                 } else {
                     long label = floatingIPListener.getOperationalIpMapping(routerName, interfaceName, internalIp);
index 3e624902c9228b7f9d532768200c42680ecacdf4..3384cf5c25c5013828aa58e047f0915901421fe6 100644 (file)
@@ -752,8 +752,8 @@ public final class NatUtil {
                 return;
             }
 
-            addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId,
-                    subnetId, Prefixes.PrefixCue.Nat);
+            addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
+                    subnetId, dpId, Prefixes.PrefixCue.Nat);
             fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
                     Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
                     null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
@@ -772,14 +772,15 @@ public final class NatUtil {
     }
 
     static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
-                                     BigInteger dpId, Uuid subnetId, Prefixes.PrefixCue prefixCue) {
+                                     String networkId, Uuid subnetId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
         InstanceIdentifier<Prefixes> prefixId = 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();
         PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
-        prefixBuilder.setVpnInterfaceName(interfaceName).setSubnetId(subnetId).setPrefixCue(prefixCue);
+        prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
+        prefixBuilder.setNetworkId(new Uuid(networkId));
         try {
             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
                     prefixBuilder.build());
index d2f37a6559d23d850fefecf17b358af571a62700..1619d5f9bf3331a6afcab412cfd47f5a8a24d3a6 100644 (file)
@@ -93,6 +93,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.lea
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry.BgpvpnType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
@@ -846,7 +847,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         Adjacencies adjs = createPortIpAdjacencies(port, isRouterInterface, wrtConfigTxn, null, null);
         String infName = port.getUuid().getValue();
         LOG.trace("createVpnInterface for Port: {}, isRouterInterface: {}", infName, isRouterInterface);
-        writeVpnInterfaceToDs(vpnIds, infName, adjs, isRouterInterface, wrtConfigTxn);
+        writeVpnInterfaceToDs(vpnIds, infName, adjs, port.getNetworkId(), isRouterInterface, wrtConfigTxn);
     }
 
     protected void withdrawPortIpFromVpnIface(Uuid vpnId, Uuid internetVpnId,
@@ -1618,7 +1619,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                 listVpn.add(internetId);
                             }
                             writeVpnInterfaceToDs(listVpn,
-                                    vpnInfName, portAdj, isRouterInterface, wrtConfigTxn);
+                                    vpnInfName, portAdj, port.getNetworkId(), isRouterInterface, wrtConfigTxn);
                             if (sn.getRouterId() != null) {
                                 addToNeutronRouterInterfacesMap(sn.getRouterId(), portId.getValue());
                             }
@@ -3028,21 +3029,21 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
     private void createExternalVpnInterface(Uuid vpnId, String infName,
                                             TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
-        writeVpnInterfaceToDs(Collections.singletonList(vpnId), infName, null,
+        writeVpnInterfaceToDs(Collections.singletonList(vpnId), infName, null, vpnId /* external network id */,
                 false /* not a router iface */, wrtConfigTxn);
     }
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     private void writeVpnInterfaceToDs(@Nonnull Collection<Uuid> vpnIdList, String infName, Adjacencies adjacencies,
-            Boolean isRouterInterface, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
+            Uuid networkUuid, Boolean isRouterInterface, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
         if (vpnIdList.isEmpty() || infName == null) {
-            LOG.error("vpn id or interface is null");
+            LOG.error("vpnid is empty or interface({}) is null", infName);
             return;
         }
         if (wrtConfigTxn == null) {
             ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
-                tx -> writeVpnInterfaceToDs(vpnIdList, infName, adjacencies, isRouterInterface, tx)), LOG,
+                tx -> writeVpnInterfaceToDs(vpnIdList, infName, adjacencies, networkUuid, isRouterInterface, tx)), LOG,
                 "Error writing VPN interface");
             return;
         }
@@ -3058,6 +3059,17 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 .setName(infName)
                 .setVpnInstanceNames(vpnIdListStruct)
                 .setRouterInterface(isRouterInterface);
+        LOG.info("Network Id is {}", networkUuid);
+        if (networkUuid != null) {
+            Network portNetwork = neutronvpnUtils.getNeutronNetwork(networkUuid);
+            ProviderTypes providerType = NeutronvpnUtils.getProviderNetworkType(portNetwork);
+            NetworkAttributes.NetworkType networkType = (providerType != null)
+                    ? NetworkAttributes.NetworkType.valueOf(providerType.getName()) : null;
+            String segmentationId = NeutronvpnUtils.getSegmentationIdFromNeutronNetwork(portNetwork);
+            vpnb.setNetworkId(networkUuid).setNetworkType(networkType)
+                .setSegmentationId(segmentationId != null ? Long.parseLong(segmentationId) : 0L);
+        }
+
         if (adjacencies != null) {
             vpnb.addAugmentation(Adjacencies.class, adjacencies);
         }
index 411d4308fc8d8ef52aaf0c88a6a23a9750fd0577..1ca4c7d94f21c0d32baaa4e10df86ca0cc267f55 100644 (file)
@@ -23,6 +23,11 @@ module l3vpn {
     //RFC6991
   }
 
+  import neutronvpn {
+    prefix nvpn;
+    revision-date "2015-06-02";
+  }
+
   description
     "This YANG module defines the generic configuration data for L3VPN service.
 
@@ -836,6 +841,7 @@ module l3vpn {
       leaf router-interface {
           type boolean;
       }
+      uses nvpn:network-attributes;
     }
   }
 
index dbc861f3f528b0884202a2b815dc5b1ae1fe6a78..b03a029c2f0aeea40705f2471a9e5b8844b10d44 100644 (file)
@@ -75,11 +75,6 @@ module odl-l3vpn {
         uses adjacency-list;
     }
 
-    augment "/l3vpn:vpn-interfaces/l3vpn:vpn-interface" {
-        ext:augment-identifier "opState";
-        leaf stateUp {type boolean; config false;}
-    }
-
     /* Operational DS containers for reverse lookups*/
     container prefix-to-interface {
         config false;
@@ -95,9 +90,7 @@ module odl-l3vpn {
               leaf vpn-interface-name {
                   type string;
               }
-              leaf subnet-id {
-                  type yang:uuid;
-              }
+              uses nvpn:network-attributes;
               leaf prefix-cue {
                   type enumeration {
                       enum none {
index 5ed64a5feb1a69847009563d811ac8b15079706a..52cf84de83108d62202e4233461c3d25f7ef8c1f 100755 (executable)
@@ -102,6 +102,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget;
 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.external.subnets.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
@@ -706,19 +707,28 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                                                   Interface interfaceState) {
         InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
         // Read NextHops
-        InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
-        Optional<Adjacencies> adjacencies = Optional.absent();
+        Optional<VpnInterface> vpnInteface = Optional.absent();
         try {
-            adjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                    path);
+            vpnInteface = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+            LogicalDatastoreType.CONFIGURATION, identifier);
         } catch (ReadFailedException e) {
             LOG.error("processVpnInterfaceAdjacencies: Failed to read data store for interface {} vpn {} rd {}"
                     + "dpn {}", interfaceName, vpnName, primaryRd, dpnId);
         }
-        if (!adjacencies.isPresent()) {
-            addVpnInterfaceToOperational(vpnName, interfaceName, dpnId, null/*adjacencies*/, lportTag,
-                    null/*gwMac*/, writeOperTxn);
-            return;
+        Uuid intfnetworkUuid = null;
+        NetworkType networkType = null;
+        Long segmentationId = Long.valueOf(-1);
+        Adjacencies adjacencies = null;
+        if (vpnInteface.isPresent()) {
+            intfnetworkUuid = vpnInteface.get().getNetworkId();
+            networkType = vpnInteface.get().getNetworkType();
+            segmentationId = vpnInteface.get().getSegmentationId();
+            adjacencies = vpnInteface.get().augmentation(Adjacencies.class);
+            if (adjacencies == null) {
+                addVpnInterfaceToOperational(vpnName, interfaceName, dpnId, null/*adjacencies*/, lportTag,
+                        null/*gwMac*/, writeOperTxn);
+                return;
+            }
         }
         // Get the rd of the vpn instance
         String nextHopIp = null;
@@ -741,7 +751,7 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
         boolean isL3VpnOverVxLan = VpnUtil.isL3VpnOverVxLan(l3vni);
         VrfEntry.EncapType encapType = isL3VpnOverVxLan ? VrfEntry.EncapType.Vxlan : VrfEntry.EncapType.Mplsgre;
         VpnPopulator registeredPopulator = L3vpnRegistry.getRegisteredPopulator(encapType);
-        List<Adjacency> nextHops = adjacencies.get().getAdjacency();
+        List<Adjacency> nextHops = (adjacencies != null) ? adjacencies.getAdjacency() : Collections.emptyList();
         List<Adjacency> value = new ArrayList<>();
         for (Adjacency nextHop : nextHops) {
             String rd = primaryRd;
@@ -760,12 +770,15 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                         ? Prefixes.PrefixCue.PhysNetFunc : Prefixes.PrefixCue.None;
                 LOG.debug("processVpnInterfaceAdjacencies: Adding prefix {} to interface {} with nextHops {} on dpn {}"
                         + " for vpn {}", prefix, interfaceName, nhList, dpnId, vpnName);
+
+                Prefixes prefixes = (intfnetworkUuid != null)
+                    ? VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, intfnetworkUuid ,networkType,
+                            segmentationId, prefixCue) :
+                    VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, prefixCue);
                 writeOperTxn.merge(
                     LogicalDatastoreType.OPERATIONAL,
                     VpnUtil.getPrefixToInterfaceIdentifier(
-                        vpnUtil.getVpnId(vpnName), prefix),
-                    VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, nextHop.getSubnetId(),
-                            prefixCue), true);
+                        vpnUtil.getVpnId(vpnName), prefix), prefixes, true);
                 final Uuid subnetId = nextHop.getSubnetId();
 
                 String gatewayIp = nextHop.getSubnetGatewayIp();
@@ -1805,13 +1818,24 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                     LOG.trace("addNewAdjToVpnInterface: Adding prefix {} to interface {} for vpn {}", prefix,
                             currVpnIntf.getName(), vpnName);
 
+                    InstanceIdentifier<VpnInterface> vpnIfaceConfigidentifier = VpnUtil
+                            .getVpnInterfaceIdentifier(currVpnIntf.getName());
+                    Optional<VpnInterface> vpnIntefaceConfig = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                            LogicalDatastoreType.CONFIGURATION, vpnIfaceConfigidentifier);
+                    Prefixes pnfPrefix = VpnUtil.getPrefixToInterface(BigInteger.ZERO, currVpnIntf.getName(), prefix,
+                            Prefixes.PrefixCue.PhysNetFunc);
+                    if (vpnIntefaceConfig.isPresent()) {
+                        pnfPrefix = VpnUtil.getPrefixToInterface(BigInteger.ZERO, currVpnIntf.getName(), prefix,
+                                vpnIntefaceConfig.get().getNetworkId(), vpnIntefaceConfig.get().getNetworkType(),
+                                vpnIntefaceConfig.get().getSegmentationId(), Prefixes.PrefixCue.PhysNetFunc);
+                    }
+
                     String parentVpnRd = getParentVpnRdForExternalSubnet(adj);
 
                     writeOperTxn.merge(
                             LogicalDatastoreType.OPERATIONAL,
                             VpnUtil.getPrefixToInterfaceIdentifier(vpnUtil.getVpnId(adj.getSubnetId().getValue()),
-                                    prefix), VpnUtil.getPrefixToInterface(BigInteger.ZERO, currVpnIntf.getName(),
-                                    prefix, adj.getSubnetId(), Prefixes.PrefixCue.PhysNetFunc), true);
+                                    prefix), pnfPrefix, true);
 
                     fibManager.addOrUpdateFibEntry(adj.getSubnetId().getValue(), adj.getMacAddress(),
                             adj.getIpAddress(), Collections.emptyList(), null /* EncapType */, 0 /* label */,
index 8e7483667b01bf2bb8cfbf2192fd24f8047b64e4..b1bde4edf050f9c8e72d449d89e6db60e3b7913e 100644 (file)
@@ -867,8 +867,7 @@ public class VpnSubnetRouteHandler {
         Preconditions.checkNotNull(nextHopIp, LOGGING_PREFIX + "NextHopIp cannot be null or empty!");
         vpnUtil.syncWrite(LogicalDatastoreType.OPERATIONAL, VpnUtil
                 .getPrefixToInterfaceIdentifier(vpnUtil.getVpnId(vpnName), subnetIp), VpnUtil
-                .getPrefixToInterface(nhDpnId, subnetId.getValue(), subnetIp, subnetId,
-                        Prefixes.PrefixCue.SubnetRoute));
+                .getPrefixToInterface(nhDpnId, subnetId.getValue(), subnetIp, Prefixes.PrefixCue.SubnetRoute));
         vpnPopulator.populateFib(input, null /*writeCfgTxn*/);
         try {
             // BGP manager will handle withdraw and advertise internally if prefix
index 274c2cf1255a241edbe58bb0101e55df63b4d35f..7031307a83cbc882381f016a1441876fd47cb611 100644 (file)
@@ -348,10 +348,18 @@ public final class VpnUtil {
         return InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build();
     }
 
-    static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix, Uuid subnetId,
+    static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix,
+            Uuid networkId, NetworkType networkType, Long segmentationId, Prefixes.PrefixCue prefixCue) {
+        return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName(
+            vpnInterfaceName).setIpAddress(ipPrefix)//.setSubnetId(subnetId)
+                .setNetworkId(networkId).setNetworkType(networkType).setSegmentationId(segmentationId)
+                .setPrefixCue(prefixCue).build();
+    }
+
+    static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix,
             Prefixes.PrefixCue prefixCue) {
         return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName(vpnInterfaceName).setIpAddress(ipPrefix)
-                .setSubnetId(subnetId).setPrefixCue(prefixCue).build();
+                .setPrefixCue(prefixCue).build();
     }
 
     Optional<Prefixes> getPrefixToInterface(long vpnId, String ipPrefix) {