X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=fibmanager%2Ffibmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Ffibmanager%2FFibManager.java;h=b9906ada2455bb32e8062d80fd2088bb09802d9f;hb=4110307879cad1aa54943aedbf937b2f21575b4c;hp=62b60ca8c1783aa7516ba633b5ee2e06591fbc9a;hpb=8e3be9c632b1b774191e602d8abb2a0592a9e2a8;p=vpnservice.git diff --git a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java index 62b60ca8..b9906ada 100644 --- a/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java +++ b/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java @@ -17,6 +17,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -41,9 +42,11 @@ import org.opendaylight.vpnservice.mdsalutil.MatchInfo; import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil; import org.opendaylight.vpnservice.mdsalutil.NwConstants; import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; -import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.OpState; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.RdToElanOp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.rd.to.elan.op.RdToElanOpEntryKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnToExtraroute; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.VpnIdsKey; @@ -71,9 +74,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpc import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetTunnelTypeOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies; -import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -185,6 +186,17 @@ public class FibManager extends AbstractDataChangeListener implements Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId() + "has null vpnId!"); Collection vpnToDpnList = vpnInstance.getVpnToDpnList(); + Long vpnId = vpnInstance.getVpnId(); + RdToElanOpEntry rdToElanOpEntry = getRdToElanOpEntry(broker, vrfTableKey.getRouteDistinguisher(), + vrfEntry.getDestPrefix()); + if (rdToElanOpEntry!=null) { + if (vpnToDpnList!=null) { + for (VpnToDpnList curDpn : vpnToDpnList) { + installSubnetRouteInFib(curDpn.getDpnId(), rdToElanOpEntry, vpnId.longValue(), vrfEntry); + } + } + return; + } BigInteger localDpnId = createLocalFibEntry(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry); if (vpnToDpnList != null) { @@ -197,6 +209,74 @@ public class FibManager extends AbstractDataChangeListener implements } } + private void installSubnetRouteInFib(BigInteger dpnId, RdToElanOpEntry rdToElanOpEntry, + long vpnId, VrfEntry vrfEntry){ + makeSubnetRouteFlow(dpnId); + List instructions = new ArrayList(); + List actionsInfos = new ArrayList(); + 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); + makeLFibTableEntry(dpnId,vrfEntry.getLabel(),instructions, + vrfEntry.getNextHopAddress(),NwConstants.ADD_FLOW); + // TODO makeTunnelTableEntry(); + } + + private RdToElanOpEntry getRdToElanOpEntry(DataBroker broker, String rd, String subnetIp) { + InstanceIdentifier id = getRdToElanOpEntryDataPath(rd,subnetIp); + Optional sn = read(broker, LogicalDatastoreType.OPERATIONAL, id); + if(sn.isPresent()) { + return sn.get(); + } + return null; + } + + private InstanceIdentifier getRdToElanOpEntryDataPath(String rd, String subnetIp) { + return InstanceIdentifier.builder(RdToElanOp.class).child(RdToElanOpEntry.class, + new RdToElanOpEntryKey(rd,subnetIp)).build(); + } + private Optional read(DataBroker broker, LogicalDatastoreType datastoreType, + InstanceIdentifier path) { + + ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); + + Optional result = Optional.absent(); + try { + result = tx.read(datastoreType, path).get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return result; + } + + private void makeSubnetRouteFlow(BigInteger dpnId) { + //Ask Vivek cookie + final BigInteger COOKIE_TABLE_MISS = new BigInteger("8000004", 16); + List actionsInfos = new ArrayList(); + List instructions = new ArrayList(); + actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[]{})); + instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos)); + List matches = new ArrayList(); + String flowRef = getFlowRef(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, NwConstants.TABLE_MISS_FLOW); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, flowRef, + NwConstants.TABLE_MISS_PRIORITY, "Subnet Route Table Miss", 0, 0, COOKIE_TABLE_MISS, matches, instructions); + + LOG.debug("Invoking MDSAL to install Table Miss Entries"); + mdsalManager.syncInstallFlow(flowEntity,1); + } + + private Collection getDpnsForVpn(VpnInstanceOpDataEntry vpnInstance) { + Collection dpns = new HashSet<>(); + for(VpnToDpnList dpn : vpnInstance.getVpnToDpnList()) { + dpns.add(dpn.getDpnId()); + } + + return dpns; + } + public BigInteger createLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) { BigInteger localDpnId = BigInteger.ZERO; Prefixes localNextHopInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix()); @@ -212,18 +292,26 @@ public class FibManager extends AbstractDataChangeListener implements } if(localNextHopInfo != null) { - localDpnId = localNextHopInfo.getDpnId(); - long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP); - List actionInfos = new ArrayList(); + localDpnId = localNextHopInfo.getDpnId(); + long groupId = nextHopManager.createLocalNextHop(vpnId, localDpnId, localNextHopInfo.getVpnInterfaceName(), localNextHopIP); + + List actionsInfos = new ArrayList(); + List instructions = new ArrayList(); - actionInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)})); + actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId)})); + instructions.add(new InstructionInfo(InstructionType.write_actions,actionsInfos)); + makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW); - makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW); - makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), groupId, vrfEntry.getNextHopAddress(), NwConstants.ADD_FLOW); + actionsInfos=new ArrayList();; + instructions=new ArrayList(); + actionsInfos.add(new ActionInfo(ActionType.pop_mpls, new String[]{})); + actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId) })); + instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos)); + makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), instructions, vrfEntry.getNextHopAddress(), NwConstants.ADD_FLOW); - LOG.debug("Installing tunnel table entry on dpn {} for interface {} with label {}", - localDpnId, localNextHopInfo.getVpnInterfaceName(), vrfEntry.getLabel()); - makeTunnelTableEntry(localDpnId, vrfEntry.getLabel(), groupId); + LOG.debug("Installing tunnel table entry on dpn {} for interface {} with label {}", + localDpnId, localNextHopInfo.getVpnInterfaceName(), vrfEntry.getLabel()); + makeTunnelTableEntry(localDpnId, vrfEntry.getLabel(), groupId); } return localDpnId; @@ -284,7 +372,7 @@ public class FibManager extends AbstractDataChangeListener implements //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); if (extra_route != null) { - localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp()); + localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp() + "/32"); localNextHopIP = extra_route.getNexthopIp() + "/32"; isExtraRoute = true; } @@ -294,17 +382,12 @@ public class FibManager extends AbstractDataChangeListener implements if(localNextHopInfo != null) { localDpnId = localNextHopInfo.getDpnId(); Prefixes prefix = getPrefixToInterface(vpnId, isExtraRoute ? localNextHopIP : vrfEntry.getDestPrefix()); - Optional opStateData = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, - FibUtil.getVpnInterfaceOpStateIdentifier(prefix.getVpnInterfaceName())); - if(opStateData.isPresent() && !opStateData.get().isStateUp()) - { makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, null /* invalid */, NwConstants.DEL_FLOW); - makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), 0 /* invalid */, + makeLFibTableEntry(localDpnId, vrfEntry.getLabel(), null /* invalid */, vrfEntry.getNextHopAddress(), NwConstants.DEL_FLOW); removeTunnelTableEntry(localDpnId, vrfEntry.getLabel()); deleteLocalAdjacency(localDpnId, vpnId, localNextHopIP); - } } return localDpnId; } @@ -385,6 +468,8 @@ public class FibManager extends AbstractDataChangeListener implements tunnelId})); } actionInfos.addAll(nextHopManager.getEgressActionsForInterface(tunnelInterface)); + List instructions= new ArrayList(); + instructions.add(new InstructionInfo(InstructionType.write_actions, actionInfos)); /* List actionInfos = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry); if(actionInfos == null) { @@ -412,35 +497,34 @@ public class FibManager extends AbstractDataChangeListener implements MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID })); } **/ - makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, actionInfos, NwConstants.ADD_FLOW); - LOG.debug( - "Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId); - } - - private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) { - InstanceIdentifier id = FibUtil.getVpnToDpnListIdentifier(rd, dpnId); - Optional dpnInVpn = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); - if (dpnInVpn.isPresent()) { - List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); - org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces - currVpnInterface = new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder().setInterfaceName(intfName).build(); - - if (vpnInterfaces.remove(currVpnInterface)) { - if (vpnInterfaces.isEmpty()) { - //FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id); - LOG.trace("cleanUpOpDataForFib: cleanUpDpnForVpn: {}, {}", dpnId, vpnId); - cleanUpDpnForVpn(dpnId, vpnId, rd); - } else { - LOG.trace("cleanUpOpDataForFib: delete interface: {} on {}", intfName, dpnId); - FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child( - org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data - .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(intfName))); - } - } - } - } + makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW); + LOG.debug("Successfully added fib entry for " + vrfEntry.getDestPrefix() + " vpnId " + vpnId); + } + + private void delIntfFromDpnToVpnList(long vpnId, BigInteger dpnId, String intfName, String rd) { + InstanceIdentifier id = FibUtil.getVpnToDpnListIdentifier(rd, dpnId); + Optional dpnInVpn = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id); + if (dpnInVpn.isPresent()) { + List vpnInterfaces = dpnInVpn.get().getVpnInterfaces(); + org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces + currVpnInterface = new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder().setInterfaceName(intfName).build(); + + if (vpnInterfaces.remove(currVpnInterface)) { + if (vpnInterfaces.isEmpty()) { + LOG.trace("Last vpn interface {} on dpn {} for vpn {}. Clean up fib in dpn", intfName, dpnId, rd); + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id); + cleanUpDpnForVpn(dpnId, vpnId, rd); + } else { + LOG.trace("Delete vpn interface {} from dpn {} to vpn {} list.", intfName, dpnId, rd); + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child( + org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data + .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(intfName))); + } + } + } + } private void cleanUpOpDataForFib(Long vpnId, String rd, final VrfEntry vrfEntry) { /* Get interface info from prefix to interface mapping; @@ -452,13 +536,19 @@ public class FibManager extends AbstractDataChangeListener implements - vpn interface op DS */ Prefixes prefixInfo = getPrefixToInterface(vpnId, vrfEntry.getDestPrefix()); - boolean extra_route = false; + Extraroute extraRoute = null; if (prefixInfo == null) { - prefixInfo = getPrefixToInterface(vpnId, vrfEntry.getNextHopAddress() + "/32"); - extra_route = true; + extraRoute = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if(extraRoute != null) { + prefixInfo = getPrefixToInterface(vpnId, extraRoute.getNexthopIp() + "/32"); + //clean up the vpn to extra route entry in DS + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnToExtrarouteIdentifier(rd, vrfEntry.getDestPrefix())); + } } - if (prefixInfo == null) + if (prefixInfo == null) { + LOG.debug("Cleanup VPN Data Failed as unable to find prefix Info for " + vrfEntry.getDestPrefix()); return; //Don't have any info for this prefix (shouldn't happen); need to return + } String ifName = prefixInfo.getVpnInterfaceName(); Optional optAdjacencies = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName)); int numAdj = 0; @@ -467,19 +557,17 @@ public class FibManager extends AbstractDataChangeListener implements } LOG.trace("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId, vrfEntry.getDestPrefix()); //remove adjacency corr to prefix - FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix())); + if (numAdj > 1) { + FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, + FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix())); + } - if((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up - //clean up the vpn interface from DpnToVpn list - delIntfFromDpnToVpnList(vpnId, prefixInfo.getDpnId(), ifName, rd); - LOG.trace("cleanUpOpDataForFib: Delete prefix to interface and vpnInterface "); + if ((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up + //clean up the vpn interface from DpnToVpn list + LOG.trace("Clean up vpn interface {} from dpn {} to vpn {} list.", ifName, prefixInfo.getDpnId(), rd); FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, - FibUtil.getPrefixToInterfaceIdentifier( - vpnId, - (extra_route) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix())); - FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, - FibUtil.getVpnInterfaceIdentifier(ifName)); - } + FibUtil.getVpnInterfaceIdentifier(ifName)); + } } private void deleteFibEntries(final InstanceIdentifier identifier, @@ -491,6 +579,24 @@ public class FibManager extends AbstractDataChangeListener implements VpnInstanceOpDataEntry vpnInstance = getVpnInstance(vrfTableKey.getRouteDistinguisher()); Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available!"); Collection vpnToDpnList = vpnInstance.getVpnToDpnList(); + RdToElanOpEntry rdToElanOpEntry= getRdToElanOpEntry(broker,vrfTableKey.getRouteDistinguisher(), + vrfEntry.getDestPrefix()); + if (rdToElanOpEntry != null) { + if (vpnToDpnList!=null) { + for(VpnToDpnList curDpn : vpnToDpnList) { + makeConnectedRoute(curDpn.getDpnId(),vpnInstance.getVpnId(),vrfEntry,vrfTableKey + .getRouteDistinguisher(), null,NwConstants.DEL_FLOW); + makeLFibTableEntry(curDpn.getDpnId(),vrfEntry.getLabel(),null, + vrfEntry.getNextHopAddress(),NwConstants.DEL_FLOW); + // TODO DeleteTunnelTableEntry(); + } + } + //Delete rd-to-elan-op-entry + InstanceIdentifier id = getRdToElanOpEntryDataPath(vrfTableKey.getRouteDistinguisher(), + vrfEntry.getDestPrefix()); + MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,id); + return; + } BigInteger localDpnId = deleteLocalFibEntry(vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(), vrfEntry); if (vpnToDpnList != null) { @@ -510,17 +616,27 @@ public class FibManager extends AbstractDataChangeListener implements final VrfEntry vrfEntry) { LOG.debug("deleting route "+ vrfEntry.getDestPrefix() + " "+vpnId); String rd = vrfTableKey.getRouteDistinguisher(); - String egressInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry, rd); - if(egressInterface == null) { - LOG.error("Could not get nexthop group id for nexthop: {} in vpn {}", - vrfEntry.getNextHopAddress(), rd); - LOG.warn("Failed to delete Route: {} in vpn: {}", - vrfEntry.getDestPrefix(), rd); - return; + boolean isRemoteRoute = true; + if (localDpnId == null) { + // localDpnId is not known when clean up happens for last vm for a vpn on a dpn + VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix()); + if(localNextHopInfo == null) { + //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn + Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix()); + if (extra_route != null) { + localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp()); + } + } + if (localNextHopInfo != null) { + isRemoteRoute = (!remoteDpnId.equals(localNextHopInfo.getDpnId())); + } + } + if (isRemoteRoute) { + makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW); + LOG.debug("Successfully delete fib entry for "+ vrfEntry.getDestPrefix() + " vpnId "+vpnId); + } else{ + LOG.debug("Did not delete fib entry rd: {} =, prefix: {} as it is local to dpn {}", rd, vrfEntry.getDestPrefix(), remoteDpnId); } - - makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW); - LOG.debug("Successfully delete fib entry for "+ vrfEntry.getDestPrefix() + " vpnId "+vpnId); } private long getIpAddress(byte[] rawIpAddress) { @@ -529,8 +645,7 @@ public class FibManager extends AbstractDataChangeListener implements } private void makeConnectedRoute(BigInteger dpId, long vpnId, VrfEntry vrfEntry, String rd, - List actionInfos, int addOrRemove) { - LOG.trace("makeConnectedRoute: vrfEntry {}",vrfEntry); + List instructions, int addOrRemove) { LOG.trace("makeConnectedRoute: vrfEntry {}",vrfEntry); String values[] = vrfEntry.getDestPrefix().split("/"); String ipAddress = values[0]; int prefixLength = (values.length == 1) ? 0 : Integer.parseInt(values[1]); @@ -552,13 +667,8 @@ public class FibManager extends AbstractDataChangeListener implements new long[] { 0x0800L })); if(prefixLength != 0) { - matches.add(new MatchInfo(MatchFieldType.ipv4_dst, new long[] { - getIpAddress(destPrefix.getAddress()), prefixLength })); - } - - List instructions = new ArrayList(); - if(addOrRemove == NwConstants.ADD_FLOW) { - instructions.add(new InstructionInfo(InstructionType.write_actions, actionInfos)); + matches.add(new MatchInfo(MatchFieldType.ipv4_destination, new String[] { + destPrefix.getHostAddress(), Integer.toString(prefixLength)})); } String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, rd, destPrefix); @@ -582,19 +692,13 @@ public class FibManager extends AbstractDataChangeListener implements } } - private void makeLFibTableEntry(BigInteger dpId, long label, long groupId, + private void makeLFibTableEntry(BigInteger dpId, long label, List instructions, String nextHop, int addOrRemove) { List matches = new ArrayList(); matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] { 0x8847L })); matches.add(new MatchInfo(MatchFieldType.mpls_label, new String[]{Long.toString(label)})); - List instructions = new ArrayList(); - List actionsInfos = new ArrayList(); - actionsInfos.add(new ActionInfo(ActionType.pop_mpls, new String[]{})); - actionsInfos.add(new ActionInfo(ActionType.group, new String[] { String.valueOf(groupId) })); - instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos)); - // Install the flow entry in L3_LFIB_TABLE String flowRef = getFlowRef(dpId, NwConstants.L3_LFIB_TABLE, label, nextHop); @@ -614,7 +718,7 @@ public class FibManager extends AbstractDataChangeListener implements } else { mdsalManager.syncRemoveFlow(flowEntity, 1); } - LOG.debug("LFIB Entry for dpID {} : label : {} group {} modified successfully {}",dpId, label, groupId ); + LOG.debug("LFIB Entry for dpID {} : label : {} instructions {} modified successfully {}",dpId, label, instructions ); } private void deleteLocalAdjacency(final BigInteger dpId, final long vpnId, final String ipAddress) { @@ -629,12 +733,39 @@ public class FibManager extends AbstractDataChangeListener implements public void populateFibOnNewDpn(BigInteger dpnId, long vpnId, String rd) { LOG.trace("New dpn {} for vpn {} : populateFibOnNewDpn", dpnId, rd); InstanceIdentifier id = buildVrfId(rd); - Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - if(vrfTable.isPresent()) { - for(VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { - // Passing null as we don't know the dpn - // to which prefix is attached at this point - createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + RdToElanOpEntry rdToElanOpEntry = getRdToElanOpEntry(broker, rd, + vrfEntry.getDestPrefix()); + if (rdToElanOpEntry!= null) { + installSubnetRouteInFib(dpnId, rdToElanOpEntry, vpnId, vrfEntry); + continue; + } + // Passing null as we don't know the dpn + // to which prefix is attached at this point + createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } + } + } + + public void populateFibOnDpn(BigInteger dpnId, long vpnId, String rd, String nexthopIp) { + LOG.trace("dpn {} for vpn {}, nexthopIp {} : populateFibOnDpn", dpnId, rd, nexthopIp); + InstanceIdentifier id = buildVrfId(rd); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + if (nexthopIp == vrfEntry.getNextHopAddress()) { + createRemoteFibEntry(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } } } } @@ -642,12 +773,33 @@ public class FibManager extends AbstractDataChangeListener implements public void cleanUpDpnForVpn(BigInteger dpnId, long vpnId, String rd) { LOG.trace("Remove dpn {} for vpn {} : cleanUpDpnForVpn", dpnId, rd); InstanceIdentifier id = buildVrfId(rd); - Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); - if(vrfTable.isPresent()) { - for(VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { - // Passing null as we don't know the dpn - // to which prefix is attached at this point - deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } + } + } + + public void cleanUpDpnForVpn(BigInteger dpnId, long vpnId, String rd, String nexthopIp) { + LOG.trace("dpn {} for vpn {}, nexthopIp {} : cleanUpDpnForVpn", dpnId, rd, nexthopIp); + InstanceIdentifier id = buildVrfId(rd); + String lockOnDpnVpn = new String(dpnId.toString()+ vpnId); + synchronized (lockOnDpnVpn.intern()) { + Optional vrfTable = FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id); + if (vrfTable.isPresent()) { + for (VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) { + // Passing null as we don't know the dpn + // to which prefix is attached at this point + if (nexthopIp == vrfEntry.getNextHopAddress()) { + deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().getKey(), vrfEntry); + } + } } } } @@ -686,8 +838,8 @@ public class FibManager extends AbstractDataChangeListener implements adjacency = nextHopManager.getRemoteNextHopPointer(localDpnId, remoteDpnId, vpnId, - vrfEntry.getDestPrefix(), - (staticRoute == true) ? extra_route.getNexthopIp() : vrfEntry.getNextHopAddress()); + (staticRoute == true) ? extra_route.getNexthopIp() + "/32" : vrfEntry.getDestPrefix(), + vrfEntry.getNextHopAddress()); } catch (NullPointerException e) { LOG.trace("", e); } @@ -799,7 +951,11 @@ public class FibManager extends AbstractDataChangeListener implements instructions.add(new InstructionInfo(InstructionType.clear_actions)); // Instruction to goto L3 InterfaceTable - instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.LPORT_DISPATCHER_TABLE })); + List actionsInfos = new ArrayList (); + actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ + Short.toString(NwConstants.LPORT_DISPATCHER_TABLE)})); + instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos)); + //instructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.LPORT_DISPATCHER_TABLE })); FlowEntity flowEntityL3Intf = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_INTERFACE_TABLE, getFlowRef(dpnId, NwConstants.L3_INTERFACE_TABLE, NwConstants.TABLE_MISS_FLOW),