From: Apurba Mukherjee Date: Thu, 2 Jul 2020 10:40:07 +0000 (+0530) Subject: OF port creation and update config side implementation X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=4cfe9c76126225b35791fa716debb4517abdeacf;p=genius.git OF port creation and update config side implementation Change-Id: Ia542b73cde03453ccd90041d6596ea3cf5f5f5dc Signed-off-by: Apurba Mukherjee --- diff --git a/commons/testutils/src/main/java/org/opendaylight/genius/testutils/TestInterfaceManager.java b/commons/testutils/src/main/java/org/opendaylight/genius/testutils/TestInterfaceManager.java index 743a707ad..e9d42e482 100644 --- a/commons/testutils/src/main/java/org/opendaylight/genius/testutils/TestInterfaceManager.java +++ b/commons/testutils/src/main/java/org/opendaylight/genius/testutils/TestInterfaceManager.java @@ -165,4 +165,9 @@ public abstract class TestInterfaceManager implements IInterfaceManager { public boolean isItmDirectTunnelsEnabled() { return false; } + + @Override + public boolean isItmOfTunnelsEnabled() { + return false; + } } diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfDpnTepConfigCache.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfDpnTepConfigCache.java new file mode 100644 index 000000000..81bb64c8d --- /dev/null +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfDpnTepConfigCache.java @@ -0,0 +1,35 @@ +/* + * 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.math.BigInteger; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.opendaylight.genius.mdsalutil.cache.DataObjectCache; +import org.opendaylight.infrautils.caches.CacheProvider; +import org.opendaylight.mdsal.binding.api.DataBroker; +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; + +@Singleton +public class OfDpnTepConfigCache extends DataObjectCache { + + @Inject + public OfDpnTepConfigCache(DataBroker dataBroker, CacheProvider cacheProvider) { + 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()); + } +} diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfTepStateCache.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfTepStateCache.java new file mode 100644 index 000000000..0bb7da5fd --- /dev/null +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfTepStateCache.java @@ -0,0 +1,36 @@ +/* + * 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 javax.inject.Inject; +import javax.inject.Singleton; +import org.opendaylight.genius.mdsalutil.cache.DataObjectCache; +import org.opendaylight.infrautils.caches.CacheProvider; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +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.of.teps.state.OfTep; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@Singleton +public class OfTepStateCache extends DataObjectCache { + + private static final Logger LOG = LoggerFactory.getLogger(OfTepStateCache.class); + + @Inject + public OfTepStateCache(DataBroker dataBroker, CacheProvider cacheProvider) { + super(OfTep.class, dataBroker, LogicalDatastoreType.OPERATIONAL, + 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()); + } +} diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfPortAddWorker.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfPortAddWorker.java new file mode 100644 index 000000000..343d6f7ec --- /dev/null +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfPortAddWorker.java @@ -0,0 +1,39 @@ +/* + * 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.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ItmOfPortAddWorker implements Callable>> { + + private static final Logger LOG = LoggerFactory.getLogger(ItmOfPortAddWorker.class); + + private final Map dpnsTepMap; + private final ItmOfTunnelAddWorker itmOfTunnelAddWorker; + + public ItmOfPortAddWorker(Map dpnsTepMap, ItmOfTunnelAddWorker itmOfTunnelAddWorker) { + this.dpnsTepMap = dpnsTepMap; + this.itmOfTunnelAddWorker = itmOfTunnelAddWorker; + } + + @Override + public List> call() throws Exception { + List> futures = new ArrayList<>() ; + futures.addAll(itmOfTunnelAddWorker.addOfPort(dpnsTepMap)); + return futures; + } +} diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfPortRemoveWorker.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfPortRemoveWorker.java new file mode 100644 index 000000000..5d375ba11 --- /dev/null +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfPortRemoveWorker.java @@ -0,0 +1,28 @@ +/* + * 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.confighelpers; + +import com.google.common.util.concurrent.ListenableFuture; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import org.opendaylight.mdsal.binding.api.DataBroker; +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; + +public class ItmOfPortRemoveWorker implements Callable>> { + public ItmOfPortRemoveWorker(Map oldDpnTepList, DataBroker dataBroker, + ItmOfTunnelDeleteWorker itmOfTunnelDeleteWorker) { + } + + @Override + public List> call() throws Exception { + return null; + } +} diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelAddWorker.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelAddWorker.java new file mode 100644 index 000000000..0d4599222 --- /dev/null +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelAddWorker.java @@ -0,0 +1,211 @@ +/* + * 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.confighelpers; + +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.ListenableFuture; +import java.time.Duration; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar; +import org.opendaylight.genius.infra.ManagedNewTransactionRunner; +import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; +import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache; +import org.opendaylight.genius.itm.impl.ITMBatchingUtils; +import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils; +import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.WriteTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.mdsal.common.api.ReadFailedException; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlanGpe; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.OvsBridgeRefInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntryKey; +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.DpnTepConfigBuilder; +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.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ItmOfTunnelAddWorker { + + private static final Logger LOG = LoggerFactory.getLogger(ItmOfTunnelAddWorker.class) ; + private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger"); + + private final DataBroker dataBroker; + private final ManagedNewTransactionRunner txRunner; + private final JobCoordinator jobCoordinator; + private final DirectTunnelUtils directTunnelUtils; + private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache; + private final DataTreeEventCallbackRegistrar eventCallbacks; + private final ItmConfig itmCfg; + + public ItmOfTunnelAddWorker(DataBroker dataBroker, JobCoordinator jobCoordinator, ItmConfig itmCfg, + DirectTunnelUtils directTunnelUtils, OvsBridgeRefEntryCache ovsBridgeRefEntryCache, + DataTreeEventCallbackRegistrar eventCallbacks) { + this.dataBroker = dataBroker; + this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker); + this.jobCoordinator = jobCoordinator; + this.itmCfg = itmCfg; + this.directTunnelUtils = directTunnelUtils; + this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache; + this.eventCallbacks = eventCallbacks; + } + + public Collection> addOfPort(Map dpnsTepMap) { + return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(transaction -> { + for (OfDpnTep dpn : dpnsTepMap.values()) { + buildOfPort(dpn, transaction); + } + updateOfDpnsConfig(dpnsTepMap, transaction); + })); + } + + private void updateOfDpnsConfig(Map dpnsTepMap, WriteTransaction tx) { + DpnTepConfigBuilder tepConfigBuilder = new DpnTepConfigBuilder(); + tepConfigBuilder.setOfDpnTep(dpnsTepMap); + InstanceIdentifier dpnTepsConfII = InstanceIdentifier.builder(DpnTepConfig.class).build(); + tx.merge(LogicalDatastoreType.CONFIGURATION, dpnTepsConfII, tepConfigBuilder.build()); + } + + private void buildOfPort(OfDpnTep dpnTep, WriteTransaction transaction) throws ReadFailedException { + Optional ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpnTep.getSourceDpnId()); + DirectTunnelUtils.createBridgeTunnelEntryInConfigDS(dpnTep.getSourceDpnId(), dpnTep.getOfPortName()); + + if (ovsBridgeRefEntry.isPresent()) { + LOG.debug("creating bridge interface on dpn {}", dpnTep.getSourceDpnId()); + InstanceIdentifier bridgeIid = + (InstanceIdentifier) ovsBridgeRefEntry.get() + .getOvsBridgeReference().getValue(); + LOG.debug("adding port to the bridge:{} tunnelName: {}", bridgeIid, dpnTep.getOfPortName()); + addOfPortToBridge(bridgeIid, dpnTep); + } else { + LOG.debug("Bridge not found. Registering Eventcallback for dpid {}", dpnTep.getSourceDpnId()); + + InstanceIdentifier bridgeRefEntryFromDS = + InstanceIdentifier.builder(OvsBridgeRefInfo.class) + .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpnTep.getSourceDpnId())).build(); + + eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> { + addPortToBridgeOnCallback(dpnTep, refEntryIid); + return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER; + }, Duration.ofMillis(5000), (id) -> { + try { + Optional ovsBridgeRefEntryOnCallback = + ovsBridgeRefEntryCache.get(dpnTep.getSourceDpnId()); + InstanceIdentifier bridgeIidOnCallback = + (InstanceIdentifier) ovsBridgeRefEntryOnCallback.get() + .getOvsBridgeReference().getValue(); + addOfPortToBridge(bridgeIidOnCallback, dpnTep); + } catch (ReadFailedException e) { + LOG.error("Bridge not found in DS/cache for dpId {}", dpnTep.getSourceDpnId()); + } + }); + } + + } + + private void addPortToBridgeOnCallback(OfDpnTep dpnTep, OvsBridgeRefEntry bridgeRefEntry) { + InstanceIdentifier bridgeIid = + (InstanceIdentifier) bridgeRefEntry.getOvsBridgeReference().getValue(); + addOfPortToBridge(bridgeIid, dpnTep); + } + + private void addOfPortToBridge(InstanceIdentifier bridgeIid, OfDpnTep dpnTep) { + Class type = + DirectTunnelUtils.TUNNEL_TYPE_MAP.get(dpnTep.getTunnelType()); + if (type == null) { + LOG.warn("Unknown Tunnel Type obtained while creating port {} on dpn {}", + dpnTep.getOfPortName(), dpnTep.getSourceDpnId()); + return; + } + + ImmutableMap.Builder options = new ImmutableMap.Builder<>(); + + // Options common to any kind of tunnel + options.put(directTunnelUtils.TUNNEL_OPTIONS_KEY, directTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + IpAddress localIp = dpnTep.getTepIp(); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_LOCAL_IP, localIp.stringValue()); + options.put(directTunnelUtils.TUNNEL_OPTIONS_REMOTE_IP, directTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_TOS, DirectTunnelUtils.TUNNEL_OPTIONS_TOS_VALUE_INHERIT); + + if (TunnelTypeVxlanGpe.class.equals(type)) { + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_EXTS, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_GPE); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSI, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSP, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC1, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC2, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC3, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC4, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW); + // VxLAN-GPE interfaces will not use the default UDP port to avoid problems with other meshes + options.put(DirectTunnelUtils.TUNNEL_OPTIONS_DESTINATION_PORT, + DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_GPE_DESTINATION_PORT); + } + + addTerminationPoint(bridgeIid, dpnTep.getOfPortName(), 0, type, options.build()); + } + + private void addTerminationPoint(InstanceIdentifier bridgeIid, String ofPortName, int vlanId, + Class type, Map options) { + + final InstanceIdentifier tpIid = DirectTunnelUtils.createTerminationPointInstanceIdentifier( + InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf( + org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang + .network.topology.rev131021.network.topology.topology.Node.class)), ofPortName); + OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder(); + + tpAugmentationBuilder.setName(ofPortName); + + if (type != null) { + tpAugmentationBuilder.setInterfaceType(type); + } + + if (options != null) { + Map optionsMap = new HashMap<>(); + for (Map.Entry entry : options.entrySet()) { + OptionsBuilder optionsBuilder = new OptionsBuilder(); + optionsBuilder.withKey(new OptionsKey(entry.getKey())); + optionsBuilder.setOption(entry.getKey()); + optionsBuilder.setValue(entry.getValue()); + optionsMap.put(optionsBuilder.key(),optionsBuilder.build()); + } + tpAugmentationBuilder.setOptions(optionsMap); + } + + if (vlanId != 0) { + tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access); + tpAugmentationBuilder.setVlanTag(new VlanId(Uint16.valueOf(vlanId))); + } + + TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); + tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid)); + tpBuilder.addAugmentation(tpAugmentationBuilder.build()); + + ITMBatchingUtils.write(tpIid, tpBuilder.build(), ITMBatchingUtils.EntityType.TOPOLOGY_CONFIG); + } +} diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelDeleteWorker.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelDeleteWorker.java new file mode 100644 index 000000000..b1ecc3b54 --- /dev/null +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelDeleteWorker.java @@ -0,0 +1,23 @@ +/* + * 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.confighelpers; + +import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar; +import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache; +import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils; +import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig; + +public class ItmOfTunnelDeleteWorker { + public ItmOfTunnelDeleteWorker(DataBroker dataBroker, JobCoordinator jobCoordinator, ItmConfig itmConfig, + DirectTunnelUtils directTunnelUtils, OvsBridgeRefEntryCache ovsBridgeRefEntryCache, + DataTreeEventCallbackRegistrar eventCallbackRegistrar) { + } +} diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java index e4807fa66..292f26deb 100644 --- a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.java @@ -100,6 +100,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipKey; +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.OfDpnTepBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey; 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; @@ -1090,4 +1093,23 @@ public final class ItmUtils { } return listOfDpId; } + + public static String generateOfPortName(Uint64 dpId, IpAddress tepIp, String tunnelType) { + String trunkInterfaceName = String.format("%s:%s:%s", dpId.toString(), tepIp.stringValue(), + tunnelType); + String uuidStr = UUID.nameUUIDFromBytes(trunkInterfaceName.getBytes(StandardCharsets.UTF_8)).toString() + .substring(0, 12).replace("-", ""); + return String.format("%s%s", "of", uuidStr); + } + + public static OfDpnTep createDpnOFTepInfo(Uint64 dpnID, IpAddress ipAddress, + String ofPortName, Class tunnelType) { + OfDpnTepBuilder tepBuilder = new OfDpnTepBuilder(); + tepBuilder.withKey(new OfDpnTepKey(dpnID)); + tepBuilder.setOfPortName(ofPortName); + tepBuilder.setSourceDpnId(dpnID); + tepBuilder.setTepIp(ipAddress); + tepBuilder.setTunnelType(tunnelType); + return tepBuilder.build(); + } } diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/listeners/TransportZoneListener.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/listeners/TransportZoneListener.java index 20cab60ba..daad3646f 100644 --- a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/listeners/TransportZoneListener.java +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/listeners/TransportZoneListener.java @@ -17,6 +17,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.jdt.annotation.NonNull; @@ -34,6 +35,10 @@ import org.opendaylight.genius.itm.confighelpers.HwVtep; import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker; import org.opendaylight.genius.itm.confighelpers.ItmInternalTunnelAddWorker; import org.opendaylight.genius.itm.confighelpers.ItmInternalTunnelDeleteWorker; +import org.opendaylight.genius.itm.confighelpers.ItmOfPortAddWorker; +import org.opendaylight.genius.itm.confighelpers.ItmOfPortRemoveWorker; +import org.opendaylight.genius.itm.confighelpers.ItmOfTunnelAddWorker; +import org.opendaylight.genius.itm.confighelpers.ItmOfTunnelDeleteWorker; import org.opendaylight.genius.itm.confighelpers.ItmTepAddWorker; import org.opendaylight.genius.itm.confighelpers.ItmTepRemoveWorker; import org.opendaylight.genius.itm.confighelpers.ItmTepsNotHostedAddWorker; @@ -60,6 +65,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership; +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.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.NotHostedTransportZones; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZonesBuilder; @@ -101,6 +108,9 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener oldDpnTepsList = createDPNTepInfo(originalTransportZone); - List newDpnTepsList = createDPNTepInfo(updatedTransportZone); - List oldDpnTepsListcopy = new ArrayList<>(); - oldDpnTepsListcopy.addAll(oldDpnTepsList); - LOG.trace("oldcopy0 {}", oldDpnTepsListcopy); - List newDpnTepsListcopy = new ArrayList<>(); - newDpnTepsListcopy.addAll(newDpnTepsList); - LOG.trace("newcopy0 {}", newDpnTepsListcopy); - - oldDpnTepsList.removeAll(newDpnTepsListcopy); - newDpnTepsList.removeAll(oldDpnTepsListcopy); - - LOG.trace("oldDpnTepsList {}", oldDpnTepsList); - LOG.trace("newDpnTepsList {}", newDpnTepsList); - LOG.trace("oldcopy {}", oldDpnTepsListcopy); - LOG.trace("newcopy {}", newDpnTepsListcopy); - LOG.trace("oldcopy Size {}", oldDpnTepsList.size()); - LOG.trace("newcopy Size {}", newDpnTepsList.size()); - - boolean equalLists = newDpnTepsList.size() == oldDpnTepsList.size() - && newDpnTepsList.containsAll(oldDpnTepsList); - LOG.trace("Is List Duplicate {} ", equalLists); - if (!newDpnTepsList.isEmpty() && !equalLists) { - LOG.trace("Adding TEPs "); - jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), - new ItmTepAddWorker(newDpnTepsList, Collections.emptyList(), dataBroker, mdsalManager, - itmInternalTunnelAddWorker, externalTunnelAddWorker)); - } - if (!oldDpnTepsList.isEmpty() && !equalLists) { - LOG.trace("Removing TEPs "); - jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), - new ItmTepRemoveWorker(oldDpnTepsList, Collections.emptyList(), originalTransportZone, mdsalManager, - itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig)); - } - List oldHwList = createhWVteps(originalTransportZone); - List newHwList = createhWVteps(updatedTransportZone); - List oldHwListcopy = new ArrayList<>(); - oldHwListcopy.addAll(oldHwList); - LOG.trace("oldHwListcopy0 {}", oldHwListcopy); - List newHwListcopy = new ArrayList<>(); - newHwListcopy.addAll(newHwList); - LOG.trace("newHwListcopy0 {}", newHwListcopy); - - oldHwList.removeAll(newHwListcopy); - newHwList.removeAll(oldHwListcopy); - LOG.trace("oldHwList {}", oldHwList); - LOG.trace("newHwList {}", newHwList); - LOG.trace("oldHwListcopy {}", oldHwListcopy); - LOG.trace("newHwListcopy {}", newHwListcopy); - if (!newHwList.isEmpty()) { - LOG.trace("Adding HW TEPs "); - jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), new ItmTepAddWorker(Collections.emptyList(), - newHwList, dataBroker, mdsalManager, itmInternalTunnelAddWorker, externalTunnelAddWorker)); - } - if (!oldHwList.isEmpty()) { - LOG.trace("Removing HW TEPs "); - jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), - new ItmTepRemoveWorker(Collections.emptyList(), oldHwList, originalTransportZone, mdsalManager, - itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig)); + + if (interfaceManager.isItmOfTunnelsEnabled()) { + updateTransportZone(originalTransportZone, updatedTransportZone); + } else { + List oldDpnTepsList = createDPNTepInfo(originalTransportZone); + List newDpnTepsList = createDPNTepInfo(updatedTransportZone); + List oldDpnTepsListcopy = new ArrayList<>(); + oldDpnTepsListcopy.addAll(oldDpnTepsList); + LOG.trace("oldcopy0 {}", oldDpnTepsListcopy); + List newDpnTepsListcopy = new ArrayList<>(); + newDpnTepsListcopy.addAll(newDpnTepsList); + LOG.trace("newcopy0 {}", newDpnTepsListcopy); + + oldDpnTepsList.removeAll(newDpnTepsListcopy); + newDpnTepsList.removeAll(oldDpnTepsListcopy); + + LOG.trace("oldDpnTepsList {}", oldDpnTepsList); + LOG.trace("newDpnTepsList {}", newDpnTepsList); + LOG.trace("oldcopy {}", oldDpnTepsListcopy); + LOG.trace("newcopy {}", newDpnTepsListcopy); + LOG.trace("oldcopy Size {}", oldDpnTepsList.size()); + LOG.trace("newcopy Size {}", newDpnTepsList.size()); + + boolean equalLists = newDpnTepsList.size() == oldDpnTepsList.size() + && newDpnTepsList.containsAll(oldDpnTepsList); + LOG.trace("Is List Duplicate {} ", equalLists); + if (!newDpnTepsList.isEmpty() && !equalLists) { + LOG.trace("Adding TEPs "); + jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), + new ItmTepAddWorker(newDpnTepsList, Collections.emptyList(), dataBroker, mdsalManager, + itmInternalTunnelAddWorker, externalTunnelAddWorker)); + } + if (!oldDpnTepsList.isEmpty() && !equalLists) { + LOG.trace("Removing TEPs "); + jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), + new ItmTepRemoveWorker(oldDpnTepsList, Collections.emptyList(), originalTransportZone, + mdsalManager, itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig)); + } + List oldHwList = createhWVteps(originalTransportZone); + List newHwList = createhWVteps(updatedTransportZone); + List oldHwListcopy = new ArrayList<>(); + oldHwListcopy.addAll(oldHwList); + LOG.trace("oldHwListcopy0 {}", oldHwListcopy); + List newHwListcopy = new ArrayList<>(); + newHwListcopy.addAll(newHwList); + LOG.trace("newHwListcopy0 {}", newHwListcopy); + + oldHwList.removeAll(newHwListcopy); + newHwList.removeAll(oldHwListcopy); + LOG.trace("oldHwList {}", oldHwList); + LOG.trace("newHwList {}", newHwList); + LOG.trace("oldHwListcopy {}", oldHwListcopy); + LOG.trace("newHwListcopy {}", newHwListcopy); + if (!newHwList.isEmpty()) { + LOG.trace("Adding HW TEPs "); + jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), + new ItmTepAddWorker(Collections.emptyList(), + newHwList, dataBroker, mdsalManager, itmInternalTunnelAddWorker, externalTunnelAddWorker)); + } + if (!oldHwList.isEmpty()) { + LOG.trace("Removing HW TEPs "); + jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), + new ItmTepRemoveWorker(Collections.emptyList(), oldHwList, originalTransportZone, mdsalManager, + itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig)); + } } } @@ -286,30 +307,41 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener opDpnList = createDPNTepInfo(transportZone); - //avoiding adding duplicates from nothosted to new dpnlist. - List duplicateFound = new ArrayList<>(); - List notHostedDpnList = getDPNTepInfoFromNotHosted(transportZone, opDpnList); - for (DPNTEPsInfo notHostedDPN:notHostedDpnList) { - for (DPNTEPsInfo newlyAddedDPN:opDpnList) { - if (newlyAddedDPN.getDPNID().compareTo(notHostedDPN.getDPNID()) == 0 - || newlyAddedDPN.getTunnelEndPoints().get(0).getIpAddress() - .equals(notHostedDPN.getTunnelEndPoints().get(0).getIpAddress())) { - duplicateFound.add(notHostedDPN); + if (interfaceManager.isItmOfTunnelsEnabled()) { + Map dpnTepMap = createOfTepInfo(transportZone); + + if (!dpnTepMap.isEmpty()) { + jobCoordinator.enqueueJob(transportZone.getZoneName(), + new ItmOfPortAddWorker(dpnTepMap, itmOfTunnelAddWorker)); + } else { + EVENT_LOGGER.debug("DPN List in TZ is empty"); + } + } else { + List opDpnList = createDPNTepInfo(transportZone); + //avoiding adding duplicates from nothosted to new dpnlist. + List duplicateFound = new ArrayList<>(); + List notHostedDpnList = getDPNTepInfoFromNotHosted(transportZone, opDpnList); + for (DPNTEPsInfo notHostedDPN : notHostedDpnList) { + for (DPNTEPsInfo newlyAddedDPN : opDpnList) { + if (newlyAddedDPN.getDPNID().compareTo(notHostedDPN.getDPNID()) == 0 + || newlyAddedDPN.getTunnelEndPoints().get(0).getIpAddress() + .equals(notHostedDPN.getTunnelEndPoints().get(0).getIpAddress())) { + duplicateFound.add(notHostedDPN); + } } } - } - notHostedDpnList.removeAll(duplicateFound); - opDpnList.addAll(notHostedDpnList); - - List hwVtepList = createhWVteps(transportZone); - LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList); - if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) { - LOG.trace("Add: Invoking ItmManager with DPN List {} ", opDpnList); - LOG.trace("Add: Invoking ItmManager with hwVtep List {} ", hwVtepList); - jobCoordinator.enqueueJob(transportZone.getZoneName(), - new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, mdsalManager, itmInternalTunnelAddWorker, - externalTunnelAddWorker)); + notHostedDpnList.removeAll(duplicateFound); + opDpnList.addAll(notHostedDpnList); + + List hwVtepList = createhWVteps(transportZone); + LOG.trace("Add: Operational dpnTepInfo - Before invoking ItmManager {}", opDpnList); + if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) { + LOG.trace("Add: Invoking ItmManager with DPN List {} ", opDpnList); + LOG.trace("Add: Invoking ItmManager with hwVtep List {} ", hwVtepList); + jobCoordinator.enqueueJob(transportZone.getZoneName(), + new ItmTepAddWorker(opDpnList, hwVtepList, dataBroker, mdsalManager, itmInternalTunnelAddWorker, + externalTunnelAddWorker)); + } } } @@ -321,6 +353,43 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener oldDpnTepMap = createOfTepInfo(originalTransportZone); + Map newDpnTepMap = createOfTepInfo(updatedTransportZone); + List oldDpnTepList = oldDpnTepMap.values().stream().collect(Collectors.toList()); + List newDpnTepList = newDpnTepMap.values().stream().collect(Collectors.toList()); + List oldDpnTepListcopy = new ArrayList<>(); + oldDpnTepListcopy.addAll(oldDpnTepList); + List newDpnTepListcopy = new ArrayList<>(); + newDpnTepListcopy.addAll(newDpnTepList); + + oldDpnTepList.removeAll(newDpnTepListcopy); + newDpnTepList.removeAll(oldDpnTepListcopy); + oldDpnTepMap.clear(); + newDpnTepMap.clear(); + for (OfDpnTep tep:oldDpnTepList) { + oldDpnTepMap.put(tep.key(), tep); + } + + for (OfDpnTep tep:newDpnTepList) { + newDpnTepMap.put(tep.key(), tep); + } + + boolean equalLists = newDpnTepList.size() == oldDpnTepList.size() + && newDpnTepList.containsAll(oldDpnTepList); + LOG.trace("Is List Duplicate? {} ", equalLists); + + if (!newDpnTepList.isEmpty() && !equalLists) { + jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), + new ItmOfPortAddWorker(newDpnTepMap, itmOfTunnelAddWorker)); + } + + if (!oldDpnTepList.isEmpty() && !equalLists) { + jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(), + new ItmOfPortRemoveWorker(oldDpnTepMap, dataBroker, itmOfTunnelDeleteWorker)); + } + } + private List createDPNTepInfoFromNotHosted(TransportZone tzNew, List opDpnList) { Map> mapNotHostedDPNToTunnelEndpt = new ConcurrentHashMap<>(); List notHostedDpnTepInfo = new ArrayList<>(); @@ -502,4 +571,21 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener createOfTepInfo(TransportZone transportZone) { + String tunnelType = ItmUtils.convertTunnelTypetoString(transportZone.getTunnelType()); + Map dpnTepMap = new HashMap<>(); + Map vtepsMap = transportZone.getVteps(); + if (vtepsMap != null && !vtepsMap.isEmpty()) { + for (Vteps vteps : vtepsMap.values()) { + Uint64 dpnID = vteps.getDpnId(); + IpAddress ipAddress = vteps.getIpAddress(); + String ofPortName = ItmUtils.generateOfPortName(dpnID, ipAddress, tunnelType); + OfDpnTep dpnTep = ItmUtils.createDpnOFTepInfo(dpnID, ipAddress, ofPortName, + transportZone.getTunnelType()); + dpnTepMap.put(dpnTep.key(), dpnTep); + } + } + return dpnTepMap; + } } diff --git a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/rpc/ItmManagerRpcService.java b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/rpc/ItmManagerRpcService.java index 8118c6aaf..208ae6d92 100644 --- a/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/rpc/ItmManagerRpcService.java +++ b/itm/itm-impl/src/main/java/org/opendaylight/genius/itm/rpc/ItmManagerRpcService.java @@ -18,6 +18,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -37,6 +38,8 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService; 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.OfTepStateCache; import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache; import org.opendaylight.genius.itm.cache.TunnelStateCache; import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker; @@ -83,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.Ext import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints; +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.teps.state.DpnsTeps; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpns; @@ -90,6 +94,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsKey; 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.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.tunnel.list.InternalTunnel; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones; @@ -133,6 +138,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.G import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder; @@ -190,6 +196,8 @@ public class ItmManagerRpcService implements ItmRpcService { private final ManagedNewTransactionRunner txRunner; private final RetryingManagedNewTransactionRunner retryingTxRunner; private final ItmConfig itmConfig; + private final OfDpnTepConfigCache ofDpnTepConfigCache; + private final OfTepStateCache ofTepStateCache; @Inject public ItmManagerRpcService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager, @@ -198,7 +206,8 @@ public class ItmManagerRpcService implements ItmRpcService { final TunnelStateCache tunnelStateCache, final InterfaceManagerService interfaceManagerService, final OvsBridgeRefEntryCache ovsBridgeRefEntryCache, - final DirectTunnelUtils directTunnelUtils) { + final DirectTunnelUtils directTunnelUtils, OfDpnTepConfigCache ofDpnTepConfigCache, + OfTepStateCache ofTepStateCache) { this.dataBroker = dataBroker; this.mdsalManager = mdsalManager; this.dpnTEPsInfoCache = dpnTEPsInfoCache; @@ -213,6 +222,8 @@ public class ItmManagerRpcService implements ItmRpcService { this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker); this.retryingTxRunner = new RetryingManagedNewTransactionRunner(dataBroker); this.itmConfig = itmConfig; + this.ofDpnTepConfigCache = ofDpnTepConfigCache; + this.ofTepStateCache = ofTepStateCache; } @PostConstruct @@ -233,6 +244,27 @@ public class ItmManagerRpcService implements ItmRpcService { Uint64 destinationDpn = input.getDestinationDpid(); Optional optTunnel = Optional.empty(); + if (interfaceManager.isItmOfTunnelsEnabled()) { + //Destination DPN Id is not relevant in OF Tunnel scenario and so is ignored + try { + Optional dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava()); + if (dpnstep.isPresent()) { + resultBld = RpcResultBuilder.success(); + resultBld.withResult(new GetTunnelInterfaceNameOutputBuilder() + .setInterfaceName(dpnstep.get().getOfPortName())).build(); + return Futures.immediateFuture(resultBld.build()); + } else { + LOG.error("OF tunnel is not available in ITM for source dpn {}", sourceDpn); + resultBld = RpcResultBuilder.failed(); + return Futures.immediateFuture(resultBld.build()); + } + } catch (ReadFailedException e) { + LOG.error("ReadFailedException: cache read failed for source dpn {} reason: {}", sourceDpn, + e.getMessage()); + resultBld = RpcResultBuilder.failed(); + return Futures.immediateFuture(resultBld.build()); + } + } if (interfaceManager.isItmDirectTunnelsEnabled()) { DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getDpnTepInterface(sourceDpn, destinationDpn); if (interfaceInfo != null) { @@ -277,7 +309,12 @@ public class ItmManagerRpcService implements ItmRpcService { .withError(RpcError.ErrorType.APPLICATION, "tunnel name not set for GetEgressActionsForTunnel call").build()); } - if (!dpnTepStateCache.isInternal(tunnelName) || !interfaceManager.isItmDirectTunnelsEnabled()) { + if (tunnelName.startsWith("of") + || (interfaceManager.isItmDirectTunnelsEnabled() && dpnTepStateCache.isInternal(tunnelName))) { + return fromListenableFuture(LOG, input, () -> getEgressActionsForInternalTunnels(input.getIntfName(), + input.getTunnelKey() != null ? input.getTunnelKey().toJava() : null, + input.getActionKey())).onFailureLogLevel(LogLevel.ERROR).build(); + } else { // Re-direct the RPC to Interface Manager // From the rpc input and get the output and copy to output org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406 @@ -308,10 +345,6 @@ public class ItmManagerRpcService implements ItmRpcService { } } ,MoreExecutors.directExecutor()); return settableFuture; - } else { - return fromListenableFuture(LOG, input, () -> getEgressActionsForInternalTunnels(input.getIntfName(), - input.getTunnelKey() != null ? input.getTunnelKey().toJava() : null, - input.getActionKey())).onFailureLogLevel(LogLevel.ERROR).build(); } } @@ -545,6 +578,29 @@ public class ItmManagerRpcService implements ItmRpcService { RpcResultBuilder resultBld; String sourceNode = input.getSourceNode(); String dstNode = input.getDestinationNode(); + if (interfaceManager.isItmOfTunnelsEnabled()) { + Optional tepDetail; + try { + tepDetail = ofDpnTepConfigCache.get(new BigInteger(sourceNode)); + } catch (ReadFailedException e) { + LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for " + + "source dpn {} reason: {}", sourceNode, e.getMessage()); + resultBld = failed(); + return Futures.immediateFuture(resultBld.build()); + } + if (tepDetail.isPresent()) { + GetExternalTunnelInterfaceNameOutputBuilder output = + new GetExternalTunnelInterfaceNameOutputBuilder() + .setInterfaceName(tepDetail.get().getOfPortName()); + resultBld = RpcResultBuilder.success(); + resultBld.withResult(output.build()); + return Futures.immediateFuture(resultBld.build()); + } else { + LOG.error("OF tunnel interface is not available in config DS for source dpn {}", sourceNode); + resultBld = failed(); + return Futures.immediateFuture(resultBld.build()); + } + } ExternalTunnelKey externalTunnelKey = new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()); InstanceIdentifier path = InstanceIdentifier.create( ExternalTunnelList.class) @@ -650,7 +706,28 @@ public class ItmManagerRpcService implements ItmRpcService { GetInternalOrExternalInterfaceNameInput input) { RpcResultBuilder resultBld = failed(); Uint64 srcDpn = input.getSourceDpid(); - IpAddress dstIp = input.getDestinationIp() ; + IpAddress dstIp = input.getDestinationIp(); + if (interfaceManager.isItmOfTunnelsEnabled()) { + Optional tepDetail; + try { + tepDetail = ofDpnTepConfigCache.get(srcDpn.toJava()); + } catch (ReadFailedException e) { + LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for " + + "source dpn {} reason: {}", srcDpn, e.getMessage()); + return Futures.immediateFuture(resultBld.build()); + } + if (tepDetail.isPresent()) { + GetInternalOrExternalInterfaceNameOutputBuilder output = + new GetInternalOrExternalInterfaceNameOutputBuilder() + .setInterfaceName(tepDetail.get().getOfPortName()); + resultBld = RpcResultBuilder.success(); + resultBld.withResult(output.build()); + return Futures.immediateFuture(resultBld.build()); + } else { + LOG.error("OF tunnel interface is not available in config DS for source dpn {}", srcDpn); + return Futures.immediateFuture(resultBld.build()); + } + } InstanceIdentifier path1 = InstanceIdentifier.create(ExternalTunnelList.class) .child(ExternalTunnel.class, new ExternalTunnelKey(dstIp.stringValue(), srcDpn.toString(), input.getTunnelType())); @@ -867,7 +944,27 @@ public class ItmManagerRpcService implements ItmRpcService { } public ListenableFuture> getTepIp(GetTepIpInput input) { - return null; + RpcResultBuilder resultBld; + Uint64 sourceDpn = input.getDpnId(); + Optional dpnstep; + try { + dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava()); + } catch (ReadFailedException e) { + LOG.error("ReadFailedException: OF tunnel is not available in ITM for source dpn {} reason: {}",sourceDpn, + e.getMessage()); + resultBld = RpcResultBuilder.failed(); + return Futures.immediateFuture(resultBld.build()); + } + if (dpnstep.isPresent()) { + resultBld = RpcResultBuilder.success(); + resultBld.withResult(new GetTepIpOutputBuilder() + .setTepIp(dpnstep.get().getTepIp())).build(); + return Futures.immediateFuture(resultBld.build()); + } else { + LOG.error("OF tunnel is not available in ITM for source dpn {}",sourceDpn); + resultBld = RpcResultBuilder.failed(); + return Futures.immediateFuture(resultBld.build()); + } } @SuppressWarnings("checkstyle:IllegalCatch") @@ -1174,40 +1271,68 @@ public class ItmManagerRpcService implements ItmRpcService { getEgressActionsForInternalTunnels(String interfaceName, Long tunnelKey, Integer actionKey) throws ExecutionException, InterruptedException, OperationFailedException { - DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName); - if (interfaceInfo == null) { - throw new IllegalStateException("Interface information not present in config DS for" + interfaceName); - } + if (interfaceName.startsWith("of")) { + Optional oftep = ofTepStateCache.get(interfaceName); + if (!oftep.isPresent()) { + throw new IllegalStateException("Interface information not present in oper DS for" + interfaceName); + } + List actions = getEgressActionInfosForOpenFlowTunnel(oftep.get().getIfIndex(), + oftep.get().getTepIp(), tunnelKey, actionKey); + return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder() + .setAction(actions.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build()); + } else { + DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName); + if (interfaceInfo == null) { + throw new IllegalStateException("Interface information not present in config DS for" + interfaceName); + } - String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType()); - if (!tunnelType.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_VXLAN)) { - throw new IllegalArgumentException(tunnelType + " tunnel not handled by ITM"); - } + String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType()); + if (!tunnelType.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_VXLAN)) { + throw new IllegalArgumentException(tunnelType + " tunnel not handled by ITM"); + } - Optional dpntePsInfoOptional = dpnTEPsInfoCache.get(InstanceIdentifier.builder(DpnEndpoints.class) - .child(DPNTEPsInfo.class, new DPNTEPsInfoKey( - // FIXME: the cache should be caching this value, not just as a String - Uint64.valueOf(dpnTepStateCache.getTunnelEndPointInfoFromCache(interfaceInfo.getTunnelName()) - .getDstEndPointInfo()))) - .build()); - Integer dstId; - if (dpntePsInfoOptional.isPresent()) { - dstId = dpntePsInfoOptional.get().getDstId(); - } else { - dstId = directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME, interfaceInfo.getRemoteDPN().toString()); + Optional dpntePsInfoOptional = dpnTEPsInfoCache.get(InstanceIdentifier + .builder(DpnEndpoints.class) + .child(DPNTEPsInfo.class, new DPNTEPsInfoKey( + // FIXME: the cache should be caching this value, not just as a String + Uint64.valueOf(dpnTepStateCache.getTunnelEndPointInfoFromCache( + interfaceInfo.getTunnelName()).getDstEndPointInfo()))) + .build()); + Integer dstId; + if (dpntePsInfoOptional.isPresent()) { + dstId = dpntePsInfoOptional.get().getDstId(); + } else { + dstId = directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME, + interfaceInfo.getRemoteDPN().toString()); + } + + List result = new ArrayList<>(); + long regValue = MetaDataUtil.getRemoteDpnMetadatForEgressTunnelTable(dstId); + int actionKeyStart = actionKey == null ? 0 : actionKey; + result.add(new ActionSetFieldTunnelId(actionKeyStart++, + Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L))); + result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, MetaDataUtil.REG6_START_INDEX, + MetaDataUtil.REG6_END_INDEX, regValue)); + result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_TUNNEL_TABLE)); + + return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder() + .setAction(result.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build()); } + } + private static List getEgressActionInfosForOpenFlowTunnel(Uint16 ifIndex, IpAddress ipAddress, + Long tunnelKey, Integer actionKey) { List result = new ArrayList<>(); - long regValue = MetaDataUtil.getRemoteDpnMetadatForEgressTunnelTable(dstId); int actionKeyStart = actionKey == null ? 0 : actionKey; result.add(new ActionSetFieldTunnelId(actionKeyStart++, Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L))); - result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, MetaDataUtil.REG6_START_INDEX, - MetaDataUtil.REG6_END_INDEX, regValue)); - result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_TUNNEL_TABLE)); + 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)); - return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder() - .setAction(result.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build()); + return result; } public static Map diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java index 17e5a5598..4d69bc929 100644 --- a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java @@ -26,6 +26,8 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService; 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.OfTepStateCache; import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache; import org.opendaylight.genius.itm.cache.TunnelStateCache; import org.opendaylight.genius.itm.cache.UnprocessedNodeConnectorCache; @@ -229,10 +231,15 @@ public class ItmManagerRpcServiceTest { 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())); + + OfTepStateCache ofTepStateCache = new OfTepStateCache(dataBroker, new GuavaCacheProvider( + new CacheManagersRegistryImpl())); itmManagerRpcService = new ItmManagerRpcService(dataBroker, mdsalApiManager, itmConfig, dpntePsInfoCache, interfaceManager, dpnTepStateCache, tunnelStateCache, interfaceManagerService, - ovsBridgeRefEntryCache, directTunnelUtils); + ovsBridgeRefEntryCache, directTunnelUtils, ofDpnTepConfigCache, ofTepStateCache); } @After diff --git a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java index d7dd64237..377f11c9f 100644 --- a/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java +++ b/itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java @@ -78,7 +78,7 @@ public class ItmTestModule extends AbstractGuiceJsr250Module { .setUseOfTunnels(true) .build(); bind(ItmConfig.class).toInstance(itmConfigObj); - IfmConfig interfaceConfig = new IfmConfigBuilder().setItmDirectTunnels(false).build(); + IfmConfig interfaceConfig = new IfmConfigBuilder().setItmDirectTunnels(false).setItmOfTunnels(false).build(); bind(IfmConfig.class).toInstance(interfaceConfig); bind(TunnelMonitorIntervalListener.class); bind(TransportZoneListener.class);