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>
long vpnId, VrfEntry vrfEntry){
makeSubnetRouteFlow(dpnId);
List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
long vpnId, VrfEntry vrfEntry){
makeSubnetRouteFlow(dpnId);
List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
- List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
Long elanTag = rdToElanOpEntry.getElanTag();
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);
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();
makeLFibTableEntry(dpnId,vrfEntry.getLabel(),instructions,
vrfEntry.getNextHopAddress(),NwConstants.ADD_FLOW);
// TODO makeTunnelTableEntry();
SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder().setKey(new SubnetOpDataEntryKey(subnetId));
subOpBuilder.setSubnetId(subnetId);
subOpBuilder.setSubnetCidr(subnetIp);
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;
if (rd == null) {
logger.error("onSubnetAddedToVpn: The VPN Instance name " + notification.getVpnName() + " does not have RD ");
return;
import org.opendaylight.vpnservice.mdsalutil.NwConstants;
import org.opendaylight.vpnservice.mdsalutil.packet.ARP;
import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
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;
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;
+ 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()
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()
import org.opendaylight.vpnservice.VpnSubnetRouteHandler;
import org.opendaylight.vpnservice.interfacemgr.globals.IfmConstants;
import org.opendaylight.vpnservice.utilities.InterfaceUtils;
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;
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;
SubnetToDpn subnetToDpn = null;
RdToElanOpEntry rdToElanOpEntry = null;
String subnetIp = "10.1.1.24";
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";
String nexthopIp = null;
String poolName = null;
String interfaceName = "VPN";
DPNTEPsInfo dpntePsInfo = null;
TunnelEndPoints tunlEndPts = null;
IpAddress ipAddress = null;
DPNTEPsInfo dpntePsInfo = null;
TunnelEndPoints tunlEndPts = null;
IpAddress ipAddress = null;
+ Ipv4Family ipv4Family = null;
String idKey = null;
AllocateIdOutput allocateIdOutput = null;
AllocateIdInput allocateIdInput = 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);
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
.state.Interface> ifStateId = InterfaceUtils.buildStateInterfaceId(portKey);
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);
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;
@Mock DataBroker dataBroker;
@Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
Optional<RdToElanOpEntry> optionalRd;
Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
optionalVpnInstnce;
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 {
@Before
public void setUp() throws Exception {
optionalSubnetMap = Optional.of(subnetmap);
optionalRd = Optional.of(rdToElanOpEntry);
optionalVpnInstnce = Optional.of(vpnInstance);
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);
doReturn(Futures.immediateCheckedFuture(optionalRd)).when(mockReadTx).read(LogicalDatastoreType.OPERATIONAL,
rdIdentifier);
.CONFIGURATION, subMapid);
doReturn(Futures.immediateCheckedFuture(optionalVpnInstnce)).when(mockReadTx).read(LogicalDatastoreType
.CONFIGURATION, instVpnInstance);
.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";
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");
poolName = "vpnservices";
elanTag = Long.valueOf(2);
longId = Long.valueOf("100");
.setSubnetIp(subnetIp).setVpnName(interfaceName).setElanTag(elanTag).build();
subnetOp = new SubnetOpDataEntryBuilder().setElanTag(elanTag).setNhDpnId(dpId).setSubnetCidr(subnetIp)
.setSubnetId(subnetId).setKey(new SubnetOpDataEntryKey(subnetId)).setVpnName(interfaceName)
.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
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
rdToElanOpEntry = new RdToElanOpEntryBuilder().setElanTag(elanTag).setRd(interfaceName).setVpnName
(interfaceName).setNextHopIp(nexthopIp)
.setKey(new RdToElanOpEntryKey(interfaceName, subnetIp)).setSubnetIp(subnetIp).build();
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();
doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();