*/
package org.opendaylight.netvirt.fibmanager;
+import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import javax.annotation.PostConstruct;
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.eclipse.jdt.annotation.Nullable;
import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.NwConstants;
-import org.opendaylight.genius.mdsalutil.UpgradeState;
import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
import org.opendaylight.genius.mdsalutil.actions.ActionPushMpls;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
import org.opendaylight.genius.utils.batching.ActionableResource;
-import org.opendaylight.genius.utils.batching.ActionableResourceImpl;
+import org.opendaylight.genius.utils.batching.ActionableResources;
import org.opendaylight.genius.utils.batching.ResourceBatchingManager;
import org.opendaylight.genius.utils.batching.ResourceHandler;
import org.opendaylight.genius.utils.batching.SubTransaction;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.WriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper;
+import org.opendaylight.serviceutils.upgrade.UpgradeState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
+import org.opendaylight.yangtools.concepts.Identifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
-public class BgpRouteVrfEntryHandler extends BaseVrfEntryHandler
- implements ResourceHandler, IVrfEntryHandler {
+public class BgpRouteVrfEntryHandler extends BaseVrfEntryHandler implements ResourceHandler {
+ private static final class ActionableResourceIdentifier implements Identifier {
+ private static final long serialVersionUID = 1L;
+
+ private final String routeDistinguisher;
+ private final String destPrefix;
+
+ ActionableResourceIdentifier(final String routeDistinguisher, final String destPrefix) {
+ this.routeDistinguisher = requireNonNull(routeDistinguisher);
+ this.destPrefix = requireNonNull(destPrefix);
+ }
+
+ @Override
+ public int hashCode() {
+ return routeDistinguisher.hashCode() * 31 + destPrefix.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof ActionableResourceIdentifier)) {
+ return false;
+ }
+ final ActionableResourceIdentifier other = (ActionableResourceIdentifier) obj;
+ return routeDistinguisher.equals(other.routeDistinguisher) && destPrefix.equals(other.destPrefix);
+ }
+
+ @Override
+ public String toString() {
+ return routeDistinguisher + destPrefix;
+ }
+ }
private static final Logger LOG = LoggerFactory.getLogger(BgpRouteVrfEntryHandler.class);
private static final int BATCH_INTERVAL = 500;
}
}
+ @Override
+ public void updateContainer(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier,
+ Object original, Object update, List<SubTransaction> transactionObjects) {
+ }
+
@Override
public void create(WriteTransaction tx, LogicalDatastoreType datastoreType, InstanceIdentifier identifier,
Object vrfEntry, List<SubTransaction> subTxns) {
}
}
- @Override
- public void createFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry, String rd) {
- ActionableResource actResource = new ActionableResourceImpl(rd + vrfEntry.getDestPrefix());
- actResource.setAction(ActionableResource.CREATE);
- actResource.setInstanceIdentifier(identifier);
- actResource.setInstance(vrfEntry);
- vrfEntryBufferQ.add(actResource);
+ void createFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry, String rd) {
+ vrfEntryBufferQ.add(ActionableResources.create(new ActionableResourceIdentifier(rd, vrfEntry.getDestPrefix()),
+ identifier, vrfEntry));
}
- @Override
- public void removeFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry, String rd) {
- ActionableResource actResource = new ActionableResourceImpl(rd + vrfEntry.getDestPrefix());
- actResource.setAction(ActionableResource.DELETE);
- actResource.setInstanceIdentifier(identifier);
- actResource.setInstance(vrfEntry);
- vrfEntryBufferQ.add(actResource);
+ void removeFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry, String rd) {
+ vrfEntryBufferQ.add(ActionableResources.delete(new ActionableResourceIdentifier(rd, vrfEntry.getDestPrefix()),
+ identifier, vrfEntry));
}
- @Override
- public void updateFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry original, VrfEntry update, String rd) {
- ActionableResource actResource = new ActionableResourceImpl(rd + update.getDestPrefix());
- actResource.setAction(ActionableResource.UPDATE);
- actResource.setInstanceIdentifier(identifier);
- actResource.setInstance(update);
- actResource.setOldInstance(original);
- vrfEntryBufferQ.add(actResource);
+ void updateFlows(InstanceIdentifier<VrfEntry> identifier, VrfEntry original, VrfEntry update, String rd) {
+ vrfEntryBufferQ.add(ActionableResources.update(new ActionableResourceIdentifier(rd, update.getDestPrefix()),
+ identifier, update, original));
}
/*
private void createFibEntries(WriteTransaction writeTx, final InstanceIdentifier<VrfEntry> vrfEntryIid,
final VrfEntry vrfEntry, List<SubTransaction> subTxns) {
final VrfTablesKey vrfTableKey = vrfEntryIid.firstKeyOf(VrfTables.class);
-
+ LOG.trace("Creating fib entry for vrfEntry with destPrefix{}, rd {}",
+ vrfEntry.getDestPrefix(), vrfTableKey.getRouteDistinguisher());
final VpnInstanceOpDataEntry vpnInstance =
getFibUtil().getVpnInstance(vrfTableKey.getRouteDistinguisher());
- 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();
- if (vpnToDpnList != null) {
- for (VpnToDpnList vpnDpn : vpnToDpnList) {
+ if (vpnInstance == null || vpnInstance.getVpnId() == null) {
+ LOG.error("Vpn Instance not availabe {}", vrfTableKey.getRouteDistinguisher());
+ return;
+ }
+ final Map<VpnToDpnListKey, VpnToDpnList> keyVpnToDpnListMap = vpnInstance.nonnullVpnToDpnList();
+ if (keyVpnToDpnListMap != null) {
+ for (VpnToDpnList vpnDpn : keyVpnToDpnListMap.values()) {
+ LOG.trace("Dpnstate is {} for dpn {} in vpn {}", vpnDpn.getDpnState(), vpnDpn.getDpnId(),
+ vpnInstance.getVpnId());
if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
- createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey.getRouteDistinguisher(),
- vrfEntry, writeTx, subTxns);
+ createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(),
+ vrfTableKey.getRouteDistinguisher(), vrfEntry, writeTx, subTxns);
}
}
}
+ LOG.trace("Created fib entry for vrfEntry with destPrefix{}, rd {}",
+ vrfEntry.getDestPrefix(), vrfTableKey.getRouteDistinguisher());
}
/*
return;
}
String vpnName = getFibUtil().getVpnNameFromId(vpnInstance.getVpnId());
- final Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
- if (vpnToDpnList != null) {
+ final Map<VpnToDpnListKey, VpnToDpnList> keyVpnToDpnListMap = vpnInstance.nonnullVpnToDpnList();
+ if (keyVpnToDpnListMap != null) {
List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker,
vpnInstance.getVpnId(), vrfEntry.getDestPrefix());
Optional<Routes> extraRouteOptional;
usedRds.get(0), vrfEntry.getDestPrefix());
}
} else {
- extraRouteOptional = Optional.absent();
+ extraRouteOptional = Optional.empty();
}
- for (VpnToDpnList curDpn : vpnToDpnList) {
+ for (VpnToDpnList curDpn : keyVpnToDpnListMap.values()) {
if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
- deleteRemoteRoute(BigInteger.ZERO, curDpn.getDpnId(), vpnInstance.getVpnId(),
+ deleteRemoteRoute(Uint64.ZERO, curDpn.getDpnId(), vpnInstance.getVpnId(),
vrfTableKey, vrfEntry, extraRouteOptional, writeTx, subTxns);
}
}
}
}
- public void programRemoteFibForBgpRoutes(final BigInteger remoteDpnId,
- final long vpnId,
+ public void programRemoteFibForBgpRoutes(final Uint64 remoteDpnId,
+ final Uint32 vpnId,
final VrfEntry vrfEntry,
WriteTransaction tx,
String rd,
List<NexthopManager.AdjacencyResult> adjacencyResults,
List<SubTransaction> subTxns) {
- Preconditions.checkArgument(vrfEntry.getRoutePaths().size() <= 2);
-
+ if (vrfEntry.nonnullRoutePaths().size() > 2) {
+ LOG.error("DC-GW can advertise only 2 bestPaths for prefix {}", vrfEntry.getDestPrefix());
+ return;
+ }
+ LOG.trace("Start programming remote fib for destPrefix {}, vpnId {}, dpnId {}",
+ vrfEntry.getDestPrefix(), vpnId, remoteDpnId);
if (adjacencyResults.size() == 1) {
programRemoteFib(remoteDpnId, vpnId, vrfEntry, tx, rd, adjacencyResults, subTxns);
return;
List<ActionInfo> actionInfos = new ArrayList<>();
for (NexthopManager.AdjacencyResult adjResult : adjacencyResults) {
String nextHopIp = adjResult.getNextHopIp();
- java.util.Optional<Long> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
+ java.util.Optional<Uint32> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
if (!optionalLabel.isPresent()) {
LOG.warn("NextHopIp {} not found in vrfEntry {}", nextHopIp, vrfEntry);
continue;
}
- long label = optionalLabel.get();
+ long label = optionalLabel.get().toJava();
actionInfos.add(new ActionRegLoad(index, FibConstants.NXM_REG_MAPPING.get(index++), 0,
31, label));
actionInfos.add(new ActionGroup(index, groupId));
instructions.add(new InstructionApplyActions(actionInfos));
makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
+ LOG.trace("End programming remote fib for destPrefix {}, vpnId {}, dpnId {}",
+ vrfEntry.getDestPrefix(), vpnId, remoteDpnId);
}
- public void createRemoteFibEntry(final BigInteger remoteDpnId,
- final long vpnId,
+ // Allow deprecated TransactionRunner calls for now
+ @SuppressWarnings("ForbidCertainMethod")
+ public void createRemoteFibEntry(final Uint64 remoteDpnId,
+ final Uint32 vpnId,
final String rd,
final VrfEntry vrfEntry,
WriteTransaction tx,
LOG.debug("Successfully added FIB entry for prefix {} in vpnId {}", vrfEntry.getDestPrefix(), vpnId);
}
- private void deleteFibEntryForBgpRoutes(BigInteger remoteDpnId, long vpnId, VrfEntry vrfEntry,
+ private void deleteFibEntryForBgpRoutes(Uint64 remoteDpnId, Uint32 vpnId, VrfEntry vrfEntry,
String rd, WriteTransaction tx, List<SubTransaction> subTxns) {
// When the tunnel is removed the fib entries should be reprogrammed/deleted depending on
// the adjacencyResults.
}
}
- public void deleteRemoteRoute(final BigInteger localDpnId, final BigInteger remoteDpnId,
- final long vpnId, final VrfTablesKey vrfTableKey,
+ // Allow deprecated TransactionRunner calls for now
+ @SuppressWarnings("ForbidCertainMethod")
+ public void deleteRemoteRoute(@Nullable final Uint64 localDpnId, final Uint64 remoteDpnId,
+ final Uint32 vpnId, final VrfTablesKey vrfTableKey,
final VrfEntry vrfEntry, Optional<Routes> extraRouteOptional,
- WriteTransaction tx, List<SubTransaction> subTxns) {
+ @Nullable WriteTransaction tx, List<SubTransaction> subTxns) {
if (tx == null) {
ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
newTx -> deleteRemoteRoute(localDpnId, remoteDpnId, vpnId, vrfTableKey, vrfEntry,
vrfEntry.getDestPrefix(), vpnId, localDpnId, remoteDpnId);
String rd = vrfTableKey.getRouteDistinguisher();
- if (localDpnId != null && localDpnId != BigInteger.ZERO) {
+ if (localDpnId != null && !Uint64.ZERO.equals(localDpnId)) {
// localDpnId is not known when clean up happens for last vm for a vpn on a dpn
if (extraRouteOptional.isPresent()) {
- nexthopManager.setupLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix(),
- Collections.emptyList() /*listBucketInfo*/ , false);
+ nexthopManager.deleteLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix());
}
deleteFibEntryForBgpRoutes(remoteDpnId, vpnId, vrfEntry, rd, tx, subTxns);
return;
// below two reads are kept as is, until best way is found to identify dpnID
VpnNexthop localNextHopInfo = nexthopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
if (extraRouteOptional.isPresent()) {
- nexthopManager.setupLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix(),
- Collections.emptyList() /*listBucketInfo*/ , false);
+ nexthopManager.deleteLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix());
} else {
checkDpnDeleteFibEntry(localNextHopInfo, remoteDpnId, vpnId, vrfEntry, rd, tx, subTxns);
}
}
public Consumer<? super VrfEntry> getConsumerForCreatingRemoteFib(
- final BigInteger dpnId, final long vpnId, final String rd,
+ final Uint64 dpnId, final Uint32 vpnId, final String rd,
final String remoteNextHopIp, final Optional<VrfTables> vrfTable,
WriteTransaction writeCfgTxn, List<SubTransaction> subTxns) {
- return vrfEntry -> vrfEntry.getRoutePaths().stream()
+ return vrfEntry -> vrfEntry.nonnullRoutePaths().values().stream()
.filter(routes -> !routes.getNexthopAddress().isEmpty()
&& remoteNextHopIp.trim().equals(routes.getNexthopAddress().trim()))
.findFirst()
}
public Consumer<? super VrfEntry> getConsumerForDeletingRemoteFib(
- final BigInteger dpnId, final long vpnId,
+ final Uint64 dpnId, final Uint32 vpnId,
final String remoteNextHopIp, final Optional<VrfTables> vrfTable,
WriteTransaction writeCfgTxn, List<SubTransaction> subTxns) {
- return vrfEntry -> vrfEntry.getRoutePaths().stream()
+ return vrfEntry -> vrfEntry.nonnullRoutePaths().values().stream()
.filter(routes -> !routes.getNexthopAddress().isEmpty()
&& remoteNextHopIp.trim().equals(routes.getNexthopAddress().trim()))
.findFirst()
.ifPresent(routes -> {
LOG.trace(" deleting remote FIB entry {}", vrfEntry);
deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().key(), vrfEntry,
- Optional.absent(), writeCfgTxn, subTxns);
+ Optional.empty(), writeCfgTxn, subTxns);
});
}
@Override
- protected void addTunnelInterfaceActions(NexthopManager.AdjacencyResult adjacencyResult, long vpnId,
+ protected void addTunnelInterfaceActions(NexthopManager.AdjacencyResult adjacencyResult, Uint32 vpnId,
VrfEntry vrfEntry, List<ActionInfo> actionInfos, String rd) {
Class<? extends TunnelTypeBase> tunnelType = VpnExtraRouteHelper
.getTunnelType(getNextHopManager().getItmManager(), adjacencyResult.getInterfaceName());
}
String nextHopIp = adjacencyResult.getNextHopIp();
if (tunnelType.equals(TunnelTypeMplsOverGre.class)) {
- java.util.Optional<Long> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
+ java.util.Optional<Uint32> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
if (!optionalLabel.isPresent()) {
LOG.warn("NextHopIp {} not found in vrfEntry {}", nextHopIp, vrfEntry);
return;
}
- long label = optionalLabel.get();
+ long label = optionalLabel.get().toJava();
LOG.debug("addTunnelInterfaceActions: Push label action for prefix {} rd {} l3vni {} nextHop {}",
vrfEntry.getDestPrefix(), rd, vrfEntry.getL3vni(), nextHopIp);
actionInfos.add(new ActionPushMpls());
actionInfos.add(new ActionSetFieldMplsLabel(label));
- actionInfos.add(new ActionNxLoadInPort(BigInteger.ZERO));
+ actionInfos.add(new ActionNxLoadInPort(Uint64.ZERO));
} else if (tunnelType.equals(TunnelTypeVxlan.class)) {
- actionInfos.add(new ActionSetFieldTunnelId(BigInteger.valueOf(vrfEntry.getL3vni())));
+ actionInfos.add(new ActionSetFieldTunnelId(Uint64.valueOf(vrfEntry.getL3vni().longValue())));
LOG.debug("addTunnelInterfaceActions: adding set tunnel id action for prefix {} rd {} l3vni {}"
+ " nextHop {} ", vrfEntry.getDestPrefix(), rd, vrfEntry.getL3vni(), nextHopIp);
addRewriteDstMacAction(vpnId, vrfEntry, null /*prefixInfo*/, actionInfos);
}
@Override
- protected void addRewriteDstMacAction(long vpnId, VrfEntry vrfEntry, Prefixes prefixInfo,
- List<ActionInfo> actionInfos) {
+ protected void addRewriteDstMacAction(Uint32 vpnId, VrfEntry vrfEntry, @Nullable Prefixes prefixInfo,
+ List<ActionInfo> actionInfos) {
if (vrfEntry.getGatewayMacAddress() != null) {
actionInfos.add(new ActionSetFieldEthernetDestination(actionInfos.size(),
new MacAddress(vrfEntry.getGatewayMacAddress())));