void writeConfTransTypeConfigDS();
String getReqTransType();
String getTransportTypeStr(String tunType);
- void handleRemoteRoute(boolean action, BigInteger localDpnId,
- BigInteger remoteDpnId, long vpnId,
- String rd, String destPrefix,
- String localNextHopIp,
- String remoteNextHopIP);
+ void manageRemoteRouteOnDPN(final boolean action,
+ BigInteger localDpnId,
+ long vpnId,
+ String rd,
+ String destPrefix,
+ String destTepIp);
void addOrUpdateFibEntry(DataBroker broker, String rd, String prefix, List<String> nextHopList,
int label, RouteOrigin origin, WriteTransaction writeConfigTxn);
}
@Override
- public void handleRemoteRoute(boolean action, BigInteger localDpnId, BigInteger remoteDpnId,
- long vpnId, String rd, String destPrefix, String localNextHopIp,
- String remoteNextHopIP) {
- vrfEntryListener.handleRemoteRoute(action, localDpnId, remoteDpnId, vpnId, rd, destPrefix,
- localNextHopIp, remoteNextHopIP);
+ public void manageRemoteRouteOnDPN(boolean action,
+ BigInteger DpnId,
+ long vpnId,
+ String rd,
+ String destPrefix,
+ String destTepIp) {
+ vrfEntryListener.manageRemoteRouteOnDPN(action, DpnId, vpnId,rd, destPrefix, destTepIp);
}
@Override
(updateNhList != null) && (!updateNhList.isEmpty()))) {
// TODO(vivek): Though ugly, Not handling this code now, as each
// tep add event will invoke flow addition
+ LOG.trace("Original VRF entry NH is null for destprefix {}. This event is IGNORED here.", update.getDestPrefix());
return;
}
// has nexthop empty'ed out, route needs to be removed from remote Dpns
if (((updateNhList == null) || (updateNhList.isEmpty()) &&
(origNhList != null) && (!origNhList.isEmpty()))) {
-
- final VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd);
- Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available " + vrfTableKey.getRouteDistinguisher());
- Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId() + " has null vpnId!");
-
- final Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
- final Long vpnId = vpnInstance.getVpnId();
-
- final List<BigInteger> localDpnIdList = getDpnIdForPrefix(dataBroker, vpnId, rd, update);
-
- if (vpnToDpnList != null) {
- DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB-" + rd.toString() + "-" + update.getDestPrefix(),
- new Callable<List<ListenableFuture<Void>>>() {
- @Override
- public List<ListenableFuture<Void>> call() throws Exception {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- for (VpnToDpnList vpnDpn : vpnToDpnList) {
- // delete subnet route on all dpns if nexthop for subnetroute changed from null
- // to a valid value.
- if (!localDpnIdList.contains(vpnDpn.getDpnId())) {
- deleteRemoteRoute(BigInteger.ZERO, vpnDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, update, tx);
- }
- }
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(tx.submit());
- return futures;
- }
- });
- }
+ LOG.trace("Original VRF entry had valid NH for destprefix {}. This event is IGNORED here.", update.getDestPrefix());
return;
}
}
rd, vrfEntry.getDestPrefix(), elanTag);
if (vpnToDpnList != null) {
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB"+rd.toString()+vrfEntry.getDestPrefix(),
+ dataStoreCoordinator.enqueueJob("FIB-"+ rd.toString() + "-" + vrfEntry.getDestPrefix(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
if (vpnToDpnList != null) {
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB"+rd.toString()+vrfEntry.getDestPrefix(),
+ dataStoreCoordinator.enqueueJob("FIB-"+ rd.toString() + "-" + vrfEntry.getDestPrefix(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
LOG.debug("Route with rd {} prefix {} label {} nexthop {} for vpn {} is an imported route. LFib and Terminating table entries will not be created.", rd, vrfEntry.getDestPrefix(), vrfEntry.getLabel(), vrfEntry.getNextHopAddressList(), vpnId);
}
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB"+vpnId.toString()+dpnId.toString()+vrfEntry.getDestPrefix(),
+ dataStoreCoordinator.enqueueJob("FIB-"+ vpnId.toString() + "-" + dpnId.toString() + "-" + vrfEntry.getDestPrefix(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
if (localNextHopInfo != null) {
final BigInteger dpnId = localNextHopInfo.getDpnId();;
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB"+vpnId.toString()+dpnId.toString()+vrfEntry.getDestPrefix(),
+ dataStoreCoordinator.enqueueJob("FIB-"+ vpnId.toString() + "-" + dpnId.toString() + "-" + vrfEntry.getDestPrefix(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
tx = dataBroker.newWriteOnlyTransaction();
}
String rd = vrfTableKey.getRouteDistinguisher();
- LOG.debug( "createremotefibentry: adding route {} for rd {} with transaction {}",
- vrfEntry.getDestPrefix(), rd, tx);
+ LOG.debug( "createremotefibentry: adding route {} for rd {} on remoteDpnId {}",
+ vrfEntry.getDestPrefix(), rd, remoteDpnId);
/********************************************/
List<AdjacencyResult> adjacencyResults = resolveAdjacency(remoteDpnId, vpnId, vrfEntry, rd);
rd, vrfEntry.getDestPrefix(), elanTag);
if (vpnToDpnList != null) {
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB" + rd.toString() + vrfEntry.getDestPrefix(),
+ dataStoreCoordinator.enqueueJob("FIB-" + rd.toString() + "-" + vrfEntry.getDestPrefix(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
vrfTableKey.getRouteDistinguisher(), vrfEntry);
if (vpnToDpnList != null) {
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob("FIB" + rd.toString() + vrfEntry.getDestPrefix(),
+ dataStoreCoordinator.enqueueJob("FIB-" + rd.toString() + "-" + vrfEntry.getDestPrefix(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
}
}
- public void handleRemoteRoute(final boolean action, final BigInteger localDpnId, final BigInteger remoteDpnId,
- final long vpnId, final String rd, final String destPrefix ,
- final String localNextHopIP, final String remoteNextHopIp) {
-
+ public void manageRemoteRouteOnDPN(final boolean action,
+ final BigInteger localDpnId,
+ final long vpnId,
+ final String rd,
+ final String destPrefix,
+ final String destTepIp) {
final VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd);
if (vpnInstance == null) {
- LOG.error("VpnInstance for rd {} not present for handleRemoteRoute for prefix {}", rd, destPrefix);
+ LOG.error("VpnInstance for rd {} not present for prefix {}", rd, destPrefix);
return;
}
-
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob( "FIB" + rd.toString()
- + "local dpid" + localDpnId
- + "remote dpid" + remoteDpnId
- + "vpnId" + vpnId
- + "localNHIp" + localNextHopIP
- + "remoteNHIp" + remoteNextHopIp,
+ dataStoreCoordinator.enqueueJob("FIB-" + vpnId + "-" + localDpnId.toString(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
VrfEntry vrfEntry = getVrfEntry(dataBroker, rd, destPrefix);
if (vrfEntry == null)
return futures;
- LOG.trace("handleRemoteRoute :: action {}, localDpnId {}, " +
- "remoteDpnId {} , vpnId {}, rd {}, destPfx {}",
- action, localDpnId, remoteDpnId, vpnId, rd, destPrefix);
+ LOG.trace("manageRemoteRouteOnDPN :: action {}, DpnId {}, vpnId {}, rd {}, destPfx {}",
+ action, localDpnId, vpnId, rd, destPrefix);
+ List<String> nhList = new ArrayList<String>();
+ List<String> nextHopAddressList = vrfEntry.getNextHopAddressList();
+ VrfEntry modVrfEntry;
+ if (nextHopAddressList == null || (nextHopAddressList.isEmpty())) {
+ nhList = Arrays.asList(destTepIp);
+ modVrfEntry = new VrfEntryBuilder(vrfEntry).setNextHopAddressList(nhList).build();
+ } else {
+ modVrfEntry = vrfEntry;
+ }
+
if (action == true) {
- LOG.trace("handleRemoteRoute updated(add) vrfEntry :: {}", vrfEntry);
- createRemoteFibEntry(remoteDpnId, vpnId, vrfTablesKey, vrfEntry, writeTransaction);
+ LOG.trace("manageRemoteRouteOnDPN updated(add) vrfEntry :: {}", modVrfEntry);
+ createRemoteFibEntry(localDpnId, vpnId, vrfTablesKey, modVrfEntry, writeTransaction);
} else {
- LOG.trace("handleRemoteRoute updated(remove) vrfEntry :: {}", vrfEntry);
- deleteRemoteRoute(null, remoteDpnId, vpnId, vrfTablesKey, vrfEntry, writeTransaction);
+ LOG.trace("manageRemoteRouteOnDPN updated(remove) vrfEntry :: {}", modVrfEntry);
+ deleteRemoteRoute(null, localDpnId, vpnId, vrfTablesKey, modVrfEntry, writeTransaction);
}
futures.add(writeTransaction.submit());
}
final Optional<VrfTables> vrfTable = FibUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (vrfTable.isPresent()) {
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob(" FIB-" + vpnId + "-" + dpnId.toString(),
+ dataStoreCoordinator.enqueueJob("FIB-" + vpnId + "-" + dpnId.toString(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
final Optional<VrfTables> vrfTable = FibUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
if (vrfTable.isPresent()) {
DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
- dataStoreCoordinator.enqueueJob(" FIB-" + vpnId + "-" + dpnId.toString(),
+ dataStoreCoordinator.enqueueJob("FIB-" + vpnId + "-" + dpnId.toString(),
new Callable<List<ListenableFuture<Void>>>() {
@Override
public List<ListenableFuture<Void>> call() throws Exception {
final VrfEntry vrfEntry, String rd) {
List<AdjacencyResult> adjacencyList = new ArrayList<>();
List<String> prefixIpList = new ArrayList<>();
- LOG.trace("resolveAdjacency called with remotedpid {}, vpnId{}, VrfEntry {}",
+ LOG.trace("resolveAdjacency called with remotedDpnId {}, vpnId{}, VrfEntry {}",
remoteDpnId, vpnId, vrfEntry);
try {
if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
leaf router-name { type string; }
}
}
-
- container dpn-to-vtep-map {
- config false;
- list dpn-to-vtep {
- key dpnId;
- leaf dpnId { type uint64;}
- leaf vtepip { type string; }
- }
- }
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnToVtepMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PortOpData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.to.vtep.map.DpnToVtep;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.to.vtep.map.DpnToVtepBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.to.vtep.map.DpnToVtepKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.port.op.data.PortOpDataEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
final BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
final String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue());
String destTepIp = String.valueOf(stateTunnelList.getDstInfo().getTepIp().getValue());
+ String rd;
+ BigInteger remoteDpnId = null;
+ boolean isTepDeletedOnDpn = false;
+
LOG.trace("Handle tunnel event for srcDpn {} SrcTepIp {} DestTepIp {} ", srcDpnId, srcTepIp, destTepIp);
int tunTypeVal = getTunnelType(stateTunnelList);
try {
if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
- // Maintain a Dpn-To-Vtep Op DS to avoid repeatedly calling updateVpnInterfaceOnTepAdd
- // method for every tunnel-add event sent by ITM when TEP is added.
- // Since TEP is common for all the (N-1) tunnels for a given Dpn , no need to update
- // the VpnInterface Adj NextHop for every tunnel event.
- InstanceIdentifier<DpnToVtep> DpnToVtepId =
- InstanceIdentifier.builder(DpnToVtepMap.class).child(DpnToVtep.class, new DpnToVtepKey(srcDpnId)).build();
- Optional<DpnToVtep> entry = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, DpnToVtepId);
-
- if (entry.isPresent()) {
- String vtepIp = entry.get().getVtepip();
- if (!vtepIp.equals(srcTepIp)) {
- // Entry found for DpnId. Unlikely to hit this code.
- LOG.error (" Tunnel ADD event already received for Dpn {} with a changed VTEP IP {}", srcDpnId, srcTepIp);
- return;
- }
- } else {
- LOG.trace(" Tunnel ADD event received for Dpn {} VTEP Ip {} ", srcDpnId, srcTepIp);
- // Entry not found. Create the entry for the DpnId
- DpnToVtepBuilder dpnToVtepBuilder = new DpnToVtepBuilder().setKey(new DpnToVtepKey(srcDpnId)).setVtepip(srcTepIp);
- VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, DpnToVtepId, dpnToVtepBuilder.build());
- }
+ LOG.trace(" Tunnel ADD event received for Dpn {} VTEP Ip {} ", srcDpnId, srcTepIp);
} else if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE) {
-
+ LOG.trace(" Tunnel DELETE event received for Dpn {} VTEP Ip {} ", srcDpnId, srcTepIp);
// When tunnel EP is deleted on a DPN , VPN gets two deletion event.
// One for a DPN on which tunnel EP was deleted and another for other-end DPN.
- // Handle only the DPN on which it was deleted , ignore other event.
- // DPN on which TEP is deleted , endpoint IP will be null.
+ // Update the adj for the vpninterfaces for a DPN on which TEP is deleted.
+ // Update the adj & VRF for the vpninterfaces for a DPN on which TEP is deleted.
+ // Dont update the adj & VRF for vpninterfaces for a DPN on which TEP is not deleted.
String endpointIpForDPN = null;
try {
endpointIpForDPN = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, srcDpnId);
endpointIpForDPN = null;
}
- if (endpointIpForDPN != null) {
- LOG.trace("Ignore Tunnel DELETE event received for Dpn {} VTEP Ip {}", srcDpnId, srcTepIp);
- return;
- }
-
- InstanceIdentifier<DpnToVtep> DpnToVtepId =
- InstanceIdentifier.builder(DpnToVtepMap.class).child(DpnToVtep.class, new DpnToVtepKey(srcDpnId)).build();
- Optional<DpnToVtep> entry = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, DpnToVtepId);
- if (entry.isPresent()) {
- String vtepIp = entry.get().getVtepip();
- if (vtepIp.equals(srcTepIp)) {
- LOG.trace(" Tunnel DELETE event received for Dpn {} VTEP Ip {} ", srcDpnId, srcTepIp);
- // Entry found for DpnId. Delete the entry.
- VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, DpnToVtepId);
- } else {
- // Unlikely to hit this condition
- LOG.error(" Tunnel DELETE event received for Dpn {} with different VTEP Ip {} than expected VTEP Ip {}", srcDpnId, srcTepIp, vtepIp);
- return;
- }
- } else {
- LOG.trace(" Tunnel DELETE event already received for Dpn {} VTEP Ip {} ", srcDpnId, srcTepIp);
+ if (endpointIpForDPN == null) {
+ LOG.trace("Tunnel TEP is deleted on Dpn {} VTEP Ip {}", srcDpnId, srcTepIp);
+ isTepDeletedOnDpn = true;
}
}
- // Get the list of VpnInterfaces from Intf Mgr for a given DPN.
+ // Get the list of VpnInterfaces from Intf Mgr for a SrcDPN on which TEP is added/deleted
Future<RpcResult<GetDpnInterfaceListOutput>> result;
- List<String> interfacelist = new ArrayList<>();
+ List<String> srcDpninterfacelist = new ArrayList<>();
+ List<String> destDpninterfacelist = new ArrayList<>();
try {
result = intfRpcService.getDpnInterfaceList(new GetDpnInterfaceListInputBuilder().setDpid(srcDpnId).build());
RpcResult<GetDpnInterfaceListOutput> rpcResult = result.get();
if (!rpcResult.isSuccessful()) {
LOG.warn("RPC Call to GetDpnInterfaceList for dpnid {} returned with Errors {}", srcDpnId, rpcResult.getErrors());
} else {
- interfacelist = rpcResult.getResult().getInterfacesList();
+ srcDpninterfacelist = rpcResult.getResult().getInterfacesList();
}
} catch (Exception e) {
LOG.warn("Exception {} when querying for GetDpnInterfaceList for dpnid {}, trace {}", e, srcDpnId, e.getStackTrace());
}
+ // Get the list of VpnInterfaces from Intf Mgr for a destDPN only for internal tunnel.
+ if (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
+ remoteDpnId = new BigInteger(stateTunnelList.getDstInfo().getTepDeviceId());
+ try {
+ result = intfRpcService.getDpnInterfaceList(new GetDpnInterfaceListInputBuilder().setDpid(remoteDpnId).build());
+ RpcResult<GetDpnInterfaceListOutput> rpcResult = result.get();
+ if (!rpcResult.isSuccessful()) {
+ LOG.warn("RPC Call to GetDpnInterfaceList for dpnid {} returned with Errors {}", srcDpnId, rpcResult.getErrors());
+ } else {
+ destDpninterfacelist = rpcResult.getResult().getInterfacesList();
+ }
+ } catch (Exception e) {
+ LOG.warn("Exception {} when querying for GetDpnInterfaceList for dpnid {}, trace {}", e, srcDpnId, e.getStackTrace());
+ }
+ }
+
/*
- * Iterate over the list of VpnInterface for a given Dpn and read the adj.
+ * Iterate over the list of VpnInterface for a SrcDpn on which TEP is added or deleted and read the adj.
* Update the adjacencies with the updated nexthop.
*/
- Iterator<String> interfacelistIter = interfacelist.iterator();
+ Iterator<String> interfacelistIter = srcDpninterfacelist.iterator();
String intfName = null;
List<Uuid> subnetList = new ArrayList<Uuid>();
Map<Long, String> vpnIdRdMap = new HashMap<Long, String>();
dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + intfName,
new UpdateVpnInterfaceOnTunnelEvent(dataBroker,
vpnInterfaceManager,
- tunTypeVal,
tunnelAction,
- action,
vpnInterface,
- stateTunnelList));
+ stateTunnelList,
+ isTepDeletedOnDpn));
// Populate the List of subnets
InstanceIdentifier<PortOpDataEntry> portOpIdentifier = InstanceIdentifier.builder(PortOpData.class).
//Populate the map for VpnId-to-Rd
long vpnId = VpnUtil.getVpnId(dataBroker, vpnInterface.getVpnInstanceName());
- String rd = VpnUtil.getVpnRd(dataBroker, vpnInterface.getVpnInstanceName());
+ rd = VpnUtil.getVpnRd(dataBroker, vpnInterface.getVpnInstanceName());
vpnIdRdMap.put(vpnId, rd);
}
}
+ /*
+ * Iterate over the list of VpnInterface for destDPN and get the prefix .
+ * Create remote rule for each of those prefix on srcDPN.
+ */
+ interfacelistIter = destDpninterfacelist.iterator();
+ while (interfacelistIter.hasNext()) {
+ intfName = interfacelistIter.next();
+ final VpnInterface vpnInterface = VpnUtil.getOperationalVpnInterface(dataBroker, intfName);
+ if (vpnInterface != null) {
+ List<Adjacency> adjList = vpnInterface.getAugmentation(Adjacencies.class).getAdjacency();
+ String prefix = null;
+ long vpnId = VpnUtil.getVpnId(dataBroker, vpnInterface.getVpnInstanceName());
+ if (vpnIdRdMap.containsKey(vpnId)) {
+ rd = vpnIdRdMap.get(vpnId);
+ LOG.trace(" Remote DpnId {} VpnId {} rd {} VpnInterface {}", remoteDpnId, vpnId, rd , vpnInterface);
+ for (Adjacency adj : adjList) {
+ prefix = adj.getIpAddress();
+ if ((tunnelAction == TunnelAction.TUNNEL_EP_ADD) &&
+ (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue())) {
+ fibManager.manageRemoteRouteOnDPN(true, srcDpnId, vpnId, rd, prefix, destTepIp);
+ }
+
+ if ((tunnelAction == TunnelAction.TUNNEL_EP_DELETE) &&
+ (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue())) {
+ fibManager.manageRemoteRouteOnDPN(false, srcDpnId, vpnId, rd, prefix, destTepIp);
+ }
+ }
+ }
+ }
+ }
+
//Iterate over the VpnId-to-Rd map.
Iterator<Map.Entry<Long, String>> entries = vpnIdRdMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Long, String> entry = entries.next();
Long vpnId = entry.getKey();
- String rd = entry.getValue();
- if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
- if(tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
- fibManager.populateInternalRoutesOnDpn(srcDpnId, vpnId, rd, srcTepIp, destTepIp);
- }
- if(tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue()) {
- fibManager.populateExternalRoutesOnDpn(srcDpnId, vpnId, rd, srcTepIp, destTepIp);
- }
- } else if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE) {
- if(tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
- fibManager.cleanUpInternalRoutesOnDpn(srcDpnId, vpnId, rd, srcTepIp, destTepIp);
- }
- if(tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue()) {
- fibManager.cleanUpExternalRoutesOnDpn(srcDpnId, vpnId, rd, srcTepIp, destTepIp);
- }
+ rd = entry.getValue();
+ if ((tunnelAction == TunnelAction.TUNNEL_EP_ADD) &&
+ (tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue())) {
+ fibManager.populateExternalRoutesOnDpn(srcDpnId, vpnId, rd, srcTepIp, destTepIp);
+ } else if ((tunnelAction == TunnelAction.TUNNEL_EP_DELETE) &&
+ (tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue())) {
+ fibManager.cleanUpExternalRoutesOnDpn(srcDpnId, vpnId, rd, srcTepIp, destTepIp);
}
}
- if (action == UpdateRouteAction.ADVERTISE_ROUTE) {
+ if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
for (Uuid subnetId : subnetList) {
// Populate the List of subnets
vpnSubnetRouteHandler.updateSubnetRouteOnTunnelUpEvent(subnetId, srcDpnId);
}
}
- if (action == UpdateRouteAction.WITHDRAW_ROUTE) {
+ if ((tunnelAction == TunnelAction.TUNNEL_EP_DELETE) && isTepDeletedOnDpn) {
for (Uuid subnetId : subnetList) {
// Populate the List of subnets
vpnSubnetRouteHandler.updateSubnetRouteOnTunnelDownEvent(subnetId, srcDpnId);
private class UpdateVpnInterfaceOnTunnelEvent implements Callable {
- private int tunTypeVal;
private VpnInterface vpnInterface;
private StateTunnelList stateTunnelList;
- private TunnelInterfaceStateListener.UpdateRouteAction action;
private VpnInterfaceManager vpnInterfaceManager;
private DataBroker broker;
private TunnelAction tunnelAction;
+ private boolean isTepDeletedOnDpn;
UpdateVpnInterfaceOnTunnelEvent(DataBroker broker,
VpnInterfaceManager vpnInterfaceManager,
- int tunTypeVal,
TunnelAction tunnelAction,
- TunnelInterfaceStateListener.UpdateRouteAction action,
VpnInterface vpnInterface,
- StateTunnelList stateTunnelList) {
+ StateTunnelList stateTunnelList,
+ boolean isTepDeletedOnDpn) {
this.broker = broker;
this.vpnInterfaceManager = vpnInterfaceManager;
- this.tunTypeVal = tunTypeVal;
this.stateTunnelList = stateTunnelList;
this.vpnInterface = vpnInterface;
- this.action = action;
this.tunnelAction = tunnelAction;
+ this.isTepDeletedOnDpn = isTepDeletedOnDpn;
}
public List<ListenableFuture<Void>> call() throws Exception {
- WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction();
- WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction();
if(tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
- vpnInterfaceManager.updateVpnInterfaceOnTepAdd(vpnInterface, stateTunnelList, writeOperTxn, writeConfigTxn);
+ vpnInterfaceManager.updateVpnInterfaceOnTepAdd(vpnInterface, stateTunnelList);
}
- if(tunnelAction == TunnelAction.TUNNEL_EP_DELETE) {
- vpnInterfaceManager.updateVpnInterfaceOnTepDelete(vpnInterface, writeOperTxn, writeConfigTxn);
+ if((tunnelAction == TunnelAction.TUNNEL_EP_DELETE) && isTepDeletedOnDpn) {
+ vpnInterfaceManager.updateVpnInterfaceOnTepDelete(vpnInterface, stateTunnelList);
}
- List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
- futures.add(writeOperTxn.submit());
- futures.add(writeConfigTxn.submit());
- return futures;
+ return null;
}
}
}
public void updateVpnInterfaceOnTepAdd(VpnInterface vpnInterface,
- StateTunnelList stateTunnelList,
- WriteTransaction writeOperTxn,
- WriteTransaction writeCfgTxn) {
+ StateTunnelList stateTunnelList) {
String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue());
+ BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
String rd = getRouteDistinguisher(vpnInterface.getVpnInstanceName());
rd = (rd != null) ? rd : vpnInterface.getVpnInstanceName();
Adjacencies adjacencies = vpnInterface.getAugmentation(Adjacencies.class);
long label = 0;
List<String> nhList = new ArrayList<String>();
boolean nextHopAdded = false;
+ long vpnId = VpnUtil.getVpnId(dataBroker, vpnInterface.getVpnInstanceName());
if (adjList != null) {
List<Adjacency> value = new ArrayList<>();
List<String> nextHopList = adj.getNextHopIpList();
// Incase nextHopList contains some other TEP IP ,
// it needs to be updated with new one.
- if ((nextHopList != null) && (!nextHopList.isEmpty())) {
- if (!nextHopList.get(0).equalsIgnoreCase((srcTepIp))) {
- nextHopAdded = true;
- }
- }
// Incase nextHopIp was null at the time of VpnInterface creation,
// it needs to be updated with new one.
- if((nextHopList == null) || (nextHopList.isEmpty())) {
+ if (nextHopList != null && (!nextHopList.isEmpty()) &&
+ (nextHopList.get(0).equalsIgnoreCase(srcTepIp))){
+ /* everything right already */
+ } else {
+ /* update the adjacency here itself */
nextHopAdded = true;
+ LOG.trace("NextHopList to be updated {}",nhList);
+ // Update the VpnInterface Op DS with new nextHopList
+ value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
+ Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
+ VpnInterface opInterface = new VpnInterfaceBuilder(vpnInterface).setKey(new VpnInterfaceKey(vpnInterface.getName()))
+ .addAugmentation(Adjacencies.class, aug).build();
+ InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName());
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface);
}
}
+
if (nextHopAdded) {
- LOG.trace("NextHopList to be updated {}",nhList);
- // Update the VpnInterface Op DS with new nextHopList
- value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
- Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
- VpnInterface opInterface = new VpnInterfaceBuilder(vpnInterface).setKey(new VpnInterfaceKey(vpnInterface.getName()))
- .addAugmentation(Adjacencies.class, aug).build();
- InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName());
- writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface, true);
+ LOG.info("Updating label mapper : label {} dpn {} prefix {} nexthoplist {} vpnid {} rd {}", label, srcDpnId , prefix, nhList, vpnId, rd);
+ updateLabelMapper(label, nhList);
// Update the VRF entry with nextHop
- fibManager.updateFibEntry(dataBroker, rd, prefix, nhList, writeCfgTxn);
-
+ fibManager.updateFibEntry(dataBroker, rd, prefix, nhList, null);
+
+ //Get the list of VPN's importing this route(prefix) .
+ // Then update the VRF entry with nhList
+ List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnInterface.getVpnInstanceName());
+ for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
+ String vpnRd = vpn.getVrfId();
+ if (vpnRd != null) {
+ LOG.debug("Exporting route with rd {} prefix {} nhList {} label {} to VPN {}", vpnRd, prefix, nhList, label, vpn);
+ fibManager.updateFibEntry(dataBroker, vpnRd, prefix, nhList, null);
+ }
+ }
// Advertise the prefix to BGP only for external vpn
// since there is a nexthop change.
try {
- if (rd != null) {
+ if (!rd.equalsIgnoreCase(vpnInterface.getVpnInstanceName())) {
bgpManager.advertisePrefix(rd, prefix, nhList, (int)label);
}
} catch (Exception ex) {
}
public void updateVpnInterfaceOnTepDelete(VpnInterface vpnInterface,
- WriteTransaction writeOperTxn,
- WriteTransaction writeCfgTxn) {
+ StateTunnelList stateTunnelList) {
String rd = getRouteDistinguisher(vpnInterface.getVpnInstanceName());
rd = (rd != null) ? rd : vpnInterface.getVpnInstanceName();
long label = 0;
List<String> nhList = new ArrayList<String>();
boolean isNextHopRemoveReqd = false;
+ BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
+ long vpnId = VpnUtil.getVpnId(dataBroker, vpnInterface.getVpnInstanceName());
if (adjList != null) {
List<Adjacency> value = new ArrayList<>();
// If nextHopList is already cleaned , no need to modify again
if((nextHopList != null) & (!nextHopList.isEmpty())) {
isNextHopRemoveReqd = true;
- } else if ((nextHopList == null) || (nextHopList.isEmpty())){
- LOG.trace("NextHopList is already cleared for interface {} ", vpnInterface);
- isNextHopRemoveReqd = false;
+ value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
+ Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
+
+ VpnInterface opInterface = new VpnInterfaceBuilder(vpnInterface).setKey(new VpnInterfaceKey(vpnInterface.getName()))
+ .addAugmentation(Adjacencies.class, aug).build();
+ InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName());
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface);
}
}
if(isNextHopRemoveReqd) {
- value.add(new AdjacencyBuilder(adj).setNextHopIpList(nhList).build());
- Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
-
- VpnInterface opInterface = new VpnInterfaceBuilder(vpnInterface).setKey(new VpnInterfaceKey(vpnInterface.getName()))
- .addAugmentation(Adjacencies.class, aug).build();
- InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName());
- writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface, true);
+ LOG.info("Updating label mapper : label {} dpn {} prefix {} nexthoplist {} vpnid {} rd {}", label, srcDpnId , prefix, nhList, vpnId, rd);
+ updateLabelMapper(label, nhList);
// Update the VRF entry with emtpy nextHop
- fibManager.updateFibEntry(dataBroker, rd, prefix, new ArrayList<String>() /* empty */, writeCfgTxn);
+ fibManager.updateFibEntry(dataBroker, rd, prefix, new ArrayList<String>() /* empty */, null);
+
+ //Get the list of VPN's importing this route(prefix) .
+ // Then update the VRF entry with nhList
+ List<VpnInstanceOpDataEntry> vpnsToImportRoute = getVpnsImportingMyRoute(vpnInterface.getVpnInstanceName());
+ for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
+ String vpnRd = vpn.getVrfId();
+ if (vpnRd != null) {
+ LOG.debug("Exporting route with rd {} prefix {} nhList {} label {} to VPN {}", vpnRd, prefix, nhList, label, vpn);
+ fibManager.updateFibEntry(dataBroker, vpnRd, prefix, nhList, null);
+ }
+ }
// Withdraw prefix from BGP only for external vpn.
try {
- if (rd != null) {
+ if (!rd.equalsIgnoreCase(vpnInterface.getVpnInstanceName())) {
bgpManager.withdrawPrefix(rd, prefix);
}
} catch (Exception ex) {
}
}
+ private void updateLabelMapper(Long label, List<String> nextHopIpList) {
+ Preconditions.checkNotNull(label, "label cannot be null or empty!");
+
+ InstanceIdentifier<LabelRouteInfo> lriIid = InstanceIdentifier.builder(LabelRouteMap.class)
+ .child(LabelRouteInfo.class, new LabelRouteInfoKey((long)label)).build();
+ Optional<LabelRouteInfo> opResult = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, lriIid);
+ if (opResult.isPresent()) {
+ LabelRouteInfo labelRouteInfo = new LabelRouteInfoBuilder(opResult.get()).setNextHopIpList(nextHopIpList).build();
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, lriIid, labelRouteInfo);
+ }
+ }
+
public void addSubnetRouteFibEntryToDS(String rd, String vpnName, String prefix, String nextHop, int label,
long elantag, BigInteger dpnId, WriteTransaction writeTxn) {
SubnetRoute route = new SubnetRouteBuilder().setElantag(elantag).build();
String vpnName = notification.getVpnName();
String subnetIp = notification.getSubnetIp();
Long elanTag = notification.getElanTag();
+ boolean isRouteAdvertised = false;
Preconditions.checkNotNull(subnetId, "SubnetId cannot be null or empty!");
Preconditions.checkNotNull(subnetIp, "SubnetPrefix cannot be null or empty!");
logger.error("Unable to fetch label from Id Manager. Bailing out of handling addition of subnet {} to vpn {}", subnetIp, vpnName);
return;
}
- addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
- subOpBuilder.setRouteAdvState(TaskState.Done);
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+ if (isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ } else {
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
} catch (Exception ex) {
logger.error("onSubnetAddedToVpn: FIB rules and Advertising nhDpnId " + nhDpnId +
" information for subnet " + subnetId.getValue() + " to BGP failed {}", ex);
public void onPortAddedToSubnet(PortAddedToSubnet notification) {
Uuid subnetId = notification.getSubnetId();
Uuid portId = notification.getPortId();
+ boolean isRouteAdvertised = false;
logger.info("onPortAddedToSubnet: Port " + portId.getValue() + " being added to subnet " + subnetId.getValue());
//TODO(vivek): Change this to use more granularized lock at subnetId level
logger.error("Unable to fetch label from Id Manager. Bailing out of handling addition of port {} to subnet {} in vpn {}", portId.getValue(), subnetIp, vpnName);
return;
}
- addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
- subOpBuilder.setRouteAdvState(TaskState.Done);
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+ if (isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ } else {
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
} catch (Exception ex) {
logger.error("onPortAddedToSubnet: Advertising NextHopDPN "+ nhDpnId +
" information for subnet " + subnetId.getValue() + " to BGP failed {}", ex);
public void onPortRemovedFromSubnet(PortRemovedFromSubnet notification) {
Uuid subnetId = notification.getSubnetId();
Uuid portId = notification.getPortId();
+ boolean isRouteAdvertised = false;
logger.info("onPortRemovedFromSubnet: Port " + portId.getValue() + " being removed from subnet " + subnetId.getValue());
//TODO(vivek): Change this to use more granularized lock at subnetId level
logger.error("Unable to fetch label from Id Manager. Bailing out of handling removal of port {} from subnet {} in vpn {}", portId.getValue(), subnetIp, vpnName);
return;
}
- addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
- subOpBuilder.setRouteAdvState(TaskState.Done);
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+ if (isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ } else {
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
} catch (Exception ex) {
logger.error("onPortRemovedFromSubnet: Swapping Withdrawing NextHopDPN " + dpnId +
" information for subnet " + subnetId.getValue() +
logger.info("onInterfaceUp: Port " + intfName);
//TODO(vivek): Change this to use more granularized lock at subnetId level
SubnetToDpn subDpn = null;
+ boolean isRouteAdvertised = false;
PortOpDataEntry portOpEntry = subOpDpnManager.getPortOpDataEntry(intfName);
if (portOpEntry == null) {
logger.info("onInterfaceUp: Port " + intfName + "is part of a subnet not in VPN, ignoring");
logger.error("Unable to fetch label from Id Manager. Bailing out of handling interface up event for port {} for subnet {} in vpn {}", intfName, subnetIp, vpnName);
return;
}
- addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
- subOpBuilder.setRouteAdvState(TaskState.Done);
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+ if(isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ } else {
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
} catch (Exception ex) {
logger.error("onInterfaceUp: Advertising NextHopDPN " + nhDpnId + " information for subnet " +
subnetId.getValue() + " to BGP failed {}" + ex);
}
public void onInterfaceDown(final BigInteger dpnId, final String interfaceName) {
+ boolean isRouteAdvertised = false;
logger.info("onInterfaceDown: Port " + interfaceName);
//TODO(vivek): Change this to use more granularized lock at subnetId level
PortOpDataEntry portOpEntry = subOpDpnManager.getPortOpDataEntry(interfaceName);
logger.error("Unable to fetch label from Id Manager. Bailing out of handling interface down event for port {} in subnet {} for vpn {}", interfaceName, subnetIp, vpnName);
return;
}
- addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
- subOpBuilder.setRouteAdvState(TaskState.Done);
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+ if(isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ } else {
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
} catch (Exception ex) {
logger.error("onInterfaceDown: Swapping Withdrawing NextHopDPN " + dpnId + " information for subnet " +
subnetId.getValue() + " to BGP failed {}" + ex);
}
public void updateSubnetRouteOnTunnelUpEvent(Uuid subnetId, BigInteger dpnId) {
+ boolean isRouteAdvertised = false;
logger.info("updateSubnetRouteOnTunnelUpEvent: Subnet {} Dpn {}", subnetId.getValue(), dpnId.toString());
try {
VpnUtil.lockSubnet(lockManager, subnetId.getValue());
try {
subOpBuilder.setNhDpnId(dpnId);
int label = getLabel(rd, subnetIp);
- addSubnetRouteToFib(rd, subnetIp, dpnId, vpnName, elanTag, label, subnetId);
- //advertiseSubnetRouteToBgp(rd, subnetIp, dpnId, vpnName, elanTag, label);
- subOpBuilder.setRouteAdvState(TaskState.Done);
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, dpnId, vpnName, elanTag, label, subnetId);
+ if(isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ } else {
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
} catch(Exception ex) {
logger.error("updateSubnetRouteOnTunnelUpEvent: Advertising NextHopDPN " + dpnId + " information for subnet " +
subnetId.getValue() + " to BGP failed {}" + ex);
}
}
}
+ subOpEntry = subOpBuilder.build();
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
+ logger.info("updateSubnetRouteOnTunnelUpEvent: Updated subnetopdataentry to OP Datastore tunnel up on dpn {} for subnet {}",
+ dpnId.toString(), subnetId.getValue());
}
- subOpEntry = subOpBuilder.build();
- MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
- logger.info("updateSubnetRouteOnTunnelUpEvent: Updated subnetopdataentry to OP Datastore tunnel up on dpn {} for subnet {}",
- dpnId.toString(), subnetId.getValue());
} catch (Exception ex) {
logger.error("Creation of SubnetOpDataEntry for subnet " +
subnetId.getValue() + " failed {}" + ex);
return;
}
SubnetOpDataEntry subOpEntry = null;
- List<SubnetToDpn> subDpnList = null;
SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(optionalSubs.get());
- String rd = subOpBuilder.getVrfId();
- String subnetIp = subOpBuilder.getSubnetCidr();
- String vpnName = subOpBuilder.getVpnName();
- long elanTag = subOpBuilder.getElanTag();
BigInteger nhDpnId = subOpBuilder.getNhDpnId();
if ((nhDpnId != null) && (nhDpnId.equals(dpnId))) {
- subDpnList = subOpBuilder.getSubnetToDpn();
- List<BigInteger> dpnIdList = new ArrayList<BigInteger>();
-
- Iterator<SubnetToDpn> subNetIt = subDpnList.iterator();
- while (subNetIt.hasNext()) {
- SubnetToDpn subnetToDpn = subNetIt.next();
- if (!subnetToDpn.getDpnId().equals(dpnId)) {
- dpnIdList.add(subnetToDpn.getDpnId());
- }
- }
- if (dpnIdList.isEmpty()) {
- subOpBuilder.setNhDpnId(null);
- try {
- // Withdraw route from BGP for this subnet
- deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
- //withdrawSubnetRoutefromBgp(rd, subnetIp);
- subOpBuilder.setRouteAdvState(TaskState.Na);
- } catch (Exception ex) {
- logger.error("updateSubnetRouteOnTunnelDownEvent: Withdrawing NextHopDPN " + dpnId.toString() + " information for subnet " +
- subnetId.getValue() + " from BGP failed {}" + ex);
- subOpBuilder.setRouteAdvState(TaskState.Pending);
- }
- } else {
- logger.debug("DpnList {} to choose the next bestfit dpn", dpnIdList);
- // current nhdpn not reachable from dc-gw, so we need to swap the NHDpnId
- nhDpnId = dpnIdList.get(0);
- subOpBuilder.setNhDpnId(nhDpnId);
- logger.debug("updateSubnetRouteOnTunnelDownEvent: Swapping the Designated DPN to " + nhDpnId.toString() + " for subnet " + subnetId.getValue());
- try {
- //update the VRF entry for the subnetroute.
- int label = getLabel(rd, subnetIp);
- addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
- subOpBuilder.setRouteAdvState(TaskState.Done);
- } catch (Exception ex) {
- logger.error("updateSubnetRouteOnTunnelDownEvent: Swapping Withdrawing NextHopDPN " + dpnId.toString() + " information for subnet " +
- subnetId.getValue() + " to BGP failed {}" + ex);
- subOpBuilder.setRouteAdvState(TaskState.Pending);
- }
- }
+ electNewDPNForSubNetRoute(subOpBuilder, dpnId, subnetId);
+ subOpEntry = subOpBuilder.build();
+ MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
+ logger.info("updateSubnetRouteOnTunnelDownEvent: Updated subnetopdataentry to OP Datastore tunnnel down on dpn {} for subnet {}",
+ dpnId.toString(), subnetId.getValue());
}
- subOpEntry = subOpBuilder.build();
- MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, subOpIdentifier, subOpEntry);
- logger.info("updateSubnetRouteOnTunnelDownEvent: Updated subnetopdataentry to OP Datastore tunnnel down on dpn {} for subnet {}",
- dpnId.toString(), subnetId.getValue());
} catch (Exception ex) {
logger.error("Updation of SubnetOpDataEntry for subnet " +
subnetId.getValue() + " failed {}" + ex);
}
}
- private void addSubnetRouteToFib(String rd, String subnetIp, BigInteger nhDpnId, String vpnName,
+ private boolean addSubnetRouteToFib(String rd, String subnetIp, BigInteger nhDpnId, String vpnName,
Long elanTag, int label, Uuid subnetId) throws Exception {
Preconditions.checkNotNull(rd, "RouteDistinguisher cannot be null or empty!");
Preconditions.checkNotNull(subnetIp, "SubnetRouteIp cannot be null or empty!");
nexthopIp = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, nhDpnId);
} catch (Exception e) {
logger.warn("Unable to find nexthopip for subnetroute subnetip {}", subnetIp);
- return;
+ return false;
}
if (nexthopIp != null) {
VpnUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(VpnUtil.getVpnId(dataBroker, vpnName), subnetIp), VpnUtil.getPrefixToInterface(nhDpnId, subnetId.getValue(), subnetIp));
vpnInterfaceManager.addSubnetRouteFibEntryToDS(rd, vpnName, subnetIp, nexthopIp, label, elanTag, nhDpnId, null);
try {
- // BGPManager (inside ODL) requires a withdraw followed by advertise
- // due to bugs with ClusterDataChangeListener used by BGPManager.
- //bgpManager.withdrawPrefix(rd, subnetIp);
+ //BGP manager will handle withdraw and advertise internally if prefix
+ //already exist
bgpManager.advertisePrefix(rd, subnetIp, Arrays.asList(nexthopIp), label);
} catch (Exception e) {
logger.error("Fail: Subnet route not advertised for rd {} subnetIp {}", rd, subnetIp, e);
}
} else {
logger.warn("The nexthopip is empty for subnetroute subnetip {}, ignoring fib route addition", subnetIp);
+ return false;
}
+ return true;
}
private int getLabel(String rd, String subnetIp) {
throw e;
}
}
+
+ private void electNewDPNForSubNetRoute(SubnetOpDataEntryBuilder subOpBuilder , BigInteger dpnId, Uuid subnetId) {
+ List<SubnetToDpn> subDpnList = null;
+ boolean isRouteAdvertised = false;
+ subDpnList = subOpBuilder.getSubnetToDpn();
+ String rd = subOpBuilder.getVrfId();
+ String subnetIp = subOpBuilder.getSubnetCidr();
+ String vpnName = subOpBuilder.getVpnName();
+ long elanTag = subOpBuilder.getElanTag();
+ BigInteger nhDpnId = null;
+ boolean isAlternateDpnSelected = false;
+ Iterator<SubnetToDpn> subNetIt = subDpnList.iterator();
+ int label = getLabel(rd, subnetIp);
+ while (subNetIt.hasNext()) {
+ SubnetToDpn subnetToDpn = subNetIt.next();
+ nhDpnId = subnetToDpn.getDpnId();
+ if (!nhDpnId.equals(dpnId)) {
+ try {
+ //update the VRF entry for the subnetroute.
+ isRouteAdvertised = addSubnetRouteToFib(rd, subnetIp, nhDpnId, vpnName, elanTag, label, subnetId);
+ if (isRouteAdvertised) {
+ subOpBuilder.setRouteAdvState(TaskState.Done);
+ subOpBuilder.setNhDpnId(nhDpnId);
+ isAlternateDpnSelected = true;
+ break;
+ }
+ } catch (Exception ex) {
+ logger.error("electNewDPNForSubNetRoute: Swapping and trying to configure NextHopDPN {} for subnet {} failed ex {}", dpnId.toString(), subnetId.getValue(), ex);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ }
+ }
+ }
+
+ //If no alternate Dpn is selected as nextHopDpn ,withdraw the subnetroute.
+ if (!isAlternateDpnSelected) {
+ logger.info("No alternate DPN available for subnet {}.Prefix withdrawn from BGP", subnetIp);
+ try {
+ // Withdraw route from BGP for this subnet
+ deleteSubnetRouteFromFib(rd, subnetIp, vpnName);
+ subOpBuilder.setNhDpnId(null);
+ subOpBuilder.setRouteAdvState(TaskState.Na);
+ } catch (Exception ex) {
+ logger.error("electNewDPNForSubNetRoute: Withdrawing NextHopDPN " + dpnId.toString() + " information for subnet " +
+ subnetId.getValue() + " from BGP failed {}" + ex);
+ subOpBuilder.setRouteAdvState(TaskState.Pending);
+ }
+ }
+ }
}