int INVALID_PORT_NO = -1;
int DEFAULT_FLOW_PRIORITY = 5;
String OF_URI_SEPARATOR = ":";
+ int INVALID_ID = 0;
}
import java.math.BigInteger;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorker;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorkerForNodeConnector;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
import org.opendaylight.infrautils.caches.CacheProvider;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
@Singleton
public class OfDpnTepConfigCache extends DataObjectCache<BigInteger, OfDpnTep> {
+ private static final Logger LOG = LoggerFactory.getLogger(OfDpnTepConfigCache.class);
+ private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
+ private final DirectTunnelUtils directTunnelUtils;
+ private final UnprocessedOFNodeConnectorCache unprocessedOFNCCache;
+ private final ManagedNewTransactionRunner txRunner;
+ private final JobCoordinator coordinator;
+
@Inject
- public OfDpnTepConfigCache(DataBroker dataBroker, CacheProvider cacheProvider) {
+ public OfDpnTepConfigCache(DataBroker dataBroker, JobCoordinator coordinator,
+ CacheProvider cacheProvider,
+ DirectTunnelUtils directTunnelUtils,
+ UnprocessedOFNodeConnectorCache unprocessedOFNCCache) {
super(OfDpnTep.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
InstanceIdentifier.builder(DpnTepConfig.class).child(OfDpnTep.class).build(), cacheProvider,
(iid, dpnsTeps) -> dpnsTeps.getSourceDpnId().toJava(),
sourceDpnId -> InstanceIdentifier.builder(DpnTepConfig.class)
.child(OfDpnTep.class, new OfDpnTepKey(Uint64.valueOf(sourceDpnId))).build());
+ this.directTunnelUtils = directTunnelUtils;
+ this.unprocessedOFNCCache = unprocessedOFNCCache;
+ this.coordinator = coordinator;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ }
+
+ @Override
+ protected void added(InstanceIdentifier<OfDpnTep> path, OfDpnTep ofDpnTep) {
+ NodeConnectorInfo nodeConnectorInfo = null;
+ try (Acquired lock = directTunnelUtils.lockTunnel(ofDpnTep.getOfPortName())) {
+ if (unprocessedOFNCCache.get(ofDpnTep.getOfPortName()) != null) {
+ nodeConnectorInfo = unprocessedOFNCCache.remove(ofDpnTep.getOfPortName());
+ }
+ }
+
+ if (nodeConnectorInfo != null && directTunnelUtils.isEntityOwner()) {
+
+ OfPortStateAddWorkerForNodeConnector ifOfStateAddWorker =
+ new OfPortStateAddWorkerForNodeConnector(new OfPortStateAddWorker(directTunnelUtils,
+ ofDpnTep, txRunner), nodeConnectorInfo);
+ LOG.debug("ITM-Of-tepInventoryState Entity Owner,ADD {} {}",
+ ofDpnTep.getSourceDpnId(), ofDpnTep.getOfPortName());
+ EVENT_LOGGER.debug("ITM-Of-tepInventoryState Entity Owner,ADD {} {}",
+ ofDpnTep.getSourceDpnId(), ofDpnTep.getOfPortName());
+ coordinator.enqueueJob(ofDpnTep.getOfPortName(), ifOfStateAddWorker, ITMConstants.JOB_MAX_RETRIES);
+ }
}
}
*/
package org.opendaylight.genius.itm.cache;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.itm.servicebinding.BindServiceUtils;
import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
import org.opendaylight.infrautils.caches.CacheProvider;
import org.opendaylight.mdsal.binding.api.DataBroker;
@Singleton
public class OfTepStateCache extends DataObjectCache<String, OfTep> {
+ private final ManagedNewTransactionRunner txRunner;
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
private static final Logger LOG = LoggerFactory.getLogger(OfTepStateCache.class);
@Inject
InstanceIdentifier.builder(OfTepsState.class).child(OfTep.class).build(), cacheProvider,
(iid, ofTepList) -> ofTepList.getOfPortName(), ofPortName -> InstanceIdentifier.builder(OfTepsState.class)
.child(OfTep.class, new OfTepKey(ofPortName)).build());
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ }
+
+ protected void added(InstanceIdentifier<OfTep> path, OfTep ofTep) {
+ LOG.info("Binding default egress dispatcher service for{}", ofTep.getOfPortName());
+ BindServiceUtils.bindDefaultEgressDispatcherService(txRunner, futures, "VXLAN_TRUNK_INTERFACE",
+ String.valueOf(ofTep.getPortNumber()), ofTep.getOfPortName(),
+ ofTep.getIfIndex());
}
}
--- /dev/null
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.cache;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.inject.Singleton;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
+
+@Singleton
+public class UnprocessedOFNodeConnectorCache {
+
+ private final ConcurrentMap<String, NodeConnectorInfo> unprocessedOFNodeConnectorMap = new ConcurrentHashMap<>();
+
+ public void add(String ofPortName, NodeConnectorInfo nodeConnectorInfo) {
+ unprocessedOFNodeConnectorMap.put(ofPortName, nodeConnectorInfo);
+ }
+
+ public NodeConnectorInfo get(String ofPortName) {
+ return unprocessedOFNodeConnectorMap.get(ofPortName);
+ }
+
+ public NodeConnectorInfo remove(String ofPortName) {
+ return unprocessedOFNodeConnectorMap.remove(ofPortName);
+ }
+
+ public ConcurrentMap<String, NodeConnectorInfo> getAllPresent() {
+ return unprocessedOFNodeConnectorMap;
+ }
+}
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.OfTepsState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeExternal;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeHwvtep;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
return InstanceIdentifier.builder(TunnelsState.class).child(StateTunnelList.class, tlKey).build();
}
+ public static InstanceIdentifier<OfTep> buildStateOfTepListId(OfTepKey ofTepKey) {
+ return InstanceIdentifier.builder(OfTepsState.class)
+ .child(OfTep.class, ofTepKey).build();
+ }
+
@NonNull
public static Optional<InternalTunnel> getInternalTunnelFromDS(Uint64 srcDpn, Uint64 destDpn,
Class<? extends TunnelTypeBase> type,
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
import org.opendaylight.genius.itm.cache.TunnelStateCache;
import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
+import org.opendaylight.genius.itm.cache.UnprocessedOFNodeConnectorCache;
import org.opendaylight.genius.itm.globals.ITMConstants;
import org.opendaylight.genius.itm.impl.ItmUtils;
import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorker;
+import org.opendaylight.genius.itm.itmdirecttunnels.workers.OfPortStateAddWorkerForNodeConnector;
import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorker;
import org.opendaylight.genius.itm.itmdirecttunnels.workers.TunnelStateAddWorkerForNodeConnector;
import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
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.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
private final UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
private final DirectTunnelUtils directTunnelUtils;
private final ConcurrentMap<String, NodeConnectorInfo> meshedMap = new ConcurrentHashMap<>();
+ private final UnprocessedOFNodeConnectorCache unprocessedOFNCCache;
+ private final OfDpnTepConfigCache ofDpnTepConfigCache;
+ private final IInterfaceManager interfaceManager;
public TunnelInventoryStateListener(final DataBroker dataBroker,
final JobCoordinator coordinator,
final UnprocessedNodeConnectorCache unprocessedNCCache,
final UnprocessedNodeConnectorEndPointCache
unprocessedNodeConnectorEndPointCache,
- final DirectTunnelUtils directTunnelUtils) {
+ final DirectTunnelUtils directTunnelUtils,
+ UnprocessedOFNodeConnectorCache unprocessedOFNCCache,
+ final OfDpnTepConfigCache ofDpnTepConfigCache,
+ final IInterfaceManager interfaceManager) {
super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class)
.child(NodeConnector.class).augmentation(FlowCapableNodeConnector.class));
this.coordinator = coordinator;
this.unprocessedNCCache = unprocessedNCCache;
this.unprocessedNodeConnectorEndPointCache = unprocessedNodeConnectorEndPointCache;
this.directTunnelUtils = directTunnelUtils;
+ this.unprocessedOFNCCache = unprocessedOFNCCache;
+ this.ofDpnTepConfigCache = ofDpnTepConfigCache;
+ this.interfaceManager = interfaceManager;
super.register();
}
@NonNull FlowCapableNodeConnector fcNodeConnectorNew) {
EVENT_LOGGER.debug("ITM-TunnelInventoryState,UPDATE DTCN received for {}", fcNodeConnectorOld.getName());
String portName = fcNodeConnectorNew.getName();
- if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)) {
+ if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
LOG.debug("Node Connector Update - {} Interface is not a tunnel I/f, so no-op", portName);
return;
} else if (!dpnTepStateCache.isInternal(portName)) {
return;
}
+ //Optional<OfDpnTep> dpnTepOptional = Optional.ofNullable(null);
NodeConnectorInfo nodeConnectorInfo =
new NodeConnectorInfoBuilder().setNodeConnectorId(key).setNodeConnector(fcNodeConnectorNew).build();
- if (portName.startsWith("of")) {
+ if (portName.startsWith("of") && interfaceManager.isItmOfTunnelsEnabled()) {
NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class))
.getId();
- String srcDpn = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId).toString();
-
- if (meshedMap.isEmpty()) {
- meshedMap.put(srcDpn, nodeConnectorInfo);
- return;
- } else {
- for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
- DpnTepInterfaceInfo infInfoForward = dpnTepStateCache.getDpnTepInterface(Uint64.valueOf(srcDpn),
- Uint64.valueOf(entry.getKey()));
- if (infInfoForward == null) {
- unprocessedNCCache.add(srcDpn + ":" + entry.getKey(),
- new TunnelStateInfoBuilder().setNodeConnectorInfo(nodeConnectorInfo).build());
+ Uint64 srcDpn = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
+
+ OfDpnTep dpntep = null;
+ try (Acquired lock = directTunnelUtils.lockTunnel(portName)) {
+ try {
+ Optional<OfDpnTep> dpnTepOptional = ofDpnTepConfigCache.get(srcDpn.toJava());
+ if (!dpnTepOptional.isPresent()) {
+ // Park the notification
+ LOG.debug("Unable to process the NodeConnector ADD event for {} as Config not available."
+ + "Hence parking it", portName);
+ unprocessedOFNCCache.add(portName, nodeConnectorInfo);
+ return;
} else {
- addTunnelState(nodeConnectorInfo, infInfoForward.getTunnelName());
- }
-
- DpnTepInterfaceInfo infInfoReverse = dpnTepStateCache.getDpnTepInterface(
- Uint64.valueOf(entry.getKey()), Uint64.valueOf(srcDpn));
-
- if (infInfoReverse == null) {
- unprocessedNCCache.add(entry.getKey() + ":" + srcDpn,
- new TunnelStateInfoBuilder().setNodeConnectorInfo(entry.getValue()).build());
- } else {
- addTunnelState(entry.getValue(), infInfoReverse.getTunnelName());
+ dpntep = dpnTepOptional.get();
}
+ } catch (ReadFailedException e) {
+ LOG.error("unable to get ofDpnTepConfigCache");
}
}
- meshedMap.put(srcDpn, nodeConnectorInfo);
+
+ if (dpntep != null) {
+ OfPortStateAddWorkerForNodeConnector ifOfStateAddWorker =
+ new OfPortStateAddWorkerForNodeConnector(new OfPortStateAddWorker(directTunnelUtils,
+ dpntep, txRunner), nodeConnectorInfo);
+ EVENT_LOGGER.debug("ITM-Of-tepInventoryState Entity Owner,ADD {} {}",
+ nodeConnectorId.getValue(), portName);
+ coordinator.enqueueJob(portName, ifOfStateAddWorker, ITMConstants.JOB_MAX_RETRIES);
+ }
} else {
addTunnelState(nodeConnectorInfo, portName);
}
}
if (tunnelEndPtInfo != null && tunnelStateInfo.getSrcDpnTepsInfo() != null
- && tunnelStateInfo.getDstDpnTepsInfo() != null && directTunnelUtils.isEntityOwner()) {
+ && tunnelStateInfo.getDstDpnTepsInfo() != null) {
EVENT_LOGGER.debug("ITM-TunnelInventoryState Entity Owner,ADD {}", portName);
coordinator.enqueueJob(portName,
new TunnelStateAddWorkerForNodeConnector(new TunnelStateAddWorker(directTunnelUtils, txRunner),
import org.opendaylight.genius.itm.cache.BfdStateCache;
import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
import org.opendaylight.genius.itm.cache.TunnelStateCache;
import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
+import org.opendaylight.genius.itm.cache.UnprocessedOFNodeConnectorCache;
import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
import org.opendaylight.genius.itm.listeners.RemoteDpnListener;
import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
final TunnelStateCache tunnelStateCache,
final UnprocessedNodeConnectorCache unprocessedNodeConnectorCache,
final UnprocessedNodeConnectorEndPointCache
- unprocessedNodeConnectorEndPointCache) {
+ unprocessedNodeConnectorEndPointCache,
+ final UnprocessedOFNodeConnectorCache unprocessedOFNodeConnectorCache,
+ final OfDpnTepConfigCache ofDpnTepConfigCache) {
if (interfaceManager.isItmDirectTunnelsEnabled()) {
LOG.debug("ITM Direct Tunnels is enabled. Initializing the listeners");
this.tunnelTopologyStateListener = new TunnelTopologyStateListener(dataBroker, coordinator,
directTunnelUtils, dpnTepStateCache, ovsBridgeEntryCache);
this.tunnelInventoryStateListener = new TunnelInventoryStateListener(dataBroker, coordinator,
tunnelStateCache, dpnTepStateCache, dpntePsInfoCache, unprocessedNodeConnectorCache,
- unprocessedNodeConnectorEndPointCache, directTunnelUtils);
+ unprocessedNodeConnectorEndPointCache, directTunnelUtils, unprocessedOFNodeConnectorCache,
+ ofDpnTepConfigCache, interfaceManager);
this.terminationPointStateListener = new TerminationPointStateListener(dataBroker, entityOwnershipUtils,
coordinator, bfdStateCache, dpnTepStateCache,tunnelStateCache);
this.interfaceConfigListener = new InterfaceConfigListener(dataBroker, coordinator);
--- /dev/null
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.itmdirecttunnels.workers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
+import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
+import org.opendaylight.genius.itm.impl.ItmUtils;
+import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
+import org.opendaylight.mdsal.binding.util.Datastore;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.IfIndexesTunnelMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class OfPortStateAddWorker {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OfPortStateAddWorker.class);
+ private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
+
+ private final DirectTunnelUtils directTunnelUtils;
+ private final OfDpnTep dpnTep;
+ private final ManagedNewTransactionRunner txRunner;
+
+ public OfPortStateAddWorker(final DirectTunnelUtils directTunnelUtils, final OfDpnTep dpnTep,
+ final ManagedNewTransactionRunner txRunner) {
+ this.directTunnelUtils = directTunnelUtils;
+ this.dpnTep = dpnTep;
+ this.txRunner = txRunner;
+ }
+
+ public List<? extends ListenableFuture<?>> addState(NodeConnectorInfo nodeConnectorInfo)
+ throws ExecutionException, InterruptedException, OperationFailedException {
+ // When this method is invoked, all parameters necessary should be available
+ // Retrieve Port No from nodeConnectorId
+ NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(
+ nodeConnectorInfo.getNodeConnectorId().firstIdentifierOf(NodeConnector.class)).getId();
+ String ofPortName = nodeConnectorInfo.getNodeConnector().getName();
+ long portNo = DirectTunnelUtils.getPortNumberFromNodeConnectorId(nodeConnectorId);
+ EVENT_LOGGER.debug("ITM-Of Port State, ADD to oper DS {}", ofPortName);
+ if (portNo == ITMConstants.INVALID_PORT_NO) {
+ LOG.error("Cannot derive port number, not proceeding with of-port State "
+ + "addition for of-port: {}", ofPortName);
+ return null;
+ }
+
+ LOG.info("adding of-port state to Oper DS for interface: {}", ofPortName);
+ OfTep ofTep = addStateEntry(ofPortName, portNo);
+
+ // If this interface is a of-port interface, create the of-port ingress flow
+ if (ofTep != null) {
+ return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
+ tx -> {
+ Uint64 dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
+ directTunnelUtils.addTunnelIngressFlow(tx, dpId, portNo, ofPortName,
+ ofTep.getIfIndex().toJava(),
+ ofTep.getTepIp().getIpv4Address());
+ }));
+ }
+ EVENT_LOGGER.debug("ITM-of-port,ADD Table 0 flow for {} completed", ofPortName);
+ return Collections.emptyList();
+ }
+
+ private OfTep addStateEntry(String ofPortName, long portNo)
+ throws ExecutionException, InterruptedException, OperationFailedException {
+ final int ifIndex = directTunnelUtils.allocateId(IfmConstants.IFM_IDPOOL_NAME, ofPortName);
+ if (ifIndex == ITMConstants.INVALID_ID) {
+ LOG.trace("aborting addStateEntry for {}, due to invalid Id", ofPortName);
+ return null;
+ }
+ createLportTagInterfaceMap(ofPortName, ifIndex);
+ final OfTepBuilder ofTepBuilder = new OfTepBuilder();
+
+ Interface.OperStatus operStatus = Interface.OperStatus.Up;
+
+ TunnelOperStatus tunnelOperStatus = DirectTunnelUtils.convertInterfaceToTunnelOperState(operStatus);
+
+ OfTepKey ofTepKey = new OfTepKey(ofPortName);
+ ofTepBuilder.withKey(ofTepKey).setTunnelType(dpnTep.getTunnelType()).setOfPortName(ofPortName)
+ .setTepIp(dpnTep.getTepIp()).setPortNumber(String.valueOf(portNo))
+ .setIfIndex(Uint16.valueOf(ifIndex)).setOfTepState(tunnelOperStatus)
+ .setSourceDpnId(dpnTep.getSourceDpnId());
+
+ InstanceIdentifier<OfTep> ofTepsListId = ItmUtils.buildStateOfTepListId(ofTepKey);
+ LOG.trace("Batching the Creation of tunnel_state: {} for Id: {}", ofTepBuilder.build(), ofTepsListId);
+ ITMBatchingUtils.write(ofTepsListId, ofTepBuilder.build(), ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
+ return ofTepBuilder.build();
+ }
+
+ private void createLportTagInterfaceMap(String infName, Integer ifIndex) {
+ LOG.debug("creating lport tag to interface map for {}", infName);
+ InstanceIdentifier<IfIndexTunnel> id = InstanceIdentifier.builder(IfIndexesTunnelMap.class)
+ .child(IfIndexTunnel.class, new IfIndexTunnelKey(ifIndex)).build();
+ IfIndexTunnel ifIndexInterface = new IfIndexTunnelBuilder().setIfIndex(ifIndex)
+ .withKey(new IfIndexTunnelKey(ifIndex)).setInterfaceName(infName).build();
+ ITMBatchingUtils.write(id, ifIndexInterface, ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.itmdirecttunnels.workers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.opendaylight.genius.itm.utils.NodeConnectorInfo;
+
+public class OfPortStateAddWorkerForNodeConnector implements Callable<List<? extends ListenableFuture<?>>> {
+ private final OfPortStateAddWorker ofPortStateAddWorker;
+ private final NodeConnectorInfo nodeConnectorInfo;
+ private final ConcurrentMap<String, NodeConnectorInfo> ofPortStateInfo = new ConcurrentHashMap<>();
+
+ public OfPortStateAddWorkerForNodeConnector(OfPortStateAddWorker ofPortStateAddWorker,
+ NodeConnectorInfo nodeConnectorInfo) {
+ this.ofPortStateAddWorker = ofPortStateAddWorker;
+ this.nodeConnectorInfo = nodeConnectorInfo;
+ }
+
+ @Override
+ public List<? extends ListenableFuture<?>> call() throws Exception {
+ // If another renderer(for eg : OVS) needs to be supported, check can be performed here
+ // to call the respective helpers.
+ return ofPortStateAddWorker.addState(nodeConnectorInfo);
+ }
+
+ @Override
+ public String toString() {
+ return "OfPortStateAddWorkerForNodeConnector{"
+ + "ofStateInfo=" + ofPortStateInfo
+ + '}';
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.itm.servicebinding;
+
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
+import org.opendaylight.genius.itm.globals.ITMConstants;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MetaDataUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
+import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
+import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
+import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
+import org.opendaylight.genius.utils.ServiceIndex;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.opendaylight.yangtools.yang.common.Uint8;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BindServiceUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BindServiceUtils.class);
+
+ private BindServiceUtils() {
+ throw new IllegalStateException("Utility class");
+ }
+
+ public static void bindDefaultEgressDispatcherService(ManagedNewTransactionRunner txRunner,
+ List<ListenableFuture<Void>> futures, String tunType,
+ String portNo, String interfaceName, Uint16 ifIndex) {
+ Map<InstructionKey, Instruction> instructions =
+ getEgressInstructionsForInterface(tunType, portNo, null, true, ifIndex, 0);
+ bindDefaultEgressDispatcherService(txRunner, futures, interfaceName, instructions);
+ }
+
+ public static void bindDefaultEgressDispatcherService(ManagedNewTransactionRunner txRunner,
+ List<ListenableFuture<Void>> futures,
+ String interfaceName,
+ Map<InstructionKey, Instruction> instructions) {
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+ int priority = ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME,
+ NwConstants.DEFAULT_EGRESS_SERVICE_INDEX);
+ BoundServices serviceInfo =
+ getBoundServices(String.format("%s.%s", "default", interfaceName),
+ ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME,
+ NwConstants.DEFAULT_EGRESS_SERVICE_INDEX),
+ priority, NwConstants.EGRESS_DISPATCHER_TABLE_COOKIE, instructions);
+ bindService(tx, interfaceName, serviceInfo, ServiceModeEgress.class);
+ }));
+ }
+
+ public static Map<InstructionKey, Instruction> getEgressInstructionsForInterface(String tunType,String portNo,
+ Long tunnelKey,
+ boolean isDefaultEgress,
+ Uint16 ifIndex, long groupId) {
+ Map<InstructionKey, Instruction> instructions = new HashMap<>();
+ List<Action> actionList = MDSALUtil.buildActions(
+ getEgressActionInfosForInterface(tunType, portNo, tunnelKey, 0,
+ isDefaultEgress, ifIndex, groupId));
+ Instruction inst = MDSALUtil.buildApplyActionsInstruction(actionList);
+ instructions.put(inst.key(), inst);
+ return instructions;
+ }
+
+ public static List<ActionInfo> getEgressActionInfosForInterface(String tunType, String portNo,
+ Long tunnelKey,
+ int actionKeyStart, boolean isDefaultEgress,
+ Uint16 ifIndex, long groupId) {
+ List<ActionInfo> result = new ArrayList<>();
+ switch (tunType) {
+ case "MPLS_OVER_GRE":
+ // fall through
+ case "GRE_TRUNK_INTERFACE":
+ if (!isDefaultEgress) {
+ // TODO tunnel_id to encode GRE key, once it is supported
+ // Until then, tunnel_id should be "cleaned", otherwise it
+ // stores the value coming from a VXLAN tunnel
+ if (tunnelKey == null) {
+ tunnelKey = 0L;
+ }
+ result.add(new ActionSetFieldTunnelId(actionKeyStart++, Uint64.valueOf(tunnelKey)));
+ addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+ } else {
+ result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
+ }
+ break;
+ // fall through
+ case "VXLAN_TRUNK_INTERFACE":
+ if (!isDefaultEgress) {
+ if (tunnelKey != null) {
+ result.add(new ActionSetFieldTunnelId(actionKeyStart++, Uint64.valueOf(tunnelKey)));
+ }
+ addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+ } else {
+ result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
+ }
+ break;
+ case "VLAN_INTERFACE":
+ LOG.error("VLAN swicth case");
+ if (isDefaultEgress) {
+ result.add(new ActionOutput(actionKeyStart++, new Uri(portNo)));
+ } else {
+ addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+ }
+ break;
+ case "LOGICAL_GROUP_INTERFACE":
+ if (isDefaultEgress) {
+ result.add(new ActionGroup(groupId));
+ } else {
+ addEgressActionInfosForInterface(ifIndex, actionKeyStart, result);
+ }
+ break;
+
+ default:
+ LOG.warn("Interface Type {} not handled yet", tunType);
+ break;
+ }
+ return result;
+ }
+
+ public static void addEgressActionInfosForInterface(Uint16 ifIndex, int actionKeyStart, List<ActionInfo> result) {
+ long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex.intValue(),
+ NwConstants.DEFAULT_SERVICE_INDEX);
+ result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, ITMConstants.REG6_START_INDEX,
+ ITMConstants.REG6_END_INDEX, regValue));
+ result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE));
+ }
+
+ public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
+ Uint64 cookie, Map<InstructionKey, Instruction> instructions) {
+ StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie)
+ .setFlowPriority(Uint16.valueOf(flowPriority))
+ .setInstruction(instructions);
+ return new BoundServicesBuilder()
+ .withKey(new BoundServicesKey(Uint8.valueOf(servicePriority)))
+ .setServiceName(serviceName)
+ .setServicePriority(Uint8.valueOf(servicePriority))
+ .setServiceType(ServiceTypeFlowBased.class)
+ .addAugmentation(augBuilder.build()).build();
+ }
+
+ public static void bindService(TypedWriteTransaction<Datastore.Configuration> tx, String interfaceName,
+ BoundServices serviceInfo,
+ Class<? extends ServiceModeBase> serviceMode) {
+ LOG.info("Binding Service {} for : {}", serviceInfo.getServiceName(), interfaceName);
+ InstanceIdentifier<BoundServices> boundServicesInstanceIdentifier = buildBoundServicesIId(
+ serviceInfo.getServicePriority(), interfaceName, serviceMode);
+ tx.mergeParentStructurePut(boundServicesInstanceIdentifier, serviceInfo);
+ }
+
+ public static InstanceIdentifier<BoundServices> buildBoundServicesIId(Uint8 servicePriority, String interfaceName,
+ Class<? extends ServiceModeBase> serviceMode) {
+ return InstanceIdentifier.builder(ServiceBindings.class)
+ .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
+ .child(BoundServices.class, new BoundServicesKey(servicePriority)).build();
+ }
+}
import org.opendaylight.genius.itm.cache.TunnelStateCache;
import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache;
import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorEndPointCache;
+import org.opendaylight.genius.itm.cache.UnprocessedOFNodeConnectorCache;
import org.opendaylight.genius.itm.globals.ITMConstants;
import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
import org.opendaylight.genius.itm.rpc.ItmManagerRpcService;
DirectTunnelUtils directTunnelUtils;
UnprocessedNodeConnectorCache unprocessedNodeConnectorCache;
UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
+ UnprocessedOFNodeConnectorCache unprocessedOFNCCache;
Optional<ExternalTunnel> externalTunnelOptional ;
Optional<InternalTunnel> internalTunnelOptional;
new TunnelStateCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()));
OvsBridgeRefEntryCache ovsBridgeRefEntryCache =
new OvsBridgeRefEntryCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()));
- OfDpnTepConfigCache ofDpnTepConfigCache = new OfDpnTepConfigCache(dataBroker, new GuavaCacheProvider(
- new CacheManagersRegistryImpl()));
+ OfDpnTepConfigCache ofDpnTepConfigCache = new OfDpnTepConfigCache(dataBroker, jobCoordinator,
+ new GuavaCacheProvider(new CacheManagersRegistryImpl()), directTunnelUtils, unprocessedOFNCCache);
OfTepStateCache ofTepStateCache = new OfTepStateCache(dataBroker, new GuavaCacheProvider(
new CacheManagersRegistryImpl()));