use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces in project netvirt by opendaylight.
the class VpnFootprintService method removeOrUpdateVpnToDpnListForIpAddress.
private void removeOrUpdateVpnToDpnListForIpAddress(Uint32 vpnId, String rd, Uint64 dpnId, ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
AtomicBoolean lastDpnOnVpn = new AtomicBoolean(false);
/* Starts synchronized block. This ensures only one reader/writer get access to vpn-dpn-list
* The future.get ensures that the write to the datastore is complete before leaving the synchronized block.
*/
// FIXME: separate this out somehow?
final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnName);
lock.lock();
try {
ListenableFuture<?> future = txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
Optional<VpnToDpnList> dpnInVpnOpt = tx.read(id).get();
if (!dpnInVpnOpt.isPresent()) {
LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} " + "rd={} id={}] and dpnId={}", vpnName, rd, id, dpnId);
return;
}
VpnToDpnList dpnInVpn = dpnInVpnOpt.get();
List<IpAddresses> ipAddresses = new ArrayList<>(dpnInVpn.nonnullIpAddresses().values());
if (ipAddresses == null) {
LOG.info("Could not find ipAddresses for DpnInVpn map for VPN=[name={} rd={} id={}] " + "and dpnId={}", vpnName, rd, id, dpnId);
return;
}
IpAddresses currIpAddress = new IpAddressesBuilder().withKey(new IpAddressesKey(ipAddressSourceValuePair.getValue())).setIpAddressSource(ipAddressSourceValuePair.getKey()).build();
if (ipAddresses.remove(currIpAddress)) {
if (ipAddresses.isEmpty()) {
Map<VpnInterfacesKey, VpnInterfaces> vpnInterfacesMap = dpnInVpn.nonnullVpnInterfaces();
VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(Collections.<IpAddresses>emptyList());
if (vpnInterfacesMap == null || vpnInterfacesMap.isEmpty()) {
dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
lastDpnOnVpn.set(true);
} else {
LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in " + "dpn {}", vpnName, dpnId);
}
tx.mergeParentStructurePut(id, dpnInVpnBuilder.build());
} else {
tx.delete(id.child(IpAddresses.class, new IpAddressesKey(ipAddressSourceValuePair.getValue())));
}
}
});
future.get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Error removing from dpnToVpnList for vpn {} Ipaddress {} dpn {}", vpnName, ipAddressSourceValuePair.getValue(), dpnId, e);
// TODO: Avoid this
throw new RuntimeException(e.getMessage(), e);
} finally {
lock.unlock();
}
if (lastDpnOnVpn.get()) {
LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd, new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false));
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces in project netvirt by opendaylight.
the class VpnFootprintService method removeOrUpdateVpnToDpnListForInterfaceName.
private void removeOrUpdateVpnToDpnListForInterfaceName(Uint32 vpnId, String rd, Uint64 dpnId, String intfName, String vpnName) {
AtomicBoolean lastDpnOnVpn = new AtomicBoolean(false);
/* Starts synchronized block. This ensures only one reader/writer get access to vpn-dpn-list
* The future.get ensures that the write to the datastore is complete before leaving the synchronized block.
*/
// FIXME: separate this out somehow?
final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnName);
lock.lock();
try {
try {
ListenableFuture<?> future = txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
Optional<VpnToDpnList> dpnInVpnOpt = tx.read(id).get();
if (!dpnInVpnOpt.isPresent()) {
LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={}" + " rd={} id={}] and dpnId={}", vpnName, rd, id, dpnId);
return;
}
VpnToDpnList dpnInVpn = dpnInVpnOpt.get();
List<VpnInterfaces> vpnInterfaces = new ArrayList<>(dpnInVpn.nonnullVpnInterfaces().values());
if (vpnInterfaces == null) {
LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and " + "dpnId={}", vpnName, rd, id, dpnId);
return;
}
VpnInterfaces currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
if (vpnInterfaces.remove(currVpnInterface)) {
if (vpnInterfaces.isEmpty()) {
Map<IpAddressesKey, IpAddresses> ipAddressesMap = dpnInVpn.nonnullIpAddresses();
VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(Collections.emptyMap());
if (ipAddressesMap == null || ipAddressesMap.isEmpty()) {
dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
lastDpnOnVpn.set(true);
} else {
LOG.error("removeOrUpdateVpnToDpnList: vpn interfaces are empty but ip addresses" + " are present for the vpn {} in dpn {} interface {}", vpnName, dpnId, intfName);
}
LOG.debug("removeOrUpdateVpnToDpnList: Removing vpn footprint for vpn {} vpnId {} " + "interface {}, on dpn {}", vpnName, vpnName, intfName, dpnId);
tx.mergeParentStructurePut(id, dpnInVpnBuilder.build());
} else {
tx.delete(id.child(VpnInterfaces.class, new VpnInterfacesKey(intfName)));
LOG.debug("removeOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} " + "interface {}, on dpn {}", vpnName, vpnName, intfName, dpnId);
}
}
});
future.get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn {} vpnId {}" + " interface {} dpn {}", vpnName, vpnId, intfName, dpnId, e);
throw new RuntimeException(e.getMessage(), e);
}
// Ends synchronized block
LOG.info("removeOrUpdateVpnToDpnList: Updated/Removed vpn footprint for vpn {} vpnId {} interface {}," + " on dpn {}", vpnName, vpnName, intfName, dpnId);
if (lastDpnOnVpn.get()) {
fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd, new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false));
LOG.info("removeOrUpdateVpnToDpnList: Sent cleanup event for dpn {} in VPN {} vpnId {} interface {}", dpnId, vpnName, vpnId, intfName);
}
} finally {
lock.unlock();
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces in project netvirt by opendaylight.
the class SubnetOpDpnManager method addInterfaceToDpn.
public SubnetToDpn addInterfaceToDpn(Uuid subnetId, Uint64 dpnId, String intfName) {
SubnetToDpn subDpn = null;
try {
// Create and add SubnetOpDataEntry object for this subnet to the SubnetOpData container
InstanceIdentifier<SubnetOpDataEntry> subOpIdentifier = InstanceIdentifier.builder(SubnetOpData.class).child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
// Please use a synchronize block here as we donot need a cluster-wide lock
InstanceIdentifier<SubnetToDpn> dpnOpId = subOpIdentifier.child(SubnetToDpn.class, new SubnetToDpnKey(dpnId));
Optional<SubnetToDpn> optionalSubDpn = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId);
if (!optionalSubDpn.isPresent()) {
// Create a new DPN Entry
subDpn = addDpnToSubnet(subnetId, dpnId);
} else {
subDpn = optionalSubDpn.get();
}
SubnetToDpnBuilder subDpnBuilder = new SubnetToDpnBuilder(subDpn);
Map<VpnInterfacesKey, VpnInterfaces> vpnInterfaceMap = new HashMap<>();
vpnInterfaceMap = subDpnBuilder.getVpnInterfaces() != null ? new HashMap<>(subDpnBuilder.getVpnInterfaces()) : vpnInterfaceMap;
VpnInterfaces vpnIntfs = new VpnInterfacesBuilder().withKey(new VpnInterfacesKey(intfName)).setInterfaceName(intfName).build();
vpnInterfaceMap.put(vpnIntfs.key(), vpnIntfs);
subDpnBuilder.setVpnInterfaces(vpnInterfaceMap);
subDpn = subDpnBuilder.build();
SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnOpId, subDpn, VpnUtil.SINGLE_TRANSACTION_BROKER_NO_RETRY);
LOG.info("addInterfaceToDpn: Created SubnetToDpn entry for subnet {} with DPNId {} intfName {}", subnetId.getValue(), dpnId, intfName);
} catch (TransactionCommitFailedException ex) {
LOG.error("addInterfaceToDpn: Addition of Interface {} for SubnetToDpn on subnet {} with DPN {} failed", intfName, subnetId.getValue(), dpnId, ex);
} catch (InterruptedException | ExecutionException e) {
LOG.error("addInterfaceToDpn: Failed to read data store for interface {} subnet {} dpn {}", intfName, subnetId, dpnId);
}
return subDpn;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces in project netvirt by opendaylight.
the class VpnInterfaceManager method updateVpnInterfacesForUnProcessAdjancencies.
public void updateVpnInterfacesForUnProcessAdjancencies(String vpnName) {
String primaryRd = vpnUtil.getVpnRd(vpnName);
VpnInstanceOpDataEntry vpnInstanceOpData = vpnUtil.getVpnInstanceOpData(primaryRd);
if (vpnInstanceOpData == null || vpnInstanceOpData.getVpnToDpnList() == null) {
return;
}
List<VpnToDpnList> vpnToDpnLists = new ArrayList<>(vpnInstanceOpData.getVpnToDpnList().values());
if (vpnToDpnLists == null || vpnToDpnLists.isEmpty()) {
return;
}
LOG.debug("Update the VpnInterfaces for Unprocessed Adjancencies for vpnName:{}", vpnName);
vpnToDpnLists.forEach(vpnToDpnList -> {
if (vpnToDpnList.getVpnInterfaces() == null) {
return;
}
vpnToDpnList.nonnullVpnInterfaces().values().forEach(vpnInterface -> {
try {
InstanceIdentifier<VpnInterfaceOpDataEntry> existingVpnInterfaceId = VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterface.getInterfaceName(), vpnName);
Optional<VpnInterfaceOpDataEntry> vpnInterfaceOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, existingVpnInterfaceId);
if (!vpnInterfaceOptional.isPresent()) {
return;
}
List<Adjacency> configVpnAdjacencies = vpnUtil.getAdjacenciesForVpnInterfaceFromConfig(vpnInterface.getInterfaceName());
if (configVpnAdjacencies == null) {
LOG.debug("There is no adjacency available for vpnInterface:{}", vpnInterface);
return;
}
List<Adjacency> operationVpnAdjacencies = new ArrayList<>(vpnInterfaceOptional.get().augmentation(AdjacenciesOp.class).nonnullAdjacency().values());
// Due to insufficient rds, some of the extra route wont get processed when it is added.
// The unprocessed adjacencies will be present in config vpn interface DS but will be missing
// in operational DS. These unprocessed adjacencies will be handled below.
// To obtain unprocessed adjacencies, filtering is done by which the missing adjacencies in
// operational DS are retrieved which is used to call addNewAdjToVpnInterface method.
configVpnAdjacencies.stream().filter(adjacency -> operationVpnAdjacencies.stream().noneMatch(operationalAdjacency -> Objects.equals(operationalAdjacency.getIpAddress(), adjacency.getIpAddress()))).forEach(adjacency -> {
LOG.debug("Processing the vpnInterface{} for the Ajacency:{}", vpnInterface, adjacency);
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getInterfaceName(), () -> {
// if the oper tx goes in
if (vpnUtil.isAdjacencyEligibleToVpn(adjacency, vpnName)) {
List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> {
// set of prefix used, as entry in prefix-to-interface datastore
// is prerequisite for refresh Fib to avoid race condition leading
// to missing remote next hop in bucket actions on bgp-vpn delete
Set<String> prefixListForRefreshFib = new HashSet<>();
ListenableFuture<?> configTxFuture = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> addNewAdjToVpnInterface(existingVpnInterfaceId, primaryRd, adjacency, vpnInterfaceOptional.get().getDpnId(), operTx, confTx, confTx, prefixListForRefreshFib));
Futures.addCallback(configTxFuture, new VpnInterfaceCallBackHandler(primaryRd, prefixListForRefreshFib), MoreExecutors.directExecutor());
futures.add(configTxFuture);
}));
return futures;
} else {
return emptyList();
}
});
});
} catch (InterruptedException | ExecutionException e) {
LOG.error("updateVpnInterfacesForUnProcessAdjancencies: Failed to read data store for vpn {} rd {}", vpnName, primaryRd);
}
});
});
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces in project netvirt by opendaylight.
the class TunnelInterfaceStateListener method handleTunnelEventForDPN.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private void handleTunnelEventForDPN(StateTunnelList stateTunnelList, TunnelAction tunnelAction) {
final Uint64 srcDpnId = stateTunnelList.getSrcInfo() != null ? Uint64.valueOf(stateTunnelList.getSrcInfo().getTepDeviceId()).intern() : Uint64.ZERO;
final String srcTepIp = stateTunnelList.getSrcInfo() != null ? stateTunnelList.getSrcInfo().getTepIp().stringValue() : "0";
String destTepIp = stateTunnelList.getDstInfo() != null ? stateTunnelList.getDstInfo().getTepIp().stringValue() : "0";
String rd;
Uint64 remoteDpnId = null;
boolean isTepDeletedOnDpn = false;
LOG.info("handleTunnelEventForDPN: Handle tunnel event for srcDpn {} SrcTepIp {} DestTepIp {} ", srcDpnId, srcTepIp, destTepIp);
int tunTypeVal = getTunnelType(stateTunnelList);
LOG.trace("handleTunnelEventForDPN: tunTypeVal is {}", tunTypeVal);
try {
if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
LOG.info("handleTunnelEventForDPN: Tunnel ADD event received for Dpn {} VTEP Ip {} destTepIp {}", srcDpnId, srcTepIp, destTepIp);
if (isTunnelInLogicalGroup(stateTunnelList)) {
return;
}
} else if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE) {
LOG.info("handleTunnelEventForDPN: Tunnel DELETE event received for Dpn {} VTEP Ip {} DestTepIp {}", srcDpnId, srcTepIp, destTepIp);
// 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.
// 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;
try {
endpointIpForDPN = InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, srcDpnId);
} catch (Exception e) {
LOG.error("handleTunnelEventForDPN: Unable to resolve endpoint IP for srcDpn {}", srcDpnId);
/* this dpn does not have the VTEP */
endpointIpForDPN = null;
}
if (endpointIpForDPN == null) {
LOG.info("handleTunnelEventForDPN: Tunnel TEP is deleted on Dpn {} VTEP Ip {} destTepIp {}", srcDpnId, srcTepIp, destTepIp);
isTepDeletedOnDpn = true;
}
}
// Get the list of VpnInterfaces from Intf Mgr for a SrcDPN on which TEP is added/deleted
Future<RpcResult<GetDpnInterfaceListOutput>> result;
List<Interfaces> srcDpninterfacelist = new ArrayList<>();
List<Interfaces> destDpninterfacelist = new ArrayList<>();
try {
result = intfRpcService.getDpnInterfaceList(new GetDpnInterfaceListInputBuilder().setDpid(srcDpnId).build());
RpcResult<GetDpnInterfaceListOutput> rpcResult = result.get();
if (!rpcResult.isSuccessful()) {
LOG.error("handleTunnelEventForDPN: RPC Call to GetDpnInterfaceList for srcDpnid {} srcTepIp {}" + " destTepIP {} returned with Errors {}", srcDpnId, srcTepIp, destTepIp, rpcResult.getErrors());
} else {
srcDpninterfacelist = rpcResult.getResult().nonnullInterfaces();
}
} catch (Exception e) {
LOG.error("handleTunnelEventForDPN: Exception when querying for GetDpnInterfaceList for srcDpnid {}" + " srcTepIp {} destTepIp {}", srcDpnId, srcTepIp, destTepIp, e);
}
// Get the list of VpnInterfaces from Intf Mgr for a destDPN only for internal tunnel.
if (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
remoteDpnId = Uint64.valueOf(stateTunnelList.getDstInfo() != null ? stateTunnelList.getDstInfo().getTepDeviceId() : "0").intern();
try {
result = intfRpcService.getDpnInterfaceList(new GetDpnInterfaceListInputBuilder().setDpid(remoteDpnId).build());
RpcResult<GetDpnInterfaceListOutput> rpcResult = result.get();
if (!rpcResult.isSuccessful()) {
LOG.error("handleTunnelEventForDPN: RPC Call to GetDpnInterfaceList for remoteDpnid {}" + " srcTepIP {} destTepIp {} returned with Errors {}", remoteDpnId, srcTepIp, destTepIp, rpcResult.getErrors());
} else {
destDpninterfacelist = rpcResult.getResult().nonnullInterfaces();
}
} catch (Exception e) {
LOG.error("handleTunnelEventForDPN: Exception when querying for GetDpnInterfaceList" + " for remoteDpnid {} srcTepIp {} destTepIp {}", remoteDpnId, srcTepIp, destTepIp, e);
}
}
/*
* 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.
*/
List<Uuid> subnetList = new ArrayList<>();
Map<Uint32, String> vpnIdRdMap = new HashMap<>();
Set<String> listVpnName = new HashSet<>();
for (Interfaces interfaces : srcDpninterfacelist) {
if (!L2vlan.class.equals(interfaces.getInterfaceType())) {
LOG.info("handleTunnelEventForDPN: Interface {} not of type L2Vlan", interfaces.getInterfaceName());
continue;
}
String intfName = interfaces.getInterfaceName();
VpnInterface vpnInterface = vpnUtil.getConfiguredVpnInterface(intfName);
if (vpnInterface != null) {
listVpnName.addAll(VpnHelper.getVpnInterfaceVpnInstanceNamesString(new ArrayList<VpnInstanceNames>(vpnInterface.nonnullVpnInstanceNames().values())));
handleTunnelEventForDPNVpn(stateTunnelList, vpnIdRdMap, tunnelAction, isTepDeletedOnDpn, subnetList, TunnelEventProcessingMethod.POPULATESUBNETS, vpnInterface);
}
}
/*
* Iterate over the list of VpnInterface for destDPN and get the prefix .
* Create remote rule for each of those prefix on srcDPN.
*/
for (Interfaces interfaces : destDpninterfacelist) {
if (!L2vlan.class.equals(interfaces.getInterfaceType())) {
LOG.info("handleTunnelEventForDPN: Interface {} not of type L2Vlan", interfaces.getInterfaceName());
continue;
}
String intfName = interfaces.getInterfaceName();
VpnInterface vpnInterface = vpnUtil.getConfiguredVpnInterface(intfName);
if (vpnInterface != null) {
handleTunnelEventForDPNVpn(stateTunnelList, vpnIdRdMap, tunnelAction, isTepDeletedOnDpn, subnetList, TunnelEventProcessingMethod.MANAGEREMOTEROUTES, vpnInterface);
}
}
// Iterate over the VpnId-to-Rd map.
for (Map.Entry<Uint32, String> entry : vpnIdRdMap.entrySet()) {
Uint32 vpnId = entry.getKey();
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 (listVpnName.size() >= 1) {
if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
for (Uuid subnetId : subnetList) {
// Populate the List of subnets
vpnSubnetRouteHandler.updateSubnetRouteOnTunnelUpEvent(subnetId, srcDpnId);
}
}
if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE && isTepDeletedOnDpn) {
for (Uuid subnetId : subnetList) {
// Populate the List of subnets
vpnSubnetRouteHandler.updateSubnetRouteOnTunnelDownEvent(subnetId, srcDpnId);
}
}
}
/*
* Program the BGP routes of all the VPNs which have footprint on the source DPN.
*
* DC-GW LB groups are programmed in DJC Jobs, so DJC with same key is used here to make sure
* groups are programmed first, then only BGP routes are programmed.
*/
jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(srcDpnId), () -> {
listVpnName.forEach(vpnName -> {
Uint32 vpnId = vpnUtil.getVpnId(vpnName);
final String vrfId = vpnIdRdMap.get(vpnId);
if ((tunnelAction == TunnelAction.TUNNEL_EP_ADD) && (tunTypeVal == VpnConstants.ITMTunnelLocType.External.getValue())) {
fibManager.populateExternalRoutesOnDpn(srcDpnId, vpnId, vrfId, srcTepIp, destTepIp);
}
});
return Collections.emptyList();
}, RETRY_COUNT);
} catch (RuntimeException e) {
LOG.error("handleTunnelEventForDpn: Unable to handle the tunnel event for srcDpnId {} srcTepIp {}" + " remoteDpnId {} destTepIp {}", srcDpnId, srcTepIp, remoteDpnId, destTepIp, e);
}
}
Aggregations