2 * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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 static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
12 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
13 import static org.opendaylight.mdsal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.Objects;
21 import java.util.Optional;
22 import java.util.concurrent.Callable;
23 import java.util.concurrent.ExecutionException;
24 import javax.inject.Inject;
25 import javax.inject.Singleton;
26 import org.opendaylight.genius.infra.Datastore.Configuration;
27 import org.opendaylight.genius.infra.Datastore.Operational;
28 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
30 import org.opendaylight.genius.infra.TypedReadTransaction;
31 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
32 import org.opendaylight.genius.infra.TypedWriteTransaction;
33 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
34 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
35 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
36 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
37 import org.opendaylight.genius.itm.impl.ItmUtils;
38 import org.opendaylight.genius.mdsalutil.ActionInfo;
39 import org.opendaylight.genius.mdsalutil.MDSALUtil;
40 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
41 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
42 import org.opendaylight.mdsal.binding.api.DataBroker;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.InterfaceChildInfo;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.itm.config.TunnelAggregation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.opendaylight.yangtools.yang.common.Uint64;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
72 public class ItmTunnelAggregationHelper {
74 public static final int ADD_TUNNEL = 0;
75 public static final int DEL_TUNNEL = 1;
76 public static final int MOD_TUNNEL = 2;
77 public static final int MOD_GROUP_TUNNEL = 3;
78 public static final int DEFAULT_WEIGHT = 1;
79 public static final long INVALID_ID = 0;
81 private static final Logger LOG = LoggerFactory.getLogger(ItmTunnelAggregationHelper.class);
82 private static boolean tunnelAggregationEnabled;
84 private final IInterfaceManager interfaceManager;
85 private final IMdsalApiManager mdsalManager;
86 private final JobCoordinator jobCoordinator;
89 public ItmTunnelAggregationHelper(final IInterfaceManager interfaceMngr,
90 final IMdsalApiManager mdsalMngr,
91 final ItmConfig itmConfig,
92 final JobCoordinator jobCoordinator) {
93 this.interfaceManager = interfaceMngr;
94 this.mdsalManager = mdsalMngr;
95 this.jobCoordinator = jobCoordinator;
96 initTunnelAggregationConfig(itmConfig);
99 public static boolean isTunnelAggregationEnabled() {
100 return tunnelAggregationEnabled;
103 public void createLogicalTunnelSelectGroup(TypedWriteTransaction<Configuration> tx,
104 Uint64 srcDpnId, String interfaceName, int lportTag) {
105 Group group = prepareLogicalTunnelSelectGroup(interfaceName, lportTag);
106 LOG.debug("MULTIPLE_VxLAN_TUNNELS: group id {} installed for {} srcDpnId {}",
107 group.getGroupId().getValue(), interfaceName, srcDpnId);
108 mdsalManager.addGroup(tx, srcDpnId, group);
111 public void updateLogicalTunnelSelectGroup(InterfaceParentEntry entry, DataBroker broker) {
112 String logicTunnelName = entry.getParentInterface();
113 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
114 .interfaces.Interface ifaceConfig = ItmUtils.getInterface(logicTunnelName, interfaceManager);
115 if (ifaceConfig == null || !ifaceConfig.getType().isAssignableFrom(Tunnel.class)) {
118 IfTunnel ifTunnel = ifaceConfig.augmentation(IfTunnel.class);
119 if (!ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
122 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateLogicalTunnelSelectGroup name {}", logicTunnelName);
123 TunnelAggregationUpdateWorker worker =
124 new TunnelAggregationUpdateWorker(null, null, ifaceConfig, entry, MOD_GROUP_TUNNEL, broker);
125 jobCoordinator.enqueueJob(logicTunnelName, worker);
128 public void updateLogicalTunnelState(Interface ifaceState, int tunnelAction, DataBroker broker) {
129 updateLogicalTunnelState(null, ifaceState, tunnelAction, broker);
132 public void updateLogicalTunnelState(Interface ifStateOrigin, Interface ifStateUpdated,
133 int tunnelAction, DataBroker broker) {
134 if (!tunnelAggregationEnabled || ifStateUpdated == null) {
135 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateLogicalTunnelState - wrong configuration -"
136 + " tunnelAggregationEnabled {} ifStateUpdated {}", tunnelAggregationEnabled, ifStateUpdated);
139 String ifName = ifStateUpdated.getName();
140 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
141 ItmUtils.getInterface(ifName, interfaceManager);
142 IfTunnel ifTunnel = iface != null ? iface.augmentation(IfTunnel.class) : null;
143 if (iface == null || ifTunnel == null) {
144 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateLogicalTunnelState - not tunnel interface {}", ifName);
147 String logicTunnelName = null;
148 if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
149 logicTunnelName = ifStateUpdated.getName();
151 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
152 if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class) && parentRefs != null) {
153 logicTunnelName = parentRefs.getParentInterface();
156 if (logicTunnelName != null) {
157 TunnelAggregationUpdateWorker worker =
158 new TunnelAggregationUpdateWorker(ifStateOrigin, ifStateUpdated, iface, null, tunnelAction, broker);
159 jobCoordinator.enqueueJob(logicTunnelName, worker);
163 private void initTunnelAggregationConfig(ItmConfig itmConfig) {
164 // Load balancing of VxLAN feature is guarded by a global configuration option in the ITM,
165 // only when the feature is enabled, the logical tunnel interfaces should be created.
166 boolean tunnelAggregationConfigEnabled = false;
167 List<TunnelAggregation> tunnelsConfig = itmConfig != null ? itmConfig.getTunnelAggregation() : null;
168 if (tunnelsConfig != null) {
169 for (TunnelAggregation tnlCfg : tunnelsConfig) {
170 Class<? extends TunnelTypeBase> tunType = ItmUtils.getTunnelType(tnlCfg.key().getTunnelType());
171 if (tunType.isAssignableFrom(TunnelTypeVxlan.class)) {
172 tunnelAggregationConfigEnabled = tnlCfg.isEnabled();
173 LOG.info("MULTIPLE_VxLAN_TUNNELS: tunnelAggregationEnabled {}", tunnelAggregationConfigEnabled);
178 tunnelAggregationEnabled = tunnelAggregationConfigEnabled;
181 private Group prepareLogicalTunnelSelectGroup(String interfaceName, int lportTag) {
182 long groupId = interfaceManager.getLogicalTunnelSelectGroupId(lportTag);
183 return MDSALUtil.buildGroup(groupId, interfaceName, GroupTypes.GroupSelect,
184 MDSALUtil.buildBucketLists(Collections.emptyList()));
187 private Bucket createBucket(String interfaceName, IfTunnel ifTunnel, int bucketId, int portNumber) {
188 List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(interfaceName);
189 if (listActionInfo == null) {
190 listActionInfo = Collections.emptyList();
192 if (listActionInfo.isEmpty()) {
193 LOG.warn("MULTIPLE_VxLAN_TUNNELS: could not build Egress bucket for {}", interfaceName);
195 Integer portWeight = ifTunnel.getWeight() != null ? ifTunnel.getWeight().toJava() : DEFAULT_WEIGHT;
196 return MDSALUtil.buildBucket(MDSALUtil.buildActions(listActionInfo), portWeight, bucketId,
197 portNumber, MDSALUtil.WATCH_GROUP);
200 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
201 justification = "https://github.com/spotbugs/spotbugs/issues/811")
202 private void updateTunnelAggregationGroup(TypedWriteTransaction<Configuration> tx,
203 InterfaceParentEntry parentEntry) {
204 String logicTunnelName = parentEntry.getParentInterface();
205 InternalTunnel logicInternalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(logicTunnelName);
206 if (logicInternalTunnel == null) {
207 LOG.debug("MULTIPLE_VxLAN_TUNNELS: {} not found in internal tunnels list", logicTunnelName);
210 InterfaceInfo ifLogicTunnel = interfaceManager.getInterfaceInfoFromOperationalDataStore(logicTunnelName);
211 long groupId = ifLogicTunnel != null
212 ? interfaceManager.getLogicalTunnelSelectGroupId(ifLogicTunnel.getInterfaceTag()) : INVALID_ID;
213 Uint64 srcDpnId = logicInternalTunnel.getSourceDPN();
214 List<Bucket> listBuckets = new ArrayList<>();
215 List<InterfaceChildEntry> interfaceChildEntries = parentEntry.getInterfaceChildEntry();
216 if (interfaceChildEntries == null || interfaceChildEntries.isEmpty()) {
217 LOG.debug("MULTIPLE_VxLAN_TUNNELS: empty child list in group {}", parentEntry.getParentInterface());
220 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
221 String curChildName = interfaceChildEntry.getChildInterface();
222 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
223 childIface = ItmUtils.getInterface(curChildName, interfaceManager);
224 IfTunnel ifTunnel = childIface != null ? childIface.augmentation(IfTunnel.class) : null;
225 if (ifTunnel == null || !ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
226 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not tunnel interface {} found in group {}",
227 curChildName, logicTunnelName);
230 ParentRefs parentRefs = childIface.augmentation(ParentRefs.class);
231 if (parentRefs == null) {
232 LOG.debug("MULTIPLE_VxLAN_TUNNELS: parent refs not specified for interface {} in group {}",
233 curChildName, logicTunnelName);
236 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(curChildName);
237 if (ifInfo == null) {
238 LOG.debug("MULTIPLE_VxLAN_TUNNELS: interface state not found for {} in groupId {}",
239 curChildName, groupId);
242 int bucketId = interfaceChildEntries.indexOf(interfaceChildEntry);
243 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateTunnelAggregationGroup - add bucketId {} to groupId {}",
245 listBuckets.add(createBucket(curChildName, ifTunnel, bucketId, ifInfo.getPortNo()));
247 if (!listBuckets.isEmpty()) {
248 Group group = MDSALUtil.buildGroup(groupId, logicTunnelName, GroupTypes.GroupSelect,
249 MDSALUtil.buildBucketLists(listBuckets));
250 mdsalManager.addGroup(tx, srcDpnId, group);
254 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
255 justification = "https://github.com/spotbugs/spotbugs/issues/811")
256 private void updateTunnelAggregationGroupBucket(Interface ifaceState, IfTunnel ifTunnel,
257 ParentRefs parentRefs, InterfaceParentEntry groupParentEntry,
258 int action, TypedReadWriteTransaction<Configuration> tx)
259 throws ExecutionException, InterruptedException {
260 String logicTunnelName = parentRefs.getParentInterface();
261 List<InterfaceChildEntry> interfaceChildEntries = groupParentEntry.getInterfaceChildEntry();
262 if (interfaceChildEntries == null) {
263 LOG.debug("MULTIPLE_VxLAN_TUNNELS: empty child list in group {}", groupParentEntry.getParentInterface());
266 String ifaceName = ifaceState.getName();
267 InterfaceChildEntry childEntry = new InterfaceChildEntryBuilder().setChildInterface(ifaceName)
268 .withKey(new InterfaceChildEntryKey(ifaceName)).build();
269 int bucketId = interfaceChildEntries.indexOf(childEntry);
270 if (bucketId == -1) {
271 LOG.debug("MULTIPLE_VxLAN_TUNNELS: wrong child id for {} in group {}", ifaceName,
272 groupParentEntry.getParentInterface());
275 InterfaceInfo ifLogicTunnel = interfaceManager.getInterfaceInfoFromOperationalDataStore(logicTunnelName);
276 long groupId = ifLogicTunnel != null
277 ? interfaceManager.getLogicalTunnelSelectGroupId(ifLogicTunnel.getInterfaceTag()) : INVALID_ID;
278 if (groupId == INVALID_ID) {
279 LOG.warn("MULTIPLE_VxLAN_TUNNELS: unknown group id for logic tunnel {}", logicTunnelName);
282 String lowerLayerIf = ifaceState.getLowerLayerIf().get(0); // openflow:dpnid:portnum
283 String[] split = lowerLayerIf.split(IfmConstants.OF_URI_SEPARATOR);
284 Uint64 srcDpnId = Uint64.valueOf(split[1]);
285 int portNumber = Integer.parseInt(split[2]);
286 if (action == ADD_TUNNEL) {
287 if (!mdsalManager.groupExists(srcDpnId, groupId)) {
288 createLogicalTunnelSelectGroup(tx, srcDpnId, logicTunnelName, ifLogicTunnel.getInterfaceTag());
290 Bucket buckt = createBucket(ifaceName, ifTunnel, bucketId, portNumber);
291 LOG.debug("MULTIPLE_VxLAN_TUNNELS: add bucketId {} to groupId {}", bucketId, groupId);
292 mdsalManager.addBucket(tx, srcDpnId, groupId, buckt);
294 LOG.debug("MULTIPLE_VxLAN_TUNNELS: remove bucketId {} from groupId {}", bucketId, groupId);
295 mdsalManager.removeBucket(tx, srcDpnId, groupId, bucketId);
299 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
300 justification = "https://github.com/spotbugs/spotbugs/issues/811")
301 private void updateLogicalTunnelGroupOperStatus(String logicalTunnelIfaceName, Interface ifaceState,
302 InterfaceParentEntry parentEntry, TypedReadWriteTransaction<Operational> tx)
303 throws ExecutionException, InterruptedException {
304 if (parentEntry == null) {
305 LOG.debug("MULTIPLE_VxLAN_TUNNELS: uninitialized parent entry {}", logicalTunnelIfaceName);
308 OperStatus newOperStatus = getAggregatedOperStatus(ifaceState, parentEntry);
309 if (logicalTunnelIfaceName.equals(ifaceState.getName())) { //the current interface is logical tunnel itself
310 if (ifaceState.getOperStatus() != newOperStatus) {
311 updateInterfaceOperStatus(logicalTunnelIfaceName, ifaceState, newOperStatus, tx);
314 InterfaceInfo ifLogicInfo =
315 interfaceManager.getInterfaceInfoFromOperationalDataStore(logicalTunnelIfaceName);
316 if (isLogicalTunnelStateUpdateNeeded(newOperStatus, ifLogicInfo)) {
317 InstanceIdentifier<Interface> id = ItmUtils.buildStateInterfaceId(logicalTunnelIfaceName);
318 Optional<Interface> ifState = tx.read(id).get();
319 if (ifState.isPresent()) {
320 Interface ifStateLogicTunnel = ifState.get();
321 updateInterfaceOperStatus(logicalTunnelIfaceName, ifStateLogicTunnel, newOperStatus, tx);
327 private boolean isLogicalTunnelStateUpdateNeeded(OperStatus newOperStatus, InterfaceInfo ifLogicInfo) {
328 return ifLogicInfo != null && (ifLogicInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP
329 && newOperStatus == OperStatus.Down
330 || ifLogicInfo.getOpState() == InterfaceInfo.InterfaceOpState.DOWN && newOperStatus == OperStatus.Up);
333 private OperStatus getAggregatedOperStatus(Interface ifaceState, InterfaceParentEntry parentEntry) {
334 String logicalTunnelName = parentEntry.getParentInterface();
335 if (!Objects.equals(logicalTunnelName, ifaceState.getName()) && ifaceState.getOperStatus() == OperStatus.Up) {
336 return OperStatus.Up;
339 List<InterfaceChildEntry> interfaceChildEntries = parentEntry.getInterfaceChildEntry();
340 if (interfaceChildEntries == null || interfaceChildEntries.isEmpty()) {
341 LOG.debug("MULTIPLE_VxLAN_TUNNELS: OperStatus is Down, because of the empty child list in group {}",
342 parentEntry.getParentInterface());
343 return OperStatus.Down;
345 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
346 String curChildInterface = interfaceChildEntry.getChildInterface();
347 if (!Objects.equals(curChildInterface, ifaceState.getName())) {
348 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(curChildInterface);
349 if (ifInfo != null && InterfaceInfo.InterfaceOpState.UP.equals(ifInfo.getOpState())) {
350 return OperStatus.Up;
354 return OperStatus.Down;
357 private void updateInterfaceOperStatus(String ifaceName, Interface ifaceState,
358 OperStatus st, TypedWriteTransaction<Operational> tx) {
359 LOG.debug("MULTIPLE_VxLAN_TUNNELS: update OperStatus to be {} for {}", st.toString(), ifaceName);
360 InstanceIdentifier<Interface> idLogicGroup = ItmUtils.buildStateInterfaceId(ifaceName);
361 InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder(ifaceState);
362 ifaceBuilderChild.setOperStatus(st);
363 tx.merge(idLogicGroup, ifaceBuilderChild.build(), CREATE_MISSING_PARENTS);
366 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
367 justification = "https://github.com/spotbugs/spotbugs/issues/811")
368 private void updateLogicalTunnelAdminStatus(String logicalTunnelName, Interface ifOrigin,
369 Interface ifUpdated, InterfaceParentEntry parentEntry, TypedWriteTransaction<Operational> tx) {
371 if (ifOrigin == null || ifUpdated == null || ifOrigin.getAdminStatus() == ifUpdated.getAdminStatus()) {
374 List<InterfaceChildEntry> interfaceChildEntries = parentEntry.getInterfaceChildEntry();
375 if (interfaceChildEntries == null || interfaceChildEntries.isEmpty()) {
376 LOG.debug("MULTIPLE_VxLAN_TUNNELS: empty child list in group {}", logicalTunnelName);
379 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
380 String curChildInterface = interfaceChildEntry.getChildInterface();
381 updateInterfaceAdminStatus(curChildInterface, ifUpdated.getAdminStatus(), tx);
385 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
386 justification = "https://github.com/spotbugs/spotbugs/issues/811")
387 private void updateInterfaceAdminStatus(String logicalTunnelName, Interface ifState,
388 TypedWriteTransaction<Operational> tx) {
389 InterfaceInfo ifLogicTunnelInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(logicalTunnelName);
390 if (ifLogicTunnelInfo == null) {
393 if (ifState.getAdminStatus() == AdminStatus.Up
394 && ifLogicTunnelInfo.getAdminState() != InterfaceAdminState.ENABLED) {
395 updateInterfaceAdminStatus(ifState.getName(), AdminStatus.Down, tx);
399 private void updateInterfaceAdminStatus(String ifaceName, AdminStatus st, TypedWriteTransaction<Operational> tx) {
400 LOG.debug("MULTIPLE_VxLAN_TUNNELS: update AdminStatus to be {} for {}", st.toString(), ifaceName);
401 InstanceIdentifier<Interface> id = ItmUtils.buildStateInterfaceId(ifaceName);
402 InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
403 ifaceBuilderChild.withKey(new InterfaceKey(ifaceName));
404 ifaceBuilderChild.setAdminStatus(st);
405 tx.merge(id, ifaceBuilderChild.build(), CREATE_MISSING_PARENTS);
408 private class TunnelAggregationUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
410 private final Interface ifStateOrigin;
411 private final Interface ifStateUpdated;
412 private final ManagedNewTransactionRunner txRunner;
413 private final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
414 .interfaces.rev140508.interfaces.Interface ifaceConfig;
415 private final int ifaceAction;
416 private final InterfaceParentEntry parentEntry;
418 TunnelAggregationUpdateWorker(Interface ifStateOrig, Interface ifStateUpdated,
419 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
420 .interfaces.Interface iface, InterfaceParentEntry entry, int action, DataBroker broker) {
421 this.ifStateOrigin = ifStateOrig;
422 this.ifStateUpdated = ifStateUpdated;
423 this.ifaceConfig = iface;
424 this.ifaceAction = action;
425 this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
426 this.parentEntry = entry;
430 public List<ListenableFuture<Void>> call() {
431 List<ListenableFuture<Void>> futures = new ArrayList<>();
432 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
433 if (ifaceAction == MOD_GROUP_TUNNEL) {
434 updateTunnelAggregationGroup(confTx, parentEntry);
437 IfTunnel ifTunnel = ifaceConfig != null ? ifaceConfig.augmentation(IfTunnel.class) : null;
438 if (ifTunnel == null) {
439 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not tunnel interface {}", ifaceConfig.getName());
442 if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
443 String logicTunnelIfaceName = ifStateUpdated.getName();
444 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
445 final InterfaceParentEntry interfaceParentEntry =
446 getInterfaceParentEntry(logicTunnelIfaceName, confTx);
447 updateLogicalTunnelGroupOperStatus(logicTunnelIfaceName, ifStateUpdated,
448 interfaceParentEntry,
450 updateLogicalTunnelAdminStatus(logicTunnelIfaceName, ifStateOrigin, ifStateUpdated,
451 interfaceParentEntry, operTx);
455 if (!ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
456 LOG.debug("MULTIPLE_VxLAN_TUNNELS: wrong tunnel type {}", ifTunnel.getTunnelInterfaceType());
459 ParentRefs parentRefs = ifaceConfig.augmentation(ParentRefs.class);
460 if (parentRefs == null) {
461 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not updated parent ref for {}", ifaceConfig.getName());
464 String logicTunnelIfaceName = parentRefs.getParentInterface();
465 InterfaceParentEntry groupEntry = getInterfaceParentEntry(logicTunnelIfaceName, confTx);
466 if (groupEntry == null) {
467 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not found InterfaceParentEntry for {}",
468 logicTunnelIfaceName);
471 if (ifaceAction == ADD_TUNNEL) {
472 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
473 operTx -> updateInterfaceAdminStatus(logicTunnelIfaceName, ifStateUpdated, operTx)));
474 updateTunnelAggregationGroupBucket(ifStateUpdated, ifTunnel, parentRefs, groupEntry,
477 } else if (ifaceAction == DEL_TUNNEL) {
478 updateTunnelAggregationGroupBucket(ifStateUpdated, ifTunnel, parentRefs, groupEntry,
482 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
483 operTx -> updateLogicalTunnelGroupOperStatus(logicTunnelIfaceName, ifStateUpdated, groupEntry,
489 private InterfaceParentEntry getInterfaceParentEntry(String logicalGroupName,
490 TypedReadTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
491 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(logicalGroupName);
492 InstanceIdentifier.InstanceIdentifierBuilder<InterfaceParentEntry> intfIdBuilder =
493 InstanceIdentifier.builder(InterfaceChildInfo.class)
494 .child(InterfaceParentEntry.class, interfaceParentEntryKey);
495 InstanceIdentifier<InterfaceParentEntry> intfId = intfIdBuilder.build();
496 return tx.read(intfId).get().orElse(null);