Bug 5781: Ping test is FAILED from DC-GW to Invisible IP 97/37997/2
authorSuraj Ranjan <suraj.ranjan@ericsson.com>
Fri, 22 Apr 2016 04:37:20 +0000 (10:07 +0530)
committerSuraj Ranjan <suraj.ranjan@ericsson.com>
Fri, 22 Apr 2016 07:17:26 +0000 (12:47 +0530)
Bug 5782: Subnet route is not getting programmed for a Network

For issue 5781:
The packets received by SubnetRouteHandler are all MPLS Label
wrapped if the packets are initiated by DC-GW.  As a result,
such packets are ignored by SubnetRoutePacketHandler.

This fix changes the SubnetRoute rule in Table 20 (LFIB Table)
to pop-off the mpls label before shipping packet to the
controller.

For issue 5782:
The race to fetch the RD by both VPNManager and SubnetRouteHandler
results in RD fetch failing in SubnetRouteHandler.  The fix is
for SubnetRouteHandler will now rely on VPNInstance config produced by
NeutronVpn rather than using vpn-instance-to-vpn-id config mapping
produced by VpnManager.

Change-Id: I73af156d0d55d7f79dca592c053f26398788b719
Signed-off-by: Suraj Ranjan <suraj.ranjan@ericsson.com>
fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnSubnetRouteHandler.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnUtil.java
vpnmanager/vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/VpnSubnetRouteHandlerTest.java

index a1e729f7aec9207ed7bf368e4f1178fdde82a7b8..769038f1cae35ebb43367547565317cc1b4d18b7 100644 (file)
@@ -220,12 +220,22 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
                                        long vpnId, VrfEntry vrfEntry){
       makeSubnetRouteFlow(dpnId);
       List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
-      List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
       Long elanTag = rdToElanOpEntry.getElanTag();
+
       instructions.add(new InstructionInfo(InstructionType.write_metadata,  new BigInteger[] { (BigInteger.valueOf(elanTag)).shiftLeft(24), MetaDataUtil.METADATA_MASK_SERVICE }));
       instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.L3_SUBNET_ROUTE_TABLE }));
       makeConnectedRoute(dpnId,vpnId,vrfEntry,rdToElanOpEntry.getRd(),
               instructions,NwConstants.ADD_FLOW);
+
+      List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
+      // reinitialize instructions list for LFIB Table
+      instructions = new ArrayList<InstructionInfo>();
+
+      actionsInfos.add(new ActionInfo(ActionType.pop_mpls, new String[]{}));
+      instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+      instructions.add(new InstructionInfo(InstructionType.write_metadata,  new BigInteger[] { (BigInteger.valueOf(elanTag)).shiftLeft(24), MetaDataUtil.METADATA_MASK_SERVICE }));
+      instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.L3_SUBNET_ROUTE_TABLE }));
+
       makeLFibTableEntry(dpnId,vrfEntry.getLabel(),instructions,
               vrfEntry.getNextHopAddress(),NwConstants.ADD_FLOW);
       // TODO makeTunnelTableEntry();
index 9e3ba8f0d91b588c5502048b98e265bd6f08056a..8e22e7bd96c2409c10300423cd2566af3f6879e3 100644 (file)
@@ -107,7 +107,7 @@ public class VpnSubnetRouteHandler implements NeutronvpnListener {
                 SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder().setKey(new SubnetOpDataEntryKey(subnetId));
                 subOpBuilder.setSubnetId(subnetId);
                 subOpBuilder.setSubnetCidr(subnetIp);
-                String rd = VpnUtil.getVpnRd(broker, vpnName);
+                String rd = VpnUtil.getVpnRdFromVpnInstanceConfig(broker, vpnName);
                 if (rd == null) {
                     logger.error("onSubnetAddedToVpn: The VPN Instance name " + notification.getVpnName() + " does not have RD ");
                     return;
index 50c5eef4a4d64fac607934655cb18a3b8225d919..7cb826cc876610d9a91855fd44d99c94713e621b 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
 import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
 import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
@@ -236,6 +237,19 @@ public class VpnUtil {
         return rd;
     }
 
+    static String getVpnRdFromVpnInstanceConfig(DataBroker broker, String vpnName) {
+        InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
+                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+        Optional<VpnInstance> vpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
+        String rd = null;
+        if(vpnInstance.isPresent()) {
+            VpnInstance instance = vpnInstance.get();
+            VpnAfConfig config = instance.getIpv4Family();
+            rd = config.getRouteDistinguisher();
+        }
+        return rd;
+    }
+
     static org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
            getVpnInstanceToVpnId(String vpnName, long vpnId, String rd) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceBuilder()
index bf933fef79df2beeca9bf1825f0aae1c81e70ab0..3d9217014e9c69f8f56ed2b0b9f90f2c4362c093 100644 (file)
@@ -26,6 +26,10 @@ import org.opendaylight.vpnservice.VpnInterfaceManager;
 import org.opendaylight.vpnservice.VpnSubnetRouteHandler;
 import org.opendaylight.vpnservice.interfacemgr.globals.IfmConstants;
 import org.opendaylight.vpnservice.utilities.InterfaceUtils;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4Family;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance
+        .Ipv4FamilyBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
@@ -109,6 +113,7 @@ public class VpnSubnetRouteHandlerTest {
     SubnetToDpn subnetToDpn = null;
     RdToElanOpEntry rdToElanOpEntry = null;
     String subnetIp = "10.1.1.24";
+    String routeDistinguisher = "100:1";
     String nexthopIp = null;
     String poolName = null;
     String interfaceName = "VPN";
@@ -131,9 +136,11 @@ public class VpnSubnetRouteHandlerTest {
     DPNTEPsInfo dpntePsInfo = null;
     TunnelEndPoints tunlEndPts = null;
     IpAddress ipAddress = null;
+    Ipv4Family ipv4Family = null;
     String idKey = null;
     AllocateIdOutput allocateIdOutput = null;
     AllocateIdInput allocateIdInput = null;
+    org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance vpnInstnce;
 
     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
             .state.Interface> ifStateId = InterfaceUtils.buildStateInterfaceId(portKey);
@@ -153,6 +160,11 @@ public class VpnSubnetRouteHandlerTest {
             child(RdToElanOpEntry.class, new RdToElanOpEntryKey(interfaceName, subnetIp)).build();
     InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id
             .VpnInstance> instVpnInstance = getVpnInstanceToVpnIdIdentifier(interfaceName);
+    InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.
+            VpnInstance> vpnInstanceIdentifier = InstanceIdentifier.builder(VpnInstances.class).child(org.opendaylight
+            .yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance.class,
+            new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances
+                    .VpnInstanceKey(interfaceName)).build();
 
     @Mock DataBroker dataBroker;
     @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
@@ -174,6 +186,8 @@ public class VpnSubnetRouteHandlerTest {
     Optional<RdToElanOpEntry> optionalRd;
     Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
             optionalVpnInstnce;
+    Optional<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance>
+            vpnInstanceOptional;
 
     @Before
     public void setUp() throws Exception {
@@ -198,6 +212,7 @@ public class VpnSubnetRouteHandlerTest {
         optionalSubnetMap = Optional.of(subnetmap);
         optionalRd = Optional.of(rdToElanOpEntry);
         optionalVpnInstnce = Optional.of(vpnInstance);
+        vpnInstanceOptional = Optional.of(vpnInstnce);
 
         doReturn(Futures.immediateCheckedFuture(optionalRd)).when(mockReadTx).read(LogicalDatastoreType.OPERATIONAL,
                 rdIdentifier);
@@ -219,13 +234,15 @@ public class VpnSubnetRouteHandlerTest {
                 .CONFIGURATION, subMapid);
         doReturn(Futures.immediateCheckedFuture(optionalVpnInstnce)).when(mockReadTx).read(LogicalDatastoreType
                 .CONFIGURATION, instVpnInstance);
+        doReturn(Futures.immediateCheckedFuture(vpnInstanceOptional)).when(mockReadTx).read(LogicalDatastoreType
+                .CONFIGURATION,vpnInstanceIdentifier);
         doReturn(idOutputOptional).when(idManager).allocateId(allocateIdInput);
     }
 
     private void setupMocks() {
 
         nexthopIp = "10.1.1.25";
-        idKey = "VPN.10.1.1.24";
+        idKey = "100:1.10.1.1.24";
         poolName = "vpnservices";
         elanTag = Long.valueOf(2);
         longId = Long.valueOf("100");
@@ -271,7 +288,7 @@ public class VpnSubnetRouteHandlerTest {
                 .setSubnetIp(subnetIp).setVpnName(interfaceName).setElanTag(elanTag).build();
         subnetOp = new SubnetOpDataEntryBuilder().setElanTag(elanTag).setNhDpnId(dpId).setSubnetCidr(subnetIp)
                 .setSubnetId(subnetId).setKey(new SubnetOpDataEntryKey(subnetId)).setVpnName(interfaceName)
-                .setVrfId(interfaceName).setSubnetToDpn(subToDpn).setRouteAdvState(TaskState.Done).build();
+                .setVrfId(routeDistinguisher).setSubnetToDpn(subToDpn).setRouteAdvState(TaskState.Done).build();
         vpnInstance = new VpnInstanceBuilder().setVpnId(elanTag).setVpnInstanceName(interfaceName).setVrfId
                 (interfaceName).setKey(new VpnInstanceKey(interfaceName)).build();
         subnetmap = new SubnetmapBuilder().setSubnetIp(subnetIp).setId(subnetId).setNetworkId(portId).setKey(new
@@ -286,6 +303,11 @@ public class VpnSubnetRouteHandlerTest {
         rdToElanOpEntry = new RdToElanOpEntryBuilder().setElanTag(elanTag).setRd(interfaceName).setVpnName
                 (interfaceName).setNextHopIp(nexthopIp)
                 .setKey(new RdToElanOpEntryKey(interfaceName, subnetIp)).setSubnetIp(subnetIp).build();
+        ipv4Family = new Ipv4FamilyBuilder().setRouteDistinguisher(routeDistinguisher).build();
+        vpnInstnce = new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances
+                .VpnInstanceBuilder().setKey(new org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn
+                .rev140815.vpn.instances.VpnInstanceKey(interfaceName)).setVpnInstanceName(interfaceName)
+                .setIpv4Family(ipv4Family).build();
         doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
         doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
         doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();