2 * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.genius.itm.confighelpers;
11 import com.google.common.collect.ImmutableMap;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.time.Duration;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashMap;
18 import java.util.Optional;
19 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
20 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
21 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
22 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
23 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
24 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
25 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.api.WriteTransaction;
28 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
29 import org.opendaylight.mdsal.common.api.ReadFailedException;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlanGpe;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.OvsBridgeRefInfo;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntryKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepConfig;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepConfigBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.opendaylight.yangtools.yang.common.Uint16;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 public class ItmOfTunnelAddWorker {
57 private static final Logger LOG = LoggerFactory.getLogger(ItmOfTunnelAddWorker.class) ;
58 private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
60 private final DataBroker dataBroker;
61 private final ManagedNewTransactionRunner txRunner;
62 private final JobCoordinator jobCoordinator;
63 private final DirectTunnelUtils directTunnelUtils;
64 private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
65 private final DataTreeEventCallbackRegistrar eventCallbacks;
66 private final ItmConfig itmCfg;
68 public ItmOfTunnelAddWorker(DataBroker dataBroker, JobCoordinator jobCoordinator, ItmConfig itmCfg,
69 DirectTunnelUtils directTunnelUtils, OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
70 DataTreeEventCallbackRegistrar eventCallbacks) {
71 this.dataBroker = dataBroker;
72 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
73 this.jobCoordinator = jobCoordinator;
75 this.directTunnelUtils = directTunnelUtils;
76 this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
77 this.eventCallbacks = eventCallbacks;
80 public Collection<? extends ListenableFuture<Void>> addOfPort(Map<OfDpnTepKey, OfDpnTep> dpnsTepMap) {
81 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(transaction -> {
82 for (OfDpnTep dpn : dpnsTepMap.values()) {
83 buildOfPort(dpn, transaction);
85 updateOfDpnsConfig(dpnsTepMap, transaction);
89 private void updateOfDpnsConfig(Map<OfDpnTepKey, OfDpnTep> dpnsTepMap, WriteTransaction tx) {
90 DpnTepConfigBuilder tepConfigBuilder = new DpnTepConfigBuilder();
91 tepConfigBuilder.setOfDpnTep(dpnsTepMap);
92 InstanceIdentifier<DpnTepConfig> dpnTepsConfII = InstanceIdentifier.builder(DpnTepConfig.class).build();
93 tx.merge(LogicalDatastoreType.CONFIGURATION, dpnTepsConfII, tepConfigBuilder.build());
96 private void buildOfPort(OfDpnTep dpnTep, WriteTransaction transaction) throws ReadFailedException {
97 Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpnTep.getSourceDpnId());
98 DirectTunnelUtils.createBridgeTunnelEntryInConfigDS(dpnTep.getSourceDpnId(), dpnTep.getOfPortName());
100 if (ovsBridgeRefEntry.isPresent()) {
101 LOG.debug("creating bridge interface on dpn {}", dpnTep.getSourceDpnId());
102 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
103 (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntry.get()
104 .getOvsBridgeReference().getValue();
105 LOG.debug("adding port to the bridge:{} tunnelName: {}", bridgeIid, dpnTep.getOfPortName());
106 addOfPortToBridge(bridgeIid, dpnTep);
108 LOG.debug("Bridge not found. Registering Eventcallback for dpid {}", dpnTep.getSourceDpnId());
110 InstanceIdentifier<OvsBridgeRefEntry> bridgeRefEntryFromDS =
111 InstanceIdentifier.builder(OvsBridgeRefInfo.class)
112 .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpnTep.getSourceDpnId())).build();
114 eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> {
115 addPortToBridgeOnCallback(dpnTep, refEntryIid);
116 return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
117 }, Duration.ofMillis(5000), (id) -> {
119 Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOnCallback =
120 ovsBridgeRefEntryCache.get(dpnTep.getSourceDpnId());
121 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIidOnCallback =
122 (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntryOnCallback.get()
123 .getOvsBridgeReference().getValue();
124 addOfPortToBridge(bridgeIidOnCallback, dpnTep);
125 } catch (ReadFailedException e) {
126 LOG.error("Bridge not found in DS/cache for dpId {}", dpnTep.getSourceDpnId());
133 private void addPortToBridgeOnCallback(OfDpnTep dpnTep, OvsBridgeRefEntry bridgeRefEntry) {
134 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
135 (InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry.getOvsBridgeReference().getValue();
136 addOfPortToBridge(bridgeIid, dpnTep);
139 private void addOfPortToBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid, OfDpnTep dpnTep) {
140 Class<? extends InterfaceTypeBase> type =
141 DirectTunnelUtils.TUNNEL_TYPE_MAP.get(dpnTep.getTunnelType());
143 LOG.warn("Unknown Tunnel Type obtained while creating port {} on dpn {}",
144 dpnTep.getOfPortName(), dpnTep.getSourceDpnId());
148 ImmutableMap.Builder<String, String> options = new ImmutableMap.Builder<>();
150 // Options common to any kind of tunnel
151 options.put(directTunnelUtils.TUNNEL_OPTIONS_KEY, directTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
152 IpAddress localIp = dpnTep.getTepIp();
153 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_LOCAL_IP, localIp.stringValue());
154 options.put(directTunnelUtils.TUNNEL_OPTIONS_REMOTE_IP, directTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
155 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_TOS, DirectTunnelUtils.TUNNEL_OPTIONS_TOS_VALUE_INHERIT);
157 if (TunnelTypeVxlanGpe.class.equals(type)) {
158 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_EXTS, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_GPE);
159 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSI, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
160 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSP, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
161 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC1, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
162 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC2, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
163 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC3, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
164 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_NSHC4, DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_FLOW);
165 // VxLAN-GPE interfaces will not use the default UDP port to avoid problems with other meshes
166 options.put(DirectTunnelUtils.TUNNEL_OPTIONS_DESTINATION_PORT,
167 DirectTunnelUtils.TUNNEL_OPTIONS_VALUE_GPE_DESTINATION_PORT);
170 addTerminationPoint(bridgeIid, dpnTep.getOfPortName(), 0, type, options.build());
173 private void addTerminationPoint(InstanceIdentifier<?> bridgeIid, String ofPortName, int vlanId,
174 Class<? extends InterfaceTypeBase> type, Map<String, String> options) {
176 final InstanceIdentifier<TerminationPoint> tpIid = DirectTunnelUtils.createTerminationPointInstanceIdentifier(
177 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(
178 org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
179 .network.topology.rev131021.network.topology.topology.Node.class)), ofPortName);
180 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
182 tpAugmentationBuilder.setName(ofPortName);
185 tpAugmentationBuilder.setInterfaceType(type);
188 if (options != null) {
189 Map<OptionsKey, Options> optionsMap = new HashMap<>();
190 for (Map.Entry<String, String> entry : options.entrySet()) {
191 OptionsBuilder optionsBuilder = new OptionsBuilder();
192 optionsBuilder.withKey(new OptionsKey(entry.getKey()));
193 optionsBuilder.setOption(entry.getKey());
194 optionsBuilder.setValue(entry.getValue());
195 optionsMap.put(optionsBuilder.key(),optionsBuilder.build());
197 tpAugmentationBuilder.setOptions(optionsMap);
201 tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
202 tpAugmentationBuilder.setVlanTag(new VlanId(Uint16.valueOf(vlanId)));
205 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
206 tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
207 tpBuilder.addAugmentation(tpAugmentationBuilder.build());
209 ITMBatchingUtils.write(tpIid, tpBuilder.build(), ITMBatchingUtils.EntityType.TOPOLOGY_CONFIG);