2 * Copyright (c) 2016, 2017 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
8 package org.opendaylight.genius.itm.confighelpers;
10 import static java.util.Collections.singletonList;
11 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
12 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
14 import com.google.common.base.Optional;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import java.time.Duration;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.Objects;
22 import java.util.concurrent.Callable;
23 import java.util.concurrent.ExecutionException;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
28 import org.opendaylight.genius.infra.Datastore.Configuration;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
30 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
31 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
32 import org.opendaylight.genius.infra.TypedWriteTransaction;
33 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
34 import org.opendaylight.genius.itm.cache.OfEndPointCache;
35 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
36 import org.opendaylight.genius.itm.globals.ITMConstants;
37 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
38 import org.opendaylight.genius.itm.impl.ItmUtils;
39 import org.opendaylight.genius.itm.impl.TunnelMonitoringConfig;
40 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
41 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
42 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.tunnel.optional.params.TunnelOptions;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.OvsBridgeRefInfo;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntryKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepsState;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepsStateBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTeps;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpns;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
75 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
76 import org.opendaylight.yangtools.yang.common.OperationFailedException;
77 import org.opendaylight.yangtools.yang.common.Uint64;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
81 public final class ItmInternalTunnelAddWorker {
83 private static final Logger LOG = LoggerFactory.getLogger(ItmInternalTunnelAddWorker.class) ;
85 private final ItmConfig itmCfg;
86 private final Integer monitorInterval;
87 private final boolean isTunnelMonitoringEnabled;
88 private final Class<? extends TunnelMonitoringTypeBase> monitorProtocol;
90 private final DataBroker dataBroker;
91 private final ManagedNewTransactionRunner txRunner;
92 private final JobCoordinator jobCoordinator;
93 private final DirectTunnelUtils directTunnelUtils;
94 private final IInterfaceManager interfaceManager;
95 private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
96 private final OfEndPointCache ofEndPointCache;
97 private final DataTreeEventCallbackRegistrar eventCallbacks;
99 public ItmInternalTunnelAddWorker(DataBroker dataBroker, JobCoordinator jobCoordinator,
100 TunnelMonitoringConfig tunnelMonitoringConfig, ItmConfig itmCfg,
101 DirectTunnelUtils directTunnelUtil,
102 IInterfaceManager interfaceManager,
103 OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
104 OfEndPointCache ofEndPointCache,
105 DataTreeEventCallbackRegistrar eventCallbacks) {
106 this.dataBroker = dataBroker;
107 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
108 this.jobCoordinator = jobCoordinator;
109 this.itmCfg = itmCfg;
110 this.directTunnelUtils = directTunnelUtil;
111 this.interfaceManager = interfaceManager;
112 this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
113 this.ofEndPointCache = ofEndPointCache;
114 this.eventCallbacks = eventCallbacks;
116 isTunnelMonitoringEnabled = tunnelMonitoringConfig.isTunnelMonitoringEnabled();
117 monitorProtocol = tunnelMonitoringConfig.getMonitorProtocol();
118 monitorInterval = tunnelMonitoringConfig.getMonitorInterval();
121 public List<ListenableFuture<Void>> buildAllTunnels(IMdsalApiManager mdsalManager, List<DPNTEPsInfo> cfgdDpnList,
122 Collection<DPNTEPsInfo> meshedDpnList) {
123 LOG.trace("Building tunnels with DPN List {} " , cfgdDpnList);
124 if (null == cfgdDpnList || cfgdDpnList.isEmpty()) {
125 LOG.error(" Build Tunnels was invoked with empty list");
126 return Collections.emptyList();
129 return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
130 for (DPNTEPsInfo dpn : cfgdDpnList) {
131 //#####if dpn is not in meshedDpnList
132 buildTunnelFrom(tx, dpn, meshedDpnList, mdsalManager);
133 if (meshedDpnList != null) {
134 meshedDpnList.add(dpn);
136 // Update the config datastore -- FIXME -- Error Handling
137 updateDpnTepInfoToConfig(tx, dpn, directTunnelUtils);
142 private static void updateDpnTepInfoToConfig(TypedWriteTransaction<Configuration> tx, DPNTEPsInfo dpn,
143 DirectTunnelUtils directTunnelUtils) throws ExecutionException, InterruptedException, OperationFailedException {
144 LOG.debug("Updating CONFIGURATION datastore with DPN {} ", dpn);
145 InstanceIdentifier<DpnEndpoints> dep = InstanceIdentifier.builder(DpnEndpoints.class).build() ;
146 List<DPNTEPsInfo> dpnList = new ArrayList<>() ;
147 dpnList.add(new DPNTEPsInfoBuilder(dpn)
148 .setDstId(directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME, dpn.getDPNID().toString())).build());
149 DpnEndpoints tnlBuilder = new DpnEndpointsBuilder().setDPNTEPsInfo(dpnList).build() ;
150 tx.merge(dep, tnlBuilder);
153 private void buildTunnelFrom(TypedReadWriteTransaction<Configuration> tx, DPNTEPsInfo srcDpn,
154 Collection<DPNTEPsInfo> meshedDpnList, IMdsalApiManager mdsalManager)
155 throws ExecutionException, InterruptedException, OperationFailedException {
156 LOG.trace("Building tunnels from DPN {} " , srcDpn);
157 if (null == meshedDpnList || meshedDpnList.isEmpty()) {
158 LOG.debug("No DPN in the mesh ");
161 for (DPNTEPsInfo dstDpn: meshedDpnList) {
162 if (!srcDpn.equals(dstDpn)) {
163 wireUpWithinTransportZone(tx, srcDpn, dstDpn, mdsalManager);
169 private void wireUpWithinTransportZone(TypedReadWriteTransaction<Configuration> tx, DPNTEPsInfo srcDpn,
170 DPNTEPsInfo dstDpn, IMdsalApiManager mdsalManager)
171 throws ExecutionException, InterruptedException, OperationFailedException {
172 LOG.trace("Wiring up within Transport Zone for Dpns {}, {} " , srcDpn, dstDpn);
173 List<TunnelEndPoints> srcEndPts = srcDpn.nonnullTunnelEndPoints();
174 List<TunnelEndPoints> dstEndPts = dstDpn.nonnullTunnelEndPoints();
176 for (TunnelEndPoints srcte : srcEndPts) {
177 for (TunnelEndPoints dstte : dstEndPts) {
178 // Compare the Transport zones
179 if (!Objects.equals(srcDpn.getDPNID(), dstDpn.getDPNID())) {
180 if (!ItmUtils.getIntersection(srcte.nonnullTzMembership(),
181 dstte.nonnullTzMembership()).isEmpty()) {
183 wireUpBidirectionalTunnel(tx, srcte, dstte, srcDpn.getDPNID(), dstDpn.getDPNID(), mdsalManager);
184 if (!ItmTunnelAggregationHelper.isTunnelAggregationEnabled()) {
185 // CHECK THIS -- Assumption -- One end point per Dpn per transport zone
194 private void wireUpBidirectionalTunnel(TypedReadWriteTransaction<Configuration> tx, TunnelEndPoints srcte,
195 TunnelEndPoints dstte, Uint64 srcDpnId, Uint64 dstDpnId, IMdsalApiManager mdsalManager)
196 throws ExecutionException, InterruptedException, OperationFailedException {
197 // Setup the flow for LLDP monitoring -- PUNT TO CONTROLLER
199 if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeLldp.class)) {
200 ItmUtils.addTerminatingServiceTable(tx, srcDpnId, mdsalManager);
201 ItmUtils.addTerminatingServiceTable(tx, dstDpnId, mdsalManager);
203 // Create the forward direction tunnel
204 if (!wireUp(tx, srcte, dstte, srcDpnId, dstDpnId)) {
205 LOG.error("Could not build tunnel between end points {}, {} " , srcte, dstte);
208 // CHECK IF FORWARD IS NOT BUILT , REVERSE CAN BE BUILT
209 // Create the tunnel for the reverse direction
210 if (!wireUp(tx, dstte, srcte, dstDpnId, srcDpnId)) {
211 LOG.error("Could not build tunnel between end points {}, {} " , dstte, srcte);
215 private boolean wireUp(TypedWriteTransaction<Configuration> tx, TunnelEndPoints srcte, TunnelEndPoints dstte,
216 Uint64 srcDpnId, Uint64 dstDpnId)
217 throws ExecutionException, InterruptedException, OperationFailedException {
219 LOG.trace("Wiring between source tunnel end points {}, destination tunnel end points {}", srcte, dstte);
220 String interfaceName = srcte.getInterfaceName();
221 Class<? extends TunnelTypeBase> tunType = srcte.getTunnelType();
222 String tunTypeStr = srcte.getTunnelType().getName();
223 // Form the trunk Interface Name
225 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName,
226 srcte.getIpAddress().stringValue(), dstte.getIpAddress().stringValue(), tunTypeStr);
228 String parentInterfaceName = null;
229 if (tunType.isAssignableFrom(TunnelTypeVxlan.class)) {
230 parentInterfaceName = createLogicalGroupTunnel(srcDpnId, dstDpnId);
232 if (interfaceManager.isItmDirectTunnelsEnabled()) {
233 createInternalDirectTunnels(srcte, dstte, srcDpnId, dstDpnId, tunType, trunkInterfaceName,
234 parentInterfaceName);
236 createTunnelInterface(srcte, dstte, srcDpnId, tunType, trunkInterfaceName, parentInterfaceName);
237 // also update itm-state ds?
238 createInternalTunnel(tx, srcDpnId, dstDpnId, tunType, trunkInterfaceName);
243 private void createTunnelInterface(TunnelEndPoints srcte, TunnelEndPoints dstte, Uint64 srcDpnId,
244 Class<? extends TunnelTypeBase> tunType, String trunkInterfaceName, String parentInterfaceName) {
245 String gateway = srcte.getIpAddress().getIpv4Address() != null ? "0.0.0.0" : "::";
246 IpAddress gatewayIpObj = IpAddressBuilder.getDefaultInstance(gateway);
247 IpAddress gwyIpAddress = gatewayIpObj;
248 LOG.debug(" Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, "
249 + "source IP - {}, destination IP - {} gateway IP - {}",
250 trunkInterfaceName, srcte.getInterfaceName(), srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress);
251 boolean useOfTunnel = ItmUtils.falseIfNull(srcte.isOptionOfTunnel());
253 List<TunnelOptions> tunOptions = ItmUtils.buildTunnelOptions(srcte, itmCfg);
254 Boolean isMonitorEnabled = !tunType.isAssignableFrom(TunnelTypeLogicalGroup.class) && isTunnelMonitoringEnabled;
255 Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName,
256 String.format("%s %s",ItmUtils.convertTunnelTypetoString(tunType), "Trunk Interface"),
257 true, tunType, srcte.getIpAddress(), dstte.getIpAddress(), true,
258 isMonitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, parentInterfaceName, tunOptions);
259 LOG.debug(" Trunk Interface builder - {} ", iface);
260 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
261 LOG.debug(" Trunk Interface Identifier - {} ", trunkIdentifier);
262 LOG.trace(" Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface);
263 ITMBatchingUtils.update(trunkIdentifier, iface, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
264 ItmUtils.ITM_CACHE.addInterface(iface);
267 private static void createInternalTunnel(TypedWriteTransaction<Configuration> tx, Uint64 srcDpnId,
268 Uint64 dstDpnId, Class<? extends TunnelTypeBase> tunType, String trunkInterfaceName) {
269 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
270 .child(InternalTunnel.class, new InternalTunnelKey(dstDpnId, srcDpnId, tunType));
271 InternalTunnel tnl = ItmUtils.buildInternalTunnel(srcDpnId, dstDpnId, tunType, trunkInterfaceName);
272 // Switching to individual transaction submit as batching latencies is causing ELAN failures.
273 // Will revert when ELAN can handle this.
274 // ITMBatchingUtils.update(path, tnl, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
275 tx.merge(path, tnl, CREATE_MISSING_PARENTS);
276 ItmUtils.ITM_CACHE.addInternalTunnel(tnl);
279 private String createLogicalGroupTunnel(Uint64 srcDpnId, Uint64 dstDpnId) {
280 boolean tunnelAggregationEnabled = ItmTunnelAggregationHelper.isTunnelAggregationEnabled();
281 if (!tunnelAggregationEnabled) {
284 String logicTunnelGroupName = ItmUtils.getLogicalTunnelGroupName(srcDpnId, dstDpnId);
285 ItmTunnelAggregationWorker addWorker =
286 new ItmTunnelAggregationWorker(logicTunnelGroupName, srcDpnId, dstDpnId, dataBroker);
287 jobCoordinator.enqueueJob(logicTunnelGroupName, addWorker);
288 return logicTunnelGroupName;
291 private static class ItmTunnelAggregationWorker implements Callable<List<ListenableFuture<Void>>> {
293 private final String logicTunnelGroupName;
294 private final Uint64 srcDpnId;
295 private final Uint64 dstDpnId;
296 private final ManagedNewTransactionRunner txRunner;
298 ItmTunnelAggregationWorker(String logicGroupName, Uint64 srcDpnId, Uint64 dstDpnId, DataBroker broker) {
299 this.logicTunnelGroupName = logicGroupName;
300 this.srcDpnId = srcDpnId;
301 this.dstDpnId = dstDpnId;
302 this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
306 public List<ListenableFuture<Void>> call() {
307 return singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
308 //The logical tunnel interface be created only when the first tunnel interface on each OVS is created
309 InternalTunnel tunnel = ItmUtils.ITM_CACHE.getInternalTunnel(logicTunnelGroupName);
310 if (tunnel == null) {
311 LOG.info("MULTIPLE_VxLAN_TUNNELS: add the logical tunnel group {} because a first tunnel"
312 + " interface on srcDpnId {} dstDpnId {} is created", logicTunnelGroupName, srcDpnId, dstDpnId);
313 createLogicalTunnelInterface(srcDpnId, TunnelTypeLogicalGroup.class, logicTunnelGroupName);
314 createInternalTunnel(tx, srcDpnId, dstDpnId, TunnelTypeLogicalGroup.class, logicTunnelGroupName);
316 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not first tunnel on srcDpnId {} dstDpnId {}", srcDpnId,
322 private static void createLogicalTunnelInterface(Uint64 srcDpnId,
323 Class<? extends TunnelTypeBase> tunType, String interfaceName) {
324 Interface iface = ItmUtils.buildLogicalTunnelInterface(srcDpnId, interfaceName,
325 String.format("%s %s",ItmUtils.convertTunnelTypetoString(tunType), "Interface"), true);
326 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(interfaceName);
327 ITMBatchingUtils.update(trunkIdentifier, iface, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
328 ItmUtils.ITM_CACHE.addInterface(iface);
332 private void createInternalDirectTunnels(TunnelEndPoints srcte, TunnelEndPoints dstte, Uint64 srcDpnId,
333 Uint64 dstDpnId, Class<? extends TunnelTypeBase> tunType, String trunkInterfaceName,
334 String parentInterfaceName) throws OperationFailedException {
335 IpAddress gatewayIpObj = IpAddressBuilder.getDefaultInstance("0.0.0.0");
336 IpAddress gwyIpAddress = gatewayIpObj;
337 LOG.debug("Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {},"
338 + " destination IP - {} gateway IP - {}", trunkInterfaceName, parentInterfaceName,
339 srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress) ;
341 boolean useOfTunnel = itmCfg.isUseOfTunnels();
343 List<TunnelOptions> tunOptions = ItmUtils.buildTunnelOptions(srcte, itmCfg);
344 Boolean isMonitorEnabled = !tunType.isAssignableFrom(TunnelTypeLogicalGroup.class) && isTunnelMonitoringEnabled;
345 Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName,
346 String.format("%s %s",ItmUtils.convertTunnelTypetoString(srcte.getTunnelType()), "Trunk Interface"),
347 true, tunType, srcte.getIpAddress(), dstte.getIpAddress(), true,
348 isMonitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, parentInterfaceName, tunOptions);
349 LOG.debug("Trunk Interface builder - {} ", iface);
351 final DpnTepsStateBuilder dpnTepsStateBuilder = new DpnTepsStateBuilder();
352 final DpnsTepsBuilder dpnsTepsBuilder = new DpnsTepsBuilder();
353 final List<DpnsTeps> dpnTeps = new ArrayList<>();
354 final List<RemoteDpns> remoteDpns = new ArrayList<>();
355 String ofTunnelPortName = null;
356 dpnsTepsBuilder.withKey(new DpnsTepsKey(srcDpnId));
357 dpnsTepsBuilder.setTunnelType(srcte.getTunnelType());
358 dpnsTepsBuilder.setSourceDpnId(srcDpnId);
360 String tunnelType = ItmUtils.convertTunnelTypetoString(srcte.getTunnelType());
361 ofTunnelPortName = DirectTunnelUtils.generateOfPortName(srcDpnId, tunnelType);
362 dpnsTepsBuilder.setOfTunnel(ofTunnelPortName);
364 RemoteDpnsBuilder remoteDpn = new RemoteDpnsBuilder();
365 remoteDpn.withKey(new RemoteDpnsKey(dstDpnId));
366 remoteDpn.setDestinationDpnId(dstDpnId);
367 remoteDpn.setTunnelName(trunkInterfaceName);
368 remoteDpn.setMonitoringEnabled(isTunnelMonitoringEnabled);
369 remoteDpn.setMonitoringInterval(monitorInterval);
370 remoteDpn.setInternal(true);
371 remoteDpns.add(remoteDpn.build());
372 dpnsTepsBuilder.setRemoteDpns(remoteDpns);
373 dpnTeps.add(dpnsTepsBuilder.build());
374 dpnTepsStateBuilder.setDpnsTeps(dpnTeps);
375 updateDpnTepInterfaceInfoToConfig(dpnTepsStateBuilder.build());
376 addTunnelConfiguration(iface, ofTunnelPortName);
379 private static void updateDpnTepInterfaceInfoToConfig(DpnTepsState dpnTeps) {
380 LOG.debug("Updating CONFIGURATION datastore with DPN-Teps {} ", dpnTeps);
381 InstanceIdentifier<DpnTepsState> dpnTepsII = InstanceIdentifier.builder(DpnTepsState.class).build() ;
382 ITMBatchingUtils.update(dpnTepsII, dpnTeps, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
385 private void addTunnelConfiguration(Interface iface, String ofTunnelPortName)
386 throws ReadFailedException {
387 // ITM Direct Tunnels This transaction is not being used -- CHECK
388 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
389 if (parentRefs == null) {
390 LOG.warn("ParentRefs for interface: {} Not Found. Creation of Tunnel OF-Port not supported"
391 + " when dpid not provided.", iface.getName());
395 Uint64 dpId = parentRefs.getDatapathNodeIdentifier();
397 LOG.warn("dpid for interface: {} Not Found. No DPID provided. Creation of OF-Port not supported.",
401 String tunnelName = ofTunnelPortName != null ? ofTunnelPortName : iface.getName();
402 // create bridge on switch, if switch is connected
403 Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpId);
404 LOG.info("adding tunnel port configuration for tunnelName: {}", tunnelName);
405 if (createTunnelPort(dpId)) {
406 LOG.debug("creating dpn tunnel mapping for dpn: {} tunnelName: {}", dpId, tunnelName);
407 DirectTunnelUtils.createBridgeTunnelEntryInConfigDS(dpId, iface.getName());
408 if (ofTunnelPortName != null) {
409 ofEndPointCache.add(dpId, tunnelName);
411 if (ovsBridgeRefEntry.isPresent()) {
412 LOG.debug("creating bridge interface on dpn {}", dpId);
413 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
414 (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntry.get()
415 .getOvsBridgeReference().getValue();
416 LOG.debug("adding port to the bridge:{} tunnelName: {}", bridgeIid, tunnelName);
417 addPortToBridge(bridgeIid, iface, tunnelName);
419 LOG.debug("Bridge not found. Registering Eventcallback for dpid {}", dpId);
421 InstanceIdentifier<OvsBridgeRefEntry> bridgeRefEntryFromDS =
422 InstanceIdentifier.builder(OvsBridgeRefInfo.class)
423 .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpId)).build();
425 eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> {
426 addPortToBridgeOnCallback(iface, tunnelName, refEntryIid);
427 return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
428 }, Duration.ofMillis(5000), (id) -> {
430 Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOnCallback = ovsBridgeRefEntryCache.get(dpId);
431 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIidOnCallback =
432 (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntryOnCallback.get()
433 .getOvsBridgeReference().getValue();
434 addPortToBridge(bridgeIidOnCallback, iface, tunnelName);
435 } catch (ReadFailedException e) {
436 LOG.error("Bridge not found in DS/cache for dpId {}", dpId);
443 private void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface, String portName) {
444 IfTunnel ifTunnel = iface.augmentation(IfTunnel.class);
445 if (ifTunnel != null) {
446 directTunnelUtils.addTunnelPortToBridge(ifTunnel, bridgeIid, iface, portName);
450 private boolean createTunnelPort(Uint64 dpId) {
451 if (!itmCfg.isUseOfTunnels()) {
454 return ofEndPointCache.get(dpId) == null;
457 private void addPortToBridgeOnCallback(Interface iface, String portName, OvsBridgeRefEntry bridgeRefEntry) {
458 InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
459 (InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry.getOvsBridgeReference().getValue();
460 addPortToBridge(bridgeIid, iface, portName);