*/
package org.opendaylight.netvirt.vpnmanager;
+import static java.util.Collections.emptyList;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+import static org.opendaylight.netvirt.vpnmanager.VpnUtil.requireNonNullElse;
+
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TransactionAdapter;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.NWUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.label.route.map.LabelRouteInfoBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.label.route.map.LabelRouteInfoKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentrybase.RoutePaths;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
@Override
public void add(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface vpnInterface) {
- LOG.info("add: intfName {} onto vpnName {}",
- vpnInterface.getName(),
- VpnHelper.getVpnInterfaceVpnInstanceNamesString(vpnInterface.getVpnInstanceNames()));
+ LOG.trace("Received VpnInterface add event: vpnInterface={}", vpnInterface);
+ LOG.info("add: intfName {} onto vpnName {}", vpnInterface.getName(),
+ VpnHelper.getVpnInterfaceVpnInstanceNamesString(vpnInterface.getVpnInstanceNames()));
addVpnInterface(identifier, vpnInterface, null, null);
}
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private void addVpnInterface(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface vpnInterface,
- final List<Adjacency> oldAdjs, final List<Adjacency> newAdjs) {
- for (VpnInstanceNames vpnInterfaceVpnInstance : vpnInterface.getVpnInstanceNames()) {
+ final @Nullable List<Adjacency> oldAdjs, final @Nullable List<Adjacency> newAdjs) {
+ for (VpnInstanceNames vpnInterfaceVpnInstance : requireNonNullElse(vpnInterface.getVpnInstanceNames(),
+ Collections.<VpnInstanceNames>emptyList())) {
String vpnName = vpnInterfaceVpnInstance.getVpnName();
addVpnInterfaceCall(identifier, vpnInterface, oldAdjs, newAdjs, vpnName);
}
private void addVpnInterfaceCall(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface vpnInterface,
final List<Adjacency> oldAdjs, final List<Adjacency> newAdjs, String vpnName) {
- final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
if (!canHandleNewVpnInterface(identifier, vpnInterface, vpnName)) {
}
private void addVpnInterfaceToVpn(final InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier,
- final VpnInterface vpnInterface, final List<Adjacency> oldAdjs,
- final List<Adjacency> newAdjs,
+ final VpnInterface vpnInterface, final @Nullable List<Adjacency> oldAdjs,
+ final @Nullable List<Adjacency> newAdjs,
final InstanceIdentifier<VpnInterface> identifier, String vpnName) {
- final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
String primaryRd = vpnUtil.getPrimaryRd(vpnName);
if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
// TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
// (the inventory tx goes in last)
List<ListenableFuture<Void>> futures = new ArrayList<>();
- ListenableFuture<Void> confFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- confTx -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- operTx -> futures.add(
- txRunner.callWithNewWriteOnlyTransactionAndSubmit(invTx -> {
+ ListenableFuture<Void> confFuture =
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ confTx -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+ operTx -> futures.add(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, invTx -> {
LOG.info(
- "addVpnInterface: VPN Interface add event - intfName {} vpnName {}"
+ "addVpnInterface: VPN Interface add event - intfName {} vpnName {}"
+ " on dpn {}",
- vpnInterface.getName(), vpnName, vpnInterface.getDpnId());
+ vpnInterface.getName(), vpnName, vpnInterface.getDpnId());
processVpnInterfaceUp(dpnId, vpnInterface, primaryRd, ifIndex, false,
- confTx, operTx, invTx, interfaceState, vpnName);
+ confTx, operTx, invTx, interfaceState, vpnName);
if (oldAdjs != null && !oldAdjs.equals(newAdjs)) {
LOG.info("addVpnInterface: Adjacency changed upon VPNInterface {}"
- + " Update for swapping VPN {} case.", interfaceName, vpnName);
+ + " Update for swapping VPN {} case.", interfaceName, vpnName);
if (newAdjs != null) {
for (Adjacency adj : newAdjs) {
if (oldAdjs.contains(adj)) {
oldAdjs.remove(adj);
} else {
if (!isBgpVpnInternetVpn
- || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
+ || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
addNewAdjToVpnInterface(vpnInterfaceOpIdentifier,
- primaryRd, adj, dpnId, operTx, confTx);
+ primaryRd, adj, dpnId, operTx, confTx, invTx);
}
}
}
}
for (Adjacency adj : oldAdjs) {
if (!isBgpVpnInternetVpn
- || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
+ || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
- operTx, confTx);
+ operTx, confTx);
}
}
}
})))));
futures.add(confFuture);
Futures.addCallback(confFuture, new PostVpnInterfaceWorker(interfaceName, true, "Config"),
- MoreExecutors.directExecutor());
+ MoreExecutors.directExecutor());
LOG.info("addVpnInterface: Addition of interface {} in VPN {} on dpn {}"
- + " processed successfully", interfaceName, vpnName, dpnId);
+ + " processed successfully", interfaceName, vpnName, dpnId);
return futures;
});
} catch (NumberFormatException | IllegalStateException e) {
LOG.error("addVpnInterface: Unable to retrieve dpnId from interface operational data store for "
- + "interface {}. Interface addition on vpn {} failed", interfaceName,
- vpnName, e);
+ + "interface {}. Interface addition on vpn {} failed", interfaceName,
+ vpnName, e);
return;
}
} else if (Boolean.TRUE.equals(vpnInterface.isRouterInterface())) {
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getName(),
() -> {
- ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
- createFibEntryForRouterInterface(primaryRd, vpnInterface, interfaceName,
+ ListenableFuture<Void> future =
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
+ createFibEntryForRouterInterface(primaryRd, vpnInterface, interfaceName,
confTx, vpnName);
- LOG.info("addVpnInterface: Router interface {} for vpn {} on dpn {}", interfaceName,
+ LOG.info("addVpnInterface: Router interface {} for vpn {} on dpn {}", interfaceName,
vpnName, vpnInterface.getDpnId());
- });
+ });
ListenableFutures.addErrorLogging(future, LOG,
- "Error creating FIB entry for interface {} on VPN {}", vpnInterface.getName(), vpnName);
+ "Error creating FIB entry for interface {} on VPN {}", vpnInterface.getName(), vpnName);
return Collections.singletonList(future);
});
} else {
LOG.info("addVpnInterface: Handling addition of VPN interface {} on vpn {} skipped as interfaceState"
- + " is not available", interfaceName, vpnName);
+ + " is not available", interfaceName, vpnName);
}
} else {
LOG.error("addVpnInterface: Handling addition of VPN interface {} on vpn {} dpn {} skipped"
- + " as vpn is pending delete", interfaceName, vpnName,
- vpnInterface.getDpnId());
+ + " as vpn is pending delete", interfaceName, vpnName,
+ vpnInterface.getDpnId());
}
}
@SuppressFBWarnings({"UW_UNCOND_WAIT", "WA_NOT_IN_LOOP"})
protected void processVpnInterfaceUp(final BigInteger dpId, VpnInterface vpnInterface, final String primaryRd,
final int lportTag, boolean isInterfaceUp,
- WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTxn,
- WriteTransaction writeInvTxn,
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTxn,
+ TypedReadWriteTransaction<Configuration> writeInvTxn,
Interface interfaceState,
- final String vpnName) {
+ final String vpnName) throws ExecutionException, InterruptedException {
final String interfaceName = vpnInterface.getName();
Optional<VpnInterfaceOpDataEntry> optOpVpnInterface = vpnUtil.getVpnInterfaceOpDataEntry(interfaceName,
vpnName);
if (opVpnInterface != null) {
String opVpnName = opVpnInterface.getVpnInstanceName();
String primaryInterfaceIp = null;
- if (opVpnName.equals(vpnName)) {
+ if (Objects.equals(opVpnName, vpnName)) {
// Please check if the primary VRF Entry does not exist for VPNInterface
// If so, we have to process ADD, as this might be a DPN Restart with Remove and Add triggered
// back to back
LOG.trace("No config adjacencies present for vpninterface {}", vpnInterface);
return;
}
- List<Adjacency> adjacencies = optAdjacencies.get().getAdjacency();
+ List<Adjacency> adjacencies = requireNonNullElse(optAdjacencies.get().getAdjacency(), emptyList());
for (Adjacency adjacency : adjacencies) {
if (adjacency.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
continue;
continue;
}
addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adjacency,
- dpId, writeOperTxn, writeConfigTxn);
+ dpId, writeOperTxn, writeConfigTxn, writeInvTxn);
}
} catch (ReadFailedException e) {
LOG.error("processVpnInterfaceUp: Failed to read data store for interface {} vpn {} rd {} dpn {}",
LogicalDatastoreType.OPERATIONAL, path);
if (adjacencies.isPresent()) {
List<Adjacency> nextHops = adjacencies.get().getAdjacency();
- if (!nextHops.isEmpty()) {
+ if (nextHops != null && !nextHops.isEmpty()) {
LOG.debug("advertiseAdjacenciesForVpnToBgp: NextHops are {} for interface {} on dpn {} for vpn {}"
+ " rd {}", nextHops, interfaceName, dpnId, vpnName, rd);
VpnInstanceOpDataEntry vpnInstanceOpData = vpnUtil.getVpnInstanceOpData(rd);
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
private void withdrawAdjacenciesForVpnFromBgp(final InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
- String vpnName, String interfaceName, WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTx) {
+ String vpnName, String interfaceName, TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTx) {
//Read NextHops
InstanceIdentifier<AdjacenciesOp> path = identifier.augmentation(AdjacenciesOp.class);
String rd = vpnUtil.getVpnRd(interfaceName);
if (adjacencies.isPresent()) {
List<Adjacency> nextHops = adjacencies.get().getAdjacency();
- if (!nextHops.isEmpty()) {
+ if (nextHops != null && !nextHops.isEmpty()) {
LOG.trace("withdrawAdjacenciesForVpnFromBgp: NextHops are {} for interface {} in vpn {} rd {}",
nextHops, interfaceName, vpnName, rd);
for (Adjacency nextHop : nextHops) {
} else {
// Perform similar operation as interface delete event for extraroutes.
String allocatedRd = nextHop.getVrfId();
- for (String nh : nextHop.getNextHopIpList()) {
+ for (String nh : requireNonNullElse(nextHop.getNextHopIpList(),
+ Collections.<String>emptyList())) {
deleteExtraRouteFromCurrentAndImportingVpns(
vpnName, nextHop.getIpAddress(), nh, allocatedRd, interfaceName, writeConfigTxn,
writeOperTx);
@SuppressWarnings("checkstyle:IllegalCatch")
protected void processVpnInterfaceAdjacencies(BigInteger dpnId, final int lportTag, String vpnName,
String primaryRd, String interfaceName, final long vpnId,
- WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTxn,
- final WriteTransaction writeInvTxn,
- Interface interfaceState) {
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTxn,
+ TypedReadWriteTransaction<Configuration> writeInvTxn,
+ Interface interfaceState)
+ throws ExecutionException, InterruptedException {
InstanceIdentifier<VpnInterface> identifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
// Read NextHops
Optional<VpnInterface> vpnInteface = Optional.absent();
boolean isL3VpnOverVxLan = VpnUtil.isL3VpnOverVxLan(l3vni);
VrfEntry.EncapType encapType = isL3VpnOverVxLan ? VrfEntry.EncapType.Vxlan : VrfEntry.EncapType.Mplsgre;
VpnPopulator registeredPopulator = L3vpnRegistry.getRegisteredPopulator(encapType);
- List<Adjacency> nextHops = (adjacencies != null) ? adjacencies.getAdjacency() : Collections.emptyList();
+ List<Adjacency> nextHops = (adjacencies != null) ? adjacencies.getAdjacency() : emptyList();
List<Adjacency> value = new ArrayList<>();
for (Adjacency nextHop : nextHops) {
String rd = primaryRd;
? VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, intfnetworkUuid ,networkType,
segmentationId, prefixCue) :
VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, prefixCue);
- writeOperTxn.merge(
- LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getPrefixToInterfaceIdentifier(
+ writeOperTxn.merge(VpnUtil.getPrefixToInterfaceIdentifier(
vpnUtil.getVpnId(vpnName), prefix), prefixes, true);
final Uuid subnetId = nextHop.getSubnetId();
}
private void addVpnInterfaceToOperational(String vpnName, String interfaceName, BigInteger dpnId, AdjacenciesOp aug,
- long lportTag, String gwMac, WriteTransaction writeOperTxn) {
+ long lportTag, String gwMac,
+ TypedWriteTransaction<Operational> writeOperTxn) {
VpnInterfaceOpDataEntry opInterface =
VpnUtil.getVpnInterfaceOpDataEntry(interfaceName, vpnName, aug, dpnId, lportTag, gwMac);
InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId = VpnUtil
.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
- writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ writeOperTxn.put(interfaceId, opInterface, CREATE_MISSING_PARENTS);
LOG.info("addVpnInterfaceToOperational: Added VPN Interface {} on dpn {} vpn {} to operational datastore",
interfaceName, dpnId, vpnName);
}
@SuppressWarnings("checkstyle:IllegalCatch")
public void updateVpnInterfaceOnTepAdd(VpnInterfaceOpDataEntry vpnInterface,
StateTunnelList stateTunnelList,
- WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTxn) {
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTxn) {
String srcTepIp = stateTunnelList.getSrcInfo().getTepIp().stringValue();
BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
AdjacenciesOp adjacencies = vpnInterface.augmentation(AdjacenciesOp.class);
- List<Adjacency> adjList = adjacencies != null ? adjacencies.getAdjacency() : new ArrayList<>();
+ List<Adjacency> adjList =
+ adjacencies != null && adjacencies.getAdjacency() != null ? adjacencies.getAdjacency() : emptyList();
if (adjList.isEmpty()) {
LOG.trace("updateVpnInterfaceOnTepAdd: Adjacencies are empty for vpnInterface {} on dpn {}",
vpnInterface, srcDpnId);
List<String> nextHopList = adj.getNextHopIpList();
// If TEP is added , update the nexthop of primary adjacency.
// Secondary adj nexthop is already pointing to primary adj IP address.
- if (nextHopList != null && !nextHopList.isEmpty()) {
- /* everything right already */
- } else {
+ if (nextHopList == null || nextHopList.isEmpty()) {
isNextHopAddReqd = true;
}
vpnInterface.getVpnInstanceName(), vpnId, rd, vpnInterface.getName());
// Update the VRF entry with nextHop
fibManager.updateRoutePathForFibEntry(primaryRd, prefix, srcTepIp,
- label, true, writeConfigTxn);
+ label, true, TransactionAdapter.toWriteTransaction(writeConfigTxn));
//Get the list of VPN's importing this route(prefix) .
// Then update the VRF entry with nhList
String vpnRd = vpn.getVrfId();
if (vpnRd != null) {
fibManager.updateRoutePathForFibEntry(vpnRd, prefix,
- srcTepIp, label, true, writeConfigTxn);
+ srcTepIp, label, true, TransactionAdapter.toWriteTransaction(writeConfigTxn));
LOG.info("updateVpnInterfaceOnTepAdd: Exported route with rd {} prefix {} nhList {} label {}"
+ " interface {} dpn {} from vpn {} to VPN {} vpnRd {}", rd, prefix, nhList, label,
vpnInterface.getName(), srcDpnId, vpnName,
.addAugmentation(AdjacenciesOp.class, aug).build();
InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId =
VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterface.getName(), vpnName);
- writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ writeOperTxn.put(interfaceId, opInterface, CREATE_MISSING_PARENTS);
LOG.info("updateVpnInterfaceOnTepAdd: interface {} updated successully on tep add on dpn {} vpn {}",
vpnInterface.getName(), srcDpnId, vpnName);
@SuppressWarnings("checkstyle:IllegalCatch")
public void updateVpnInterfaceOnTepDelete(VpnInterfaceOpDataEntry vpnInterface,
StateTunnelList stateTunnelList,
- WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTxn) {
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTxn) {
AdjacenciesOp adjacencies = vpnInterface.augmentation(AdjacenciesOp.class);
List<Adjacency> adjList = adjacencies != null ? adjacencies.getAdjacency() : new ArrayList<>();
vpnId, rd, vpnInterface.getName());
// Update the VRF entry with removed nextHop
fibManager.updateRoutePathForFibEntry(primaryRd, prefix, srcTepIp,
- label, false, writeConfigTxn);
+ label, false, TransactionAdapter.toWriteTransaction(writeConfigTxn));
//Get the list of VPN's importing this route(prefix) .
// Then update the VRF entry with nhList
String vpnRd = vpn.getVrfId();
if (vpnRd != null) {
fibManager.updateRoutePathForFibEntry(vpnRd, prefix,
- srcTepIp, label, false, writeConfigTxn);
+ srcTepIp, label, false, TransactionAdapter.toWriteTransaction(writeConfigTxn));
LOG.info("updateVpnInterfaceOnTepDelete: Exported route with rd {} prefix {} nhList {}"
+ " label {} interface {} dpn {} from vpn {} to VPN {} vpnRd {}", rd, prefix,
nhList, label, vpnInterface.getName(), srcDpnId,
.addAugmentation(AdjacenciesOp.class, aug).build();
InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId =
VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterface.getName(), vpnName);
- writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface,
- WriteTransaction.CREATE_MISSING_PARENTS);
+ writeOperTxn.put(interfaceId, opInterface, CREATE_MISSING_PARENTS);
LOG.info("updateVpnInterfaceOnTepDelete: interface {} updated successully on tep delete on dpn {} vpn {}",
vpnInterface.getName(), srcDpnId, vpnName);
}
for (VpnInstanceOpDataEntry vpn : vpnsToExportRoute) {
List<VrfEntry> vrfEntries = vpnUtil.getAllVrfEntries(vpn.getVrfId());
if (vrfEntries != null) {
- ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
- for (VrfEntry vrfEntry : vrfEntries) {
- try {
- if (!FibHelper.isControllerManagedNonInterVpnLinkRoute(
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
+ for (VrfEntry vrfEntry : vrfEntries) {
+ try {
+ if (!FibHelper.isControllerManagedNonInterVpnLinkRoute(
RouteOrigin.value(vrfEntry.getOrigin()))) {
- LOG.info("handleVpnsExportingRoutes: vrfEntry with rd {} prefix {}"
- + " is not a controller managed non intervpn link route. Ignoring.",
+ LOG.info("handleVpnsExportingRoutes: vrfEntry with rd {} prefix {}"
+ + " is not a controller managed non intervpn link route. Ignoring.",
vpn.getVrfId(), vrfEntry.getDestPrefix());
- continue;
- }
- String prefix = vrfEntry.getDestPrefix();
- String gwMac = vrfEntry.getGatewayMacAddress();
- vrfEntry.getRoutePaths().forEach(routePath -> {
- String nh = routePath.getNexthopAddress();
- int label = routePath.getLabel().intValue();
- if (FibHelper.isControllerManagedVpnInterfaceRoute(RouteOrigin.value(
- vrfEntry.getOrigin()))) {
- LOG.info("handleVpnsExportingRoutesImporting: Importing fib entry rd {} prefix {}"
- + " nexthop {} label {} to vpn {} vpnRd {}",
- vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
- fibManager.addOrUpdateFibEntry(vpnRd, null /*macAddress*/, prefix,
- Collections.singletonList(nh), VrfEntry.EncapType.Mplsgre, label,
- 0 /*l3vni*/, gwMac, vpn.getVrfId(), RouteOrigin.SELF_IMPORTED,
- confTx);
- } else {
- LOG.info("handleVpnsExportingRoutes: Importing subnet route fib entry rd {} "
- + "prefix {} nexthop {} label {} to vpn {} vpnRd {}",
- vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
- SubnetRoute route = vrfEntry.augmentation(SubnetRoute.class);
- importSubnetRouteForNewVpn(vpnRd, prefix, nh, label, route, vpn.getVrfId(),
- confTx);
+ continue;
}
- });
- } catch (RuntimeException e) {
- LOG.error("getNextHopAddressList: Exception occurred while importing route with rd {}"
- + " prefix {} routePaths {} to vpn {} vpnRd {}", vpn.getVrfId(),
+ String prefix = vrfEntry.getDestPrefix();
+ String gwMac = vrfEntry.getGatewayMacAddress();
+ requireNonNullElse(vrfEntry.getRoutePaths(),
+ Collections.<RoutePaths>emptyList()).forEach(routePath -> {
+ String nh = routePath.getNexthopAddress();
+ int label = routePath.getLabel().intValue();
+ if (FibHelper.isControllerManagedVpnInterfaceRoute(RouteOrigin.value(
+ vrfEntry.getOrigin()))) {
+ LOG.info(
+ "handleVpnsExportingRoutesImporting: Importing fib entry rd {}"
+ + " prefix {} nexthop {} label {} to vpn {} vpnRd {}",
+ vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
+ fibManager.addOrUpdateFibEntry(vpnRd, null /*macAddress*/, prefix,
+ Collections.singletonList(nh), VrfEntry.EncapType.Mplsgre, label,
+ 0 /*l3vni*/, gwMac, vpn.getVrfId(), RouteOrigin.SELF_IMPORTED,
+ confTx);
+ } else {
+ LOG.info("handleVpnsExportingRoutes: Importing subnet route fib entry"
+ + " rd {} prefix {} nexthop {} label {} to vpn {} vpnRd {}",
+ vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
+ SubnetRoute route = vrfEntry.augmentation(SubnetRoute.class);
+ importSubnetRouteForNewVpn(vpnRd, prefix, nh, label, route, vpn.getVrfId(),
+ confTx);
+ }
+ });
+ } catch (RuntimeException e) {
+ LOG.error("getNextHopAddressList: Exception occurred while importing route with rd {}"
+ + " prefix {} routePaths {} to vpn {} vpnRd {}", vpn.getVrfId(),
vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), vpnName, vpnRd);
+ }
}
- }
- }), LOG, "Error handing VPN exporting routes");
+ }), LOG, "Error handing VPN exporting routes");
} else {
LOG.info("getNextHopAddressList: No vrf entries to import from vpn {} with rd {} to vpn {} with rd {}",
vpn.getVpnInstanceName(), vpn.getVrfId(), vpnName, vpnRd);
@Override
public void remove(InstanceIdentifier<VpnInterface> identifier, VpnInterface vpnInterface) {
- final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ LOG.trace("Received VpnInterface remove event: vpnInterface={}", vpnInterface);
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
- for (VpnInstanceNames vpnInterfaceVpnInstance : vpnInterface.getVpnInstanceNames()) {
+ for (VpnInstanceNames vpnInterfaceVpnInstance : requireNonNullElse(vpnInterface.getVpnInstanceNames(),
+ Collections.<VpnInstanceNames>emptyList())) {
String vpnName = vpnInterfaceVpnInstance.getVpnName();
removeVpnInterfaceCall(identifier, vpnInterface, vpnName, interfaceName);
}
final String interfaceName) {
if (Boolean.TRUE.equals(vpnInterface.isRouterInterface())) {
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getName(), () -> {
- ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
- deleteFibEntryForRouterInterface(vpnInterface, confTx, vpnName);
- LOG.info("remove: Router interface {} for vpn {}", interfaceName, vpnName);
- });
+ ListenableFuture<Void> future =
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
+ deleteFibEntryForRouterInterface(vpnInterface, confTx, vpnName);
+ LOG.info("remove: Router interface {} for vpn {}", interfaceName, vpnName);
+ });
ListenableFutures.addErrorLogging(future, LOG, "Error removing call for interface {} on VPN {}",
vpnInterface.getName(), vpnName);
return Collections.singletonList(future);
}, DJC_MAX_RETRIES);
} else {
- removeVpnInterfaceFromVpn(identifier, vpnInterface, vpnName, interfaceName);
+ Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(dataBroker, interfaceName);
+ removeVpnInterfaceFromVpn(identifier, vpnInterface, vpnName, interfaceName, interfaceState);
}
}
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
private void removeVpnInterfaceFromVpn(final InstanceIdentifier<VpnInterface> identifier,
- final VpnInterface vpnInterface, final String vpnName,
- final String interfaceName) {
+ final VpnInterface vpnInterface, final String vpnName,
+ final String interfaceName, final Interface interfaceState) {
LOG.info("remove: VPN Interface remove event - intfName {} vpn {} dpn {}" ,vpnInterface.getName(),
vpnName, vpnInterface.getDpnId());
removeInterfaceFromUnprocessedList(identifier, vpnInterface);
jobCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
() -> {
List<ListenableFuture<Void>> futures = new ArrayList<>(3);
- ListenableFuture<Void> configFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- writeConfigTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- writeOperTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeInvTxn -> {
- LOG.info("remove: - intfName {} onto vpnName {} running config-driven",
- interfaceName, vpnName);
- BigInteger dpId = BigInteger.ZERO;
- int ifIndex = 0;
- String gwMacAddress = null;
- InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId =
- VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
- Optional<VpnInterfaceOpDataEntry> optVpnInterface = Optional.absent();
- try {
- optVpnInterface = SingleTransactionDataBroker.syncReadOptional(dataBroker,
- LogicalDatastoreType.OPERATIONAL, interfaceId);
- } catch (ReadFailedException e) {
- LOG.error("remove: Failed to read data store for interface {} vpn {}", interfaceName,
- vpnName);
- return;
- }
- Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(dataBroker,
- interfaceName);
- if (interfaceState != null) {
+ ListenableFuture<Void> configFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+ writeConfigTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+ writeOperTxn -> futures.add(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, writeInvTxn -> {
+ LOG.info("remove: - intfName {} onto vpnName {} running config-driven",
+ interfaceName, vpnName);
+ BigInteger dpId;
+ int ifIndex;
+ String gwMacAddress;
+ InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId =
+ VpnUtil.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
+ Optional<VpnInterfaceOpDataEntry> optVpnInterface;
try {
- dpId = InterfaceUtils.getDpIdFromInterface(interfaceState);
- } catch (NumberFormatException | IllegalStateException e) {
- LOG.error("remove: Unable to retrieve dpnId from interface operational"
- + " data store for interface {} on dpn {} for vpn {} Fetching"
- + " from vpn interface op data store. ", interfaceName,
- vpnInterface.getDpnId(), vpnName, e);
- dpId = BigInteger.ZERO;
+ optVpnInterface = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, interfaceId);
+ } catch (ReadFailedException e) {
+ LOG.error("remove: Failed to read data store for interface {} vpn {}",
+ interfaceName, vpnName);
+ return;
}
- ifIndex = interfaceState.getIfIndex();
- gwMacAddress = interfaceState.getPhysAddress().getValue();
- } else {
- LOG.info("remove: Interface state not available for {}. Trying to fetch data"
- + " from vpn interface op.", interfaceName);
- if (optVpnInterface.isPresent()) {
- VpnInterfaceOpDataEntry vpnOpInterface = optVpnInterface.get();
- dpId = vpnOpInterface.getDpnId();
- ifIndex = vpnOpInterface.getLportTag().intValue();
- gwMacAddress = vpnOpInterface.getGatewayMacAddress();
+ if (interfaceState != null) {
+ try {
+ dpId = InterfaceUtils.getDpIdFromInterface(interfaceState);
+ } catch (NumberFormatException | IllegalStateException e) {
+ LOG.error("remove: Unable to retrieve dpnId from interface operational"
+ + " data store for interface {} on dpn {} for vpn {} Fetching"
+ + " from vpn interface op data store. ", interfaceName,
+ vpnInterface.getDpnId(), vpnName, e);
+ dpId = BigInteger.ZERO;
+ }
+ ifIndex = interfaceState.getIfIndex();
+ gwMacAddress = interfaceState.getPhysAddress().getValue();
} else {
- LOG.error("remove: Handling removal of VPN interface {} for vpn {} skipped"
- + " as interfaceState and vpn interface op is not"
- + " available", interfaceName, vpnName);
- return;
+ LOG.info("remove: Interface state not available for {}. Trying to fetch data"
+ + " from vpn interface op.", interfaceName);
+ if (optVpnInterface.isPresent()) {
+ VpnInterfaceOpDataEntry vpnOpInterface = optVpnInterface.get();
+ dpId = vpnOpInterface.getDpnId();
+ ifIndex = vpnOpInterface.getLportTag().intValue();
+ gwMacAddress = vpnOpInterface.getGatewayMacAddress();
+ } else {
+ LOG.error("remove: Handling removal of VPN interface {} for vpn {} skipped"
+ + " as interfaceState and vpn interface op is not"
+ + " available", interfaceName, vpnName);
+ return;
+ }
}
- }
- processVpnInterfaceDown(dpId, interfaceName, ifIndex, gwMacAddress,
- optVpnInterface.isPresent() ? optVpnInterface.get() : null, false,
- writeConfigTxn, writeOperTxn, writeInvTxn);
- LOG.info(
- "remove: Removal of vpn interface {} on dpn {} for vpn {} processed "
- + "successfully",
- interfaceName, vpnInterface.getDpnId(), vpnName);
- })))));
+ processVpnInterfaceDown(dpId, interfaceName, ifIndex, gwMacAddress,
+ optVpnInterface.isPresent() ? optVpnInterface.get() : null, false,
+ writeConfigTxn, writeOperTxn, writeInvTxn);
+ LOG.info(
+ "remove: Removal of vpn interface {} on dpn {} for vpn {} processed "
+ + "successfully",
+ interfaceName, vpnInterface.getDpnId(), vpnName);
+ })))));
futures.add(configFuture);
Futures.addCallback(configFuture, new PostVpnInterfaceWorker(interfaceName, false, "Config"));
return futures;
String gwMac,
VpnInterfaceOpDataEntry vpnOpInterface,
boolean isInterfaceStateDown,
- WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTxn,
- WriteTransaction writeInvTxn) {
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTxn,
+ TypedReadWriteTransaction<Configuration> writeInvTxn)
+ throws ExecutionException, InterruptedException {
if (vpnOpInterface == null) {
LOG.error("processVpnInterfaceDown: Unable to process delete/down for interface {} on dpn {}"
+ " as it is not available in operational data store", interfaceName, dpId);
private void removeAdjacenciesFromVpn(final BigInteger dpnId, final int lportTag, final String interfaceName,
final String vpnName, final long vpnId, String gwMac,
- WriteTransaction writeConfigTxn, final WriteTransaction writeOperTxn,
- final WriteTransaction writeInvTxn) {
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTxn,
+ TypedReadWriteTransaction<Configuration> writeInvTxn)
+ throws ExecutionException, InterruptedException {
//Read NextHops
try {
InstanceIdentifier<VpnInterfaceOpDataEntry> identifier = VpnUtil
String primaryRd = vpnUtil.getVpnRd(vpnName);
LOG.info("removeAdjacenciesFromVpn: For interface {} on dpn {} RD recovered for vpn {} as rd {}",
interfaceName, dpnId, vpnName, primaryRd);
- if (adjacencies.isPresent() && !adjacencies.get().getAdjacency().isEmpty()) {
+ if (adjacencies.isPresent() && adjacencies.get().getAdjacency() != null
+ && !adjacencies.get().getAdjacency().isEmpty()) {
List<Adjacency> nextHops = adjacencies.get().getAdjacency();
LOG.info("removeAdjacenciesFromVpn: NextHops for interface {} on dpn {} for vpn {} are {}",
interfaceName, dpnId, vpnName, nextHops);
} else {
// This is a primary adjacency
nhList = nextHop.getNextHopIpList() != null ? nextHop.getNextHopIpList()
- : Collections.emptyList();
+ : emptyList();
removeGwMacAndArpResponderFlows(nextHop, vpnId, dpnId, lportTag, gwMac,
interfaceName, writeInvTxn);
}
if (!nhList.isEmpty()) {
- if (rd.equals(vpnName)) {
+ if (Objects.equals(rd, vpnName)) {
//this is an internal vpn - the rd is assigned to the vpn instance name;
//remove from FIB directly
nhList.forEach(removeAdjacencyFromInternalVpn(nextHop, vpnName,
// this vpn interface has no more adjacency left, so clean up the vpn interface from Operational DS
LOG.info("removeAdjacenciesFromVpn: Vpn Interface {} on vpn {} dpn {} has no adjacencies."
+ " Removing it.", interfaceName, vpnName, dpnId);
- writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, identifier);
+ writeOperTxn.delete(identifier);
}
} catch (ReadFailedException e) {
LOG.error("removeAdjacenciesFromVpn: Failed to read data store for interface {} dpn {} vpn {}",
}
}
- private Consumer<String> removeAdjacencyFromInternalVpn(Adjacency nextHop, String vpnName, String interfaceName,
- BigInteger dpnId, WriteTransaction writeConfigTxn,
- WriteTransaction writeOperTx) {
+ private Consumer<String> removeAdjacencyFromInternalVpn(Adjacency nextHop, String vpnName,
+ String interfaceName, BigInteger dpnId,
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTx) {
return (nh) -> {
String primaryRd = vpnUtil.getVpnRd(vpnName);
String prefix = nextHop.getIpAddress();
private void removeAdjacencyFromBgpvpn(Adjacency nextHop, List<String> nhList, String vpnName, String primaryRd,
BigInteger dpnId, String rd, String interfaceName,
- WriteTransaction writeConfigTxn, WriteTransaction writeOperTx) {
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTx) {
List<VpnInstanceOpDataEntry> vpnsToImportRoute =
vpnUtil.getVpnsImportingMyRoute(vpnName);
nhList.forEach((nh) -> {
private void removeGwMacAndArpResponderFlows(Adjacency nextHop, long vpnId, BigInteger dpnId,
int lportTag, String gwMac, String interfaceName,
- WriteTransaction writeInvTxn) {
+ TypedReadWriteTransaction<Configuration> writeInvTxn)
+ throws ExecutionException, InterruptedException {
final Uuid subnetId = nextHop.getSubnetId();
if (nextHop.getSubnetGatewayMacAddress() == null) {
// A valid mac-address was not available for this subnet-gateway-ip
+ " extra-route/learned-route in rd {} prefix {} interface {} on dpn {}"
+ " for vpn {}", nextHop.getVrfId(), nextHop.getIpAddress(), interfaceName, dpnId,
vpnName);
- nhList = Collections.emptyList();
+ nhList = emptyList();
} else {
nhList = Collections.singletonList(nextHopIp);
}
@Override
protected void update(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface original,
final VpnInterface update) {
- LOG.info("update: VPN Interface update event - intfName {} on dpn {} oldVpn {} newVpn {}" ,update.getName(),
- update.getDpnId(), original.getVpnInstanceNames(),
- update.getVpnInstanceNames());
+ LOG.trace("Received VpnInterface update event: original={}, update={}", original, update);
+ LOG.info("update: VPN Interface update event - intfName {} on dpn {} oldVpn {} newVpn {}", update.getName(),
+ update.getDpnId(), original.getVpnInstanceNames(), update.getVpnInstanceNames());
final String vpnInterfaceName = update.getName();
final BigInteger dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
- final Adjacencies origAdjs = original.augmentation(Adjacencies.class);
- final List<Adjacency> oldAdjs = origAdjs != null && origAdjs.getAdjacency()
- != null ? origAdjs.getAdjacency() : new ArrayList<>();
- final Adjacencies updateAdjs = update.augmentation(Adjacencies.class);
- final List<Adjacency> newAdjs = updateAdjs != null && updateAdjs.getAdjacency()
- != null ? updateAdjs.getAdjacency() : new ArrayList<>();
-
LOG.info("VPN Interface update event - intfName {}", vpnInterfaceName);
//handles switching between <internal VPN - external VPN>
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterfaceName, () -> {
- if (handleVpnSwapForVpnInterface(identifier, original, update)) {
- LOG.info("update: handled VPNInterface {} on dpn {} update"
- + "upon VPN swap from oldVpn(s) {} to newVpn(s) {}",
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ if (handleVpnInstanceUpdateForVpnInterface(identifier, original, update, futures)) {
+ LOG.info("update: handled Instance update for VPNInterface {} on dpn {} from oldVpn(s) {} "
+ + "to newVpn(s) {}",
original.getName(), dpnId,
VpnHelper.getVpnInterfaceVpnInstanceNamesString(original.getVpnInstanceNames()),
VpnHelper.getVpnInterfaceVpnInstanceNamesString(update.getVpnInstanceNames()));
- return Collections.emptyList();
- }
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- for (VpnInstanceNames vpnInterfaceVpnInstance : update.getVpnInstanceNames()) {
- String newVpnName = vpnInterfaceVpnInstance.getVpnName();
- List<Adjacency> copyNewAdjs = new ArrayList<>(newAdjs);
- List<Adjacency> copyOldAdjs = new ArrayList<>(oldAdjs);
- String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
- if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
- // TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
- futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
- futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(operTx -> {
- InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier =
- VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterfaceName, newVpnName);
- LOG.info("VPN Interface update event - intfName {} onto vpnName {} running config-driven",
- update.getName(), newVpnName);
- //handle both addition and removal of adjacencies
- //currently, new adjacency may be an extra route
- boolean isBgpVpnInternetVpn = vpnUtil.isBgpVpnInternet(newVpnName);
- if (!oldAdjs.equals(newAdjs)) {
- for (Adjacency adj : copyNewAdjs) {
- if (copyOldAdjs.contains(adj)) {
- copyOldAdjs.remove(adj);
- } else {
- // add new adjacency - right now only extra route will hit this path
- if (!isBgpVpnInternetVpn || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
- addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adj,
- dpnId, operTx, confTx);
- }
- LOG.info("update: new Adjacency {} with nextHop {} label {} subnet {} added to"
- + " vpn interface {} on vpn {} dpnId {}",
- adj.getIpAddress(), adj.getNextHopIpList(),
- adj.getLabel(), adj.getSubnetId(), update.getName(),
- newVpnName, dpnId);
- }
- }
- for (Adjacency adj : copyOldAdjs) {
- if (!isBgpVpnInternetVpn || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
- if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency
- && !adj.isPhysNetworkFunc()) {
- delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
- operTx, confTx);
- //remove FIB entry
- String vpnRd = vpnUtil.getVpnRd(newVpnName);
- LOG.debug("update: remove prefix {} from the FIB and BGP entry "
- + "for the Vpn-Rd {} ", adj.getIpAddress(), vpnRd);
- //remove BGP entry
- fibManager.removeFibEntry(vpnRd, adj.getIpAddress(), confTx);
- if (vpnRd != null && !vpnRd.equalsIgnoreCase(newVpnName)) {
- bgpManager.withdrawPrefix(vpnRd, adj.getIpAddress());
- }
- } else {
- delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
- operTx, confTx);
- }
- }
- LOG.info("update: Adjacency {} with nextHop {} label {} subnet {} removed from"
- + " vpn interface {} on vpn {}", adj.getIpAddress(), adj
- .getNextHopIpList(),
- adj.getLabel(), adj.getSubnetId(), update.getName(), newVpnName);
- }
- }
- }));
- }));
- for (ListenableFuture<Void> future : futures) {
- ListenableFutures.addErrorLogging(future, LOG, "update: failed for interface {} on vpn {}",
- update.getName(), update.getVpnInstanceNames());
- }
- } else {
- LOG.error("update: Ignoring update of vpnInterface {}, as newVpnInstance {} with primaryRd {}"
- + " is already marked for deletion", vpnInterfaceName, newVpnName, primaryRd);
- }
+ return emptyList();
}
+ updateVpnInstanceAdjChange(original, update, vpnInterfaceName, futures);
return futures;
});
}
- private boolean handleVpnSwapForVpnInterface(InstanceIdentifier<VpnInterface> identifier,
- VpnInterface original, VpnInterface update) {
- boolean isSwap = Boolean.FALSE;
- final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ private boolean handleVpnInstanceUpdateForVpnInterface(InstanceIdentifier<VpnInterface> identifier,
+ VpnInterface original, VpnInterface update,
+ List<ListenableFuture<Void>> futures) {
+ boolean isVpnInstanceUpdate = false;
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
- List<String> oldVpnList = original.getVpnInstanceNames().stream()
- .map(VpnInstanceNames::getVpnName).collect(Collectors.toList());
+ List<String> oldVpnList = VpnUtil.getVpnListForVpnInterface(original);
List<String> oldVpnListCopy = new ArrayList<>();
oldVpnListCopy.addAll(oldVpnList);
- List<String> newVpnList = update.getVpnInstanceNames().stream()
- .map(VpnInstanceNames::getVpnName).collect(Collectors.toList());
+ List<String> newVpnList = VpnUtil.getVpnListForVpnInterface(update);
+ List<String> newVpnListCopy = new ArrayList<>();
+ newVpnListCopy.addAll(newVpnList);
+
oldVpnList.removeAll(newVpnList);
newVpnList.removeAll(oldVpnListCopy);
+ //This block will execute only on if there is a change in the VPN Instance.
if (!oldVpnList.isEmpty() || !newVpnList.isEmpty()) {
- for (String oldVpnName: oldVpnList) {
- isSwap = Boolean.TRUE;
- LOG.info("handleVpnSwapForVpnInterface: VPN Interface update event - intfName {} remove vpnName {}"
- + " running config-driven swap removal", interfaceName, oldVpnName);
- removeVpnInterfaceCall(identifier, original, oldVpnName, interfaceName);
- LOG.info("handleVpnSwapForVpnInterface: Processed Remove for update on VPNInterface {} upon VPN swap"
- + "from old vpn {} to newVpn(s) {}", interfaceName, oldVpnName, newVpnList);
+ /*
+ * Internet BGP-VPN Instance update with single router:
+ * ====================================================
+ * In this case single VPN Interface will be part of maximum 2 VPN Instance only.
+ * 1st VPN Instance : router VPN or external BGP-VPN.
+ * 2nd VPN Instance : Internet BGP-VPN(router-gw update/delete) for public network access.
+ *
+ * VPN Instance UPDATE:
+ * oldVpnList = 0 and newVpnList = 1 (Internet BGP-VPN)
+ * oldVpnList = 1 and newVpnList = 0 (Internet BGP-VPN)
+ *
+ * External BGP-VPN Instance update with single router:
+ * ====================================================
+ * In this case single VPN interface will be part of maximum 1 VPN Instance only.
+ *
+ * Updated VPN Instance will be always either internal router VPN to
+ * external BGP-VPN or external BGP-VPN to internal router VPN swap.
+ *
+ * VPN Instance UPDATE:
+ * oldVpnList = 1 and newVpnList = 1 (router VPN to Ext-BGPVPN)
+ * oldVpnList = 1 and newVpnList = 1 (Ext-BGPVPN to router VPN)
+ *
+ * Dual Router VPN Instance Update:
+ * ================================
+ * In this case single VPN interface will be part of maximum 3 VPN Instance only.
+ *
+ * 1st VPN Instance : router VPN or external BGP-VPN-1.
+ * 2nd VPN Instance : router VPN or external BGP-VPN-2.
+ * 3rd VPN Instance : Internet BGP-VPN(router-gw update/delete) for public network access.
+ *
+ * Dual Router --> Associated with common external BGP-VPN Instance.
+ * 1st router and 2nd router are getting associated with single External BGP-VPN
+ * 1) add 1st router to external bgpvpn --> oldVpnList=1, newVpnList=1;
+ * 2) add 2nd router to the same external bgpvpn --> oldVpnList=1, newVpnList=0
+ * In this case, we need to call removeVpnInterfaceCall() followed by addVpnInterfaceCall()
+ *
+ *
+ */
+ isVpnInstanceUpdate = true;
+ if (VpnUtil.isDualRouterVpnUpdate(oldVpnListCopy, newVpnListCopy)) {
+ if ((oldVpnListCopy.size() == 2 || oldVpnListCopy.size() == 3)
+ && (oldVpnList.size() == 1 && newVpnList.size() == 0)) {
+ //Identify the external BGP-VPN Instance and pass that value as newVpnList
+ List<String> externalBgpVpnList = new ArrayList<>();
+ for (String newVpnName : newVpnListCopy) {
+ String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
+ VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(primaryRd);
+ if (vpnInstanceOpDataEntry.getBgpvpnType() == VpnInstanceOpDataEntry
+ .BgpvpnType.BGPVPNExternal) {
+ externalBgpVpnList.add(newVpnName);
+ break;
+ }
+ }
+ //This call will execute removeVpnInterfaceCall() followed by addVpnInterfaceCall()
+ updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList,
+ externalBgpVpnList, oldVpnListCopy, futures);
+
+ } else if ((oldVpnListCopy.size() == 2 || oldVpnListCopy.size() == 3)
+ && (oldVpnList.size() == 0 && newVpnList.size() == 1)) {
+ //Identify the router VPN Instance and pass that value as oldVpnList
+ List<String> routerVpnList = new ArrayList<>();
+ for (String newVpnName : newVpnListCopy) {
+ String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
+ VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(primaryRd);
+ if (vpnInstanceOpDataEntry.getBgpvpnType() == VpnInstanceOpDataEntry
+ .BgpvpnType.VPN) {
+ routerVpnList.add(newVpnName);
+ break;
+ }
+ }
+ //This call will execute removeVpnInterfaceCall() followed by addVpnInterfaceCall()
+ updateVpnInstanceChange(identifier, interfaceName, original, update, routerVpnList,
+ newVpnList, oldVpnListCopy, futures);
+
+ } else {
+ //Handle remaining use cases.
+ updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList,
+ oldVpnListCopy, futures);
+ }
+ } else {
+ updateVpnInstanceChange(identifier, interfaceName, original, update, oldVpnList, newVpnList,
+ oldVpnListCopy, futures);
}
- //Wait for previous interface bindings to be removed
+ }
+ return isVpnInstanceUpdate;
+ }
+
+ private void updateVpnInstanceChange(InstanceIdentifier<VpnInterface> identifier, String interfaceName,
+ VpnInterface original, VpnInterface update, List<String> oldVpnList,
+ List<String> newVpnList, List<String> oldVpnListCopy,
+ List<ListenableFuture<Void>> futures) {
+ final Adjacencies origAdjs = original.augmentation(Adjacencies.class);
+ final List<Adjacency> oldAdjs = (origAdjs != null && origAdjs.getAdjacency() != null)
+ ? origAdjs.getAdjacency() : new ArrayList<>();
+ final Adjacencies updateAdjs = update.augmentation(Adjacencies.class);
+ final List<Adjacency> newAdjs = (updateAdjs != null && updateAdjs.getAdjacency() != null)
+ ? updateAdjs.getAdjacency() : new ArrayList<>();
+
+ boolean isOldVpnRemoveCallExecuted = false;
+ for (String oldVpnName : oldVpnList) {
+ LOG.info("updateVpnInstanceChange: VPN Interface update event - intfName {} "
+ + "remove from vpnName {} ", interfaceName, oldVpnName);
+ removeVpnInterfaceCall(identifier, original, oldVpnName, interfaceName);
+ LOG.info("updateVpnInstanceChange: Processed Remove for update on VPNInterface"
+ + " {} upon VPN update from old vpn {} to newVpn(s) {}", interfaceName, oldVpnName,
+ newVpnList);
+ isOldVpnRemoveCallExecuted = true;
+ }
+ //Wait for previous interface bindings to be removed
+ if (isOldVpnRemoveCallExecuted && !newVpnList.isEmpty()) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
//Ignore
}
+ }
+ for (String newVpnName : newVpnList) {
+ String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
+ if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
+ LOG.info("updateVpnInstanceChange: VPN Interface update event - intfName {} "
+ + "onto vpnName {} ", interfaceName, newVpnName);
+ addVpnInterfaceCall(identifier, update, oldAdjs, newAdjs, newVpnName);
+ LOG.info("updateVpnInstanceChange: Processed Add for update on VPNInterface {}"
+ + "from oldVpn(s) {} to newVpn {} ",
+ interfaceName, oldVpnListCopy, newVpnName);
+ /* This block will execute only if V6 subnet is associated with internet BGP-VPN.
+ * Use Case:
+ * In Dual stack network, first V4 subnet only attached to router and router is associated
+ * with internet BGP-VPN(router-gw). At this point VPN interface is having only router vpn instance.
+ * Later V6 subnet is added to router, at this point existing VPN interface will get updated
+ * with Internet BGP-VPN instance(Note: Internet BGP-VPN Instance update in vpn interface
+ * is applicable for only on V6 subnet is added to router). newVpnList = Contains only Internet
+ * BGP-VPN Instance. So we required V6 primary adjacency info needs to be populated onto
+ * router VPN as well as Internet BGP-VPN.
+ *
+ * addVpnInterfaceCall() --> It will create V6 Adj onto Internet BGP-VPN only.
+ * updateVpnInstanceAdjChange() --> This method call is needed for second primary V6 Adj
+ * update in existing router VPN instance.
+ */
+ if (vpnUtil.isBgpVpnInternet(newVpnName)) {
+ LOG.info("updateVpnInstanceChange: VPN Interface {} with new Adjacency {} in existing "
+ + "VPN instance {}", interfaceName, newAdjs, original.getVpnInstanceNames());
+ updateVpnInstanceAdjChange(original, update, interfaceName, futures);
+ }
+ }
+ }
+ }
- final Adjacencies origAdjs = original.augmentation(Adjacencies.class);
- final List<Adjacency> oldAdjs = (origAdjs != null && origAdjs.getAdjacency() != null)
- ? origAdjs.getAdjacency() : new ArrayList<>();
- final Adjacencies updateAdjs = update.augmentation(Adjacencies.class);
- final List<Adjacency> newAdjs = (updateAdjs != null && updateAdjs.getAdjacency() != null)
- ? updateAdjs.getAdjacency() : new ArrayList<>();
- for (String newVpnName: newVpnList) {
- String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
- isSwap = Boolean.TRUE;
- if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
- LOG.info("handleVpnSwapForVpnInterface: VPN Interface update event - intfName {} onto vpnName {}"
- + "running config-driven swap addition", interfaceName, newVpnName);
- addVpnInterfaceCall(identifier, update, oldAdjs, newAdjs, newVpnName);
- LOG.info("handleVpnSwapForVpnInterface: Processed Add for update on VPNInterface {}"
- + "from oldVpn(s) {} to newVpn {} upon VPN swap",
- interfaceName, oldVpnListCopy, newVpnName);
+ private List<ListenableFuture<Void>> updateVpnInstanceAdjChange(VpnInterface original, VpnInterface update,
+ String vpnInterfaceName,
+ List<ListenableFuture<Void>> futures) {
+ final Adjacencies origAdjs = original.augmentation(Adjacencies.class);
+ final List<Adjacency> oldAdjs = origAdjs != null && origAdjs.getAdjacency()
+ != null ? origAdjs.getAdjacency() : new ArrayList<>();
+ final Adjacencies updateAdjs = update.augmentation(Adjacencies.class);
+ final List<Adjacency> newAdjs = updateAdjs != null && updateAdjs.getAdjacency()
+ != null ? updateAdjs.getAdjacency() : new ArrayList<>();
+
+ final BigInteger dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
+ for (VpnInstanceNames vpnInterfaceVpnInstance : requireNonNullElse(update.getVpnInstanceNames(),
+ Collections.<VpnInstanceNames>emptyList())) {
+ String newVpnName = vpnInterfaceVpnInstance.getVpnName();
+ List<Adjacency> copyNewAdjs = new ArrayList<>(newAdjs);
+ List<Adjacency> copyOldAdjs = new ArrayList<>(oldAdjs);
+ String primaryRd = vpnUtil.getPrimaryRd(newVpnName);
+ if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
+ // TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
+ InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier =
+ VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterfaceName, newVpnName);
+ LOG.info("VPN Interface update event - intfName {} onto vpnName {} running config-driven",
+ update.getName(), newVpnName);
+ //handle both addition and removal of adjacencies
+ //currently, new adjacency may be an extra route
+ boolean isBgpVpnInternetVpn = vpnUtil.isBgpVpnInternet(newVpnName);
+ if (!oldAdjs.equals(newAdjs)) {
+ for (Adjacency adj : copyNewAdjs) {
+ if (copyOldAdjs.contains(adj)) {
+ copyOldAdjs.remove(adj);
+ } else {
+ // add new adjacency
+ if (!isBgpVpnInternetVpn || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
+ addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adj,
+ dpnId, operTx, confTx, confTx);
+ }
+ LOG.info("update: new Adjacency {} with nextHop {} label {} subnet {} added to"
+ + " vpn interface {} on vpn {} dpnId {}",
+ adj.getIpAddress(), adj.getNextHopIpList(),
+ adj.getLabel(), adj.getSubnetId(), update.getName(),
+ newVpnName, dpnId);
+ }
+ }
+ for (Adjacency adj : copyOldAdjs) {
+ if (!isBgpVpnInternetVpn || vpnUtil.isAdjacencyEligibleToVpnInternet(adj)) {
+ if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency
+ && !adj.isPhysNetworkFunc()) {
+ delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+ operTx, confTx);
+ //remove FIB entry
+ String vpnRd = vpnUtil.getVpnRd(newVpnName);
+ LOG.debug("update: remove prefix {} from the FIB and BGP entry "
+ + "for the Vpn-Rd {} ", adj.getIpAddress(), vpnRd);
+ //remove BGP entry
+ fibManager.removeFibEntry(vpnRd, adj.getIpAddress(), confTx);
+ if (vpnRd != null && !vpnRd.equalsIgnoreCase(newVpnName)) {
+ bgpManager.withdrawPrefix(vpnRd, adj.getIpAddress());
+ }
+ } else {
+ delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+ operTx, confTx);
+ }
+ }
+ LOG.info("update: Adjacency {} with nextHop {} label {} subnet {} removed from"
+ + " vpn interface {} on vpn {}", adj.getIpAddress(), adj
+ .getNextHopIpList(),
+ adj.getLabel(), adj.getSubnetId(), update.getName(), newVpnName);
+ }
+ }
+ }));
+ }));
+ for (ListenableFuture<Void> future : futures) {
+ ListenableFutures.addErrorLogging(future, LOG, "update: failed for interface {} on vpn {}",
+ update.getName(), update.getVpnInstanceNames());
}
+ } else {
+ LOG.error("update: Ignoring update of vpnInterface {}, as newVpnInstance {} with primaryRd {}"
+ + " is already marked for deletion", vpnInterfaceName, newVpnName, primaryRd);
}
}
- return isSwap;
+ return futures;
}
private void updateLabelMapper(Long label, List<String> nextHopIpList) {
}
public synchronized void importSubnetRouteForNewVpn(String rd, String prefix, String nextHop, int label,
- SubnetRoute route, String parentVpnRd, WriteTransaction writeConfigTxn) {
+ SubnetRoute route, String parentVpnRd, TypedWriteTransaction<Configuration> writeConfigTxn) {
RouteOrigin origin = RouteOrigin.SELF_IMPORTED;
VrfEntry vrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, nextHop, origin, parentVpnRd)
InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
VrfTables vrfTableNew = new VrfTablesBuilder().setRouteDistinguisher(rd).setVrfEntry(vrfEntryList).build();
if (writeConfigTxn != null) {
- writeConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableNew, true);
+ writeConfigTxn.merge(vrfTableId, vrfTableNew, CREATE_MISSING_PARENTS);
} else {
vpnUtil.syncUpdate(LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableNew);
}
}
protected void addNewAdjToVpnInterface(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier, String primaryRd,
- Adjacency adj, BigInteger dpnId, WriteTransaction writeOperTxn,
- WriteTransaction writeConfigTxn) {
+ Adjacency adj, BigInteger dpnId,
+ TypedWriteTransaction<Operational> writeOperTxn,
+ TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedReadWriteTransaction<Configuration> writeInvTxn)
+ throws ExecutionException, InterruptedException {
String interfaceName = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class).getName();
String configVpnName = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class).getVpnInstanceName();
try {
VrfEntry.EncapType encapType = VpnUtil.getEncapType(isL3VpnOverVxLan);
long l3vni = vpnInstanceOpData.getL3vni() == null ? 0L : vpnInstanceOpData.getL3vni();
VpnPopulator populator = L3vpnRegistry.getRegisteredPopulator(encapType);
- List<Adjacency> adjacencies;
- if (optAdjacencies.isPresent()) {
- adjacencies = optAdjacencies.get().getAdjacency();
- } else {
- // This code will be hit in case of first PNF adjacency
- adjacencies = new ArrayList<>();
+ List<Adjacency> adjacencies = new ArrayList<>();
+ if (optAdjacencies.isPresent() && optAdjacencies.get().getAdjacency() != null) {
+ adjacencies.addAll(optAdjacencies.get().getAdjacency());
}
long vpnId = vpnUtil.getVpnId(vpnName);
L3vpnInput input = new L3vpnInput().setNextHop(adj).setVpnName(vpnName)
if (interfaceState != null) {
processVpnInterfaceAdjacencies(dpnId, currVpnIntf.getLportTag().intValue(), vpnName, primaryRd,
currVpnIntf.getName(),
- vpnId, writeConfigTxn, writeOperTxn, null, interfaceState);
+ vpnId, writeConfigTxn, writeOperTxn, writeInvTxn, interfaceState);
}
}
if (adj.getNextHopIpList() != null && !adj.getNextHopIpList().isEmpty()
String parentVpnRd = getParentVpnRdForExternalSubnet(adj);
writeOperTxn.merge(
- LogicalDatastoreType.OPERATIONAL,
VpnUtil.getPrefixToInterfaceIdentifier(vpnUtil.getVpnId(adj.getSubnetId().getValue()),
prefix), pnfPrefix, true);
fibManager.addOrUpdateFibEntry(adj.getSubnetId().getValue(), adj.getMacAddress(),
- adj.getIpAddress(), Collections.emptyList(), null /* EncapType */, 0 /* label */,
+ adj.getIpAddress(), emptyList(), null /* EncapType */, 0 /* label */,
0 /*l3vni*/, null /* gw-mac */, parentVpnRd, RouteOrigin.LOCAL, writeConfigTxn);
input.setRd(adj.getVrfId());
aug, dpnId, currVpnIntf.getLportTag(),
currVpnIntf.getGatewayMacAddress());
- writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, identifier, newVpnIntf, true);
+ writeOperTxn.merge(identifier, newVpnIntf, CREATE_MISSING_PARENTS);
}
} catch (ReadFailedException e) {
LOG.error("addNewAdjToVpnInterface: Failed to read data store for interface {} dpn {} vpn {} rd {} ip "
}
}
+ @Nullable
private String getParentVpnRdForExternalSubnet(Adjacency adj) {
Subnets subnets = vpnUtil.getExternalSubnet(adj.getSubnetId());
return subnets != null ? subnets.getExternalNetworkId().getValue() : null;
}
protected void delAdjFromVpnInterface(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier, Adjacency adj,
- BigInteger dpnId, WriteTransaction writeOperTxn, WriteTransaction writeConfigTxn) {
+ BigInteger dpnId, TypedWriteTransaction<Operational> writeOperTxn,
+ TypedWriteTransaction<Configuration> writeConfigTxn) {
String interfaceName = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class).getName();
String vpnName = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class).getVpnInstanceName();
try {
if (optAdjacencies.isPresent()) {
List<Adjacency> adjacencies = optAdjacencies.get().getAdjacency();
- if (!adjacencies.isEmpty()) {
+ if (adjacencies != null && !adjacencies.isEmpty()) {
LOG.trace("delAdjFromVpnInterface: Adjacencies are {}", adjacencies);
- Iterator<Adjacency> adjIt = adjacencies.iterator();
- while (adjIt.hasNext()) {
- Adjacency adjElem = adjIt.next();
- if (adjElem.getIpAddress().equals(adj.getIpAddress())) {
- String rd = adjElem.getVrfId();
+ for (Adjacency adjacency : adjacencies) {
+ if (Objects.equals(adjacency.getIpAddress(), adj.getIpAddress())) {
+ String rd = adjacency.getVrfId();
if (adj.getNextHopIpList() != null) {
for (String nh : adj.getNextHopIpList()) {
deleteExtraRouteFromCurrentAndImportingVpns(
}
private void deleteExtraRouteFromCurrentAndImportingVpns(String vpnName, String destination, String nextHop,
- String rd, String intfName, WriteTransaction writeConfigTxn, WriteTransaction writeOperTx) {
+ String rd, String intfName, TypedWriteTransaction<Configuration> writeConfigTxn,
+ TypedWriteTransaction<Operational> writeOperTx) {
vpnManager.delExtraRoute(vpnName, destination, nextHop, rd, vpnName, intfName, writeConfigTxn, writeOperTx);
List<VpnInstanceOpDataEntry> vpnsToImportRoute = vpnUtil.getVpnsImportingMyRoute(vpnName);
for (VpnInstanceOpDataEntry vpn : vpnsToImportRoute) {
}
protected void createFibEntryForRouterInterface(String primaryRd, VpnInterface vpnInterface, String interfaceName,
- WriteTransaction writeConfigTxn, String vpnName) {
+ TypedWriteTransaction<Configuration> writeConfigTxn, String vpnName) {
if (vpnInterface == null) {
return;
}
}
protected void deleteFibEntryForRouterInterface(VpnInterface vpnInterface,
- WriteTransaction writeConfigTxn, String vpnName) {
+ TypedWriteTransaction<Configuration> writeConfigTxn, String vpnName) {
Adjacencies adjs = vpnInterface.augmentation(Adjacencies.class);
String rd = vpnUtil.getVpnRd(vpnName);
if (adjs != null) {
- List<Adjacency> adjsList = adjs.getAdjacency();
+ List<Adjacency> adjsList = requireNonNullElse(adjs.getAdjacency(), emptyList());
for (Adjacency adj : adjsList) {
if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
String primaryInterfaceIp = adj.getIpAddress();
}
private void processSavedInterface(UnprocessedVpnInterfaceData intefaceData, String vpnName) {
- if (!canHandleNewVpnInterface(intefaceData.identifier, intefaceData.vpnInterface, vpnName)) {
- LOG.error("add: VpnInstance {} for vpnInterface {} not ready, holding on ",
- vpnName, intefaceData.vpnInterface.getName());
- return;
- }
- final VpnInterfaceKey key = intefaceData.identifier
- .firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ final VpnInterfaceKey key = intefaceData.identifier.firstKeyOf(VpnInterface.class);
final String interfaceName = key.getName();
InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier = VpnUtil
.getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnName);
addVpnInterfaceToVpn(vpnInterfaceOpIdentifier, intefaceData.vpnInterface, null, null,
intefaceData.identifier, vpnName);
- return;
}
private void addToUnprocessedVpnInterfaces(InstanceIdentifier<VpnInterface> identifier,
LOG.debug("There is no adjacency available for vpnInterface:{}", vpnInterface);
return;
}
- List<Adjacency> operationVpnAdjacencies = vpnInterfaceOptional.get()
- .augmentation(AdjacenciesOp.class).getAdjacency();
+ List<Adjacency> operationVpnAdjacencies = requireNonNullElse(vpnInterfaceOptional.get()
+ .augmentation(AdjacenciesOp.class).getAdjacency(), emptyList());
// 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.
configVpnAdjacencies.stream()
.filter(adjacency -> operationVpnAdjacencies.stream()
.noneMatch(operationalAdjacency ->
- operationalAdjacency.getIpAddress().equals(adjacency.getIpAddress())))
+ 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<Void>> futures = new ArrayList<>();
- futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx ->
- futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
- confTx -> addNewAdjToVpnInterface(existingVpnInterfaceId,
- primaryRd, adjacency, vpnInterfaceOptional.get()
- .getDpnId(), confTx, operTx)))));
+ futures.add(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx ->
+ futures.add(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ confTx -> addNewAdjToVpnInterface(existingVpnInterfaceId,
+ primaryRd, adjacency, vpnInterfaceOptional.get()
+ .getDpnId(), operTx, confTx, confTx)))));
return futures;
} else {
- return Collections.emptyList();
+ return emptyList();
}
});
});