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;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 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.eclipse.jdt.annotation.Nullable;
27 import org.opendaylight.genius.infra.Datastore.Configuration;
28 import org.opendaylight.genius.infra.Datastore.Operational;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
30 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
31 import org.opendaylight.genius.infra.TypedReadTransaction;
32 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
33 import org.opendaylight.genius.infra.TypedWriteTransaction;
34 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
35 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
36 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
37 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
38 import org.opendaylight.genius.itm.impl.ItmUtils;
39 import org.opendaylight.genius.mdsalutil.ActionInfo;
40 import org.opendaylight.genius.mdsalutil.MDSALUtil;
41 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
42 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
43 import org.opendaylight.mdsal.binding.api.DataBroker;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.InterfaceChildInfo;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.itm.config.TunnelAggregation;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.itm.config.TunnelAggregationKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.opendaylight.yangtools.yang.common.Uint64;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
74 public class ItmTunnelAggregationHelper {
76 public static final int ADD_TUNNEL = 0;
77 public static final int DEL_TUNNEL = 1;
78 public static final int MOD_TUNNEL = 2;
79 public static final int MOD_GROUP_TUNNEL = 3;
80 public static final int DEFAULT_WEIGHT = 1;
81 public static final long INVALID_ID = 0;
83 private static final Logger LOG = LoggerFactory.getLogger(ItmTunnelAggregationHelper.class);
84 private static boolean tunnelAggregationEnabled;
86 private final IInterfaceManager interfaceManager;
87 private final IMdsalApiManager mdsalManager;
88 private final JobCoordinator jobCoordinator;
91 public ItmTunnelAggregationHelper(final IInterfaceManager interfaceMngr,
92 final IMdsalApiManager mdsalMngr,
93 final ItmConfig itmConfig,
94 final JobCoordinator jobCoordinator) {
95 this.interfaceManager = interfaceMngr;
96 this.mdsalManager = mdsalMngr;
97 this.jobCoordinator = jobCoordinator;
98 initTunnelAggregationConfig(itmConfig);
101 public static boolean isTunnelAggregationEnabled() {
102 return tunnelAggregationEnabled;
105 public void createLogicalTunnelSelectGroup(TypedWriteTransaction<Configuration> tx,
106 Uint64 srcDpnId, String interfaceName, int lportTag) {
107 Group group = prepareLogicalTunnelSelectGroup(interfaceName, lportTag);
108 LOG.debug("MULTIPLE_VxLAN_TUNNELS: group id {} installed for {} srcDpnId {}",
109 group.getGroupId().getValue(), interfaceName, srcDpnId);
110 mdsalManager.addGroup(tx, srcDpnId, group);
113 public void updateLogicalTunnelSelectGroup(InterfaceParentEntry entry, DataBroker broker) {
114 String logicTunnelName = entry.getParentInterface();
115 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
116 .interfaces.Interface ifaceConfig = ItmUtils.getInterface(logicTunnelName, interfaceManager);
117 if (ifaceConfig == null || !ifaceConfig.getType().isAssignableFrom(Tunnel.class)) {
120 IfTunnel ifTunnel = ifaceConfig.augmentation(IfTunnel.class);
121 if (!ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
124 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateLogicalTunnelSelectGroup name {}", logicTunnelName);
125 TunnelAggregationUpdateWorker worker =
126 new TunnelAggregationUpdateWorker(null, null, ifaceConfig, entry, MOD_GROUP_TUNNEL, broker);
127 jobCoordinator.enqueueJob(logicTunnelName, worker);
130 public void updateLogicalTunnelState(Interface ifaceState, int tunnelAction, DataBroker broker) {
131 updateLogicalTunnelState(null, ifaceState, tunnelAction, broker);
134 public void updateLogicalTunnelState(Interface ifStateOrigin, Interface ifStateUpdated,
135 int tunnelAction, DataBroker broker) {
136 if (!tunnelAggregationEnabled || ifStateUpdated == null) {
137 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateLogicalTunnelState - wrong configuration -"
138 + " tunnelAggregationEnabled {} ifStateUpdated {}", tunnelAggregationEnabled, ifStateUpdated);
141 String ifName = ifStateUpdated.getName();
142 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
143 ItmUtils.getInterface(ifName, interfaceManager);
144 IfTunnel ifTunnel = iface != null ? iface.augmentation(IfTunnel.class) : null;
145 if (iface == null || ifTunnel == null) {
146 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateLogicalTunnelState - not tunnel interface {}", ifName);
149 String logicTunnelName = null;
150 if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
151 logicTunnelName = ifStateUpdated.getName();
153 ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
154 if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class) && parentRefs != null) {
155 logicTunnelName = parentRefs.getParentInterface();
158 if (logicTunnelName != null) {
159 TunnelAggregationUpdateWorker worker =
160 new TunnelAggregationUpdateWorker(ifStateOrigin, ifStateUpdated, iface, null, tunnelAction, broker);
161 jobCoordinator.enqueueJob(logicTunnelName, worker);
165 private void initTunnelAggregationConfig(ItmConfig itmConfig) {
166 // Load balancing of VxLAN feature is guarded by a global configuration option in the ITM,
167 // only when the feature is enabled, the logical tunnel interfaces should be created.
168 boolean tunnelAggregationConfigEnabled = false;
169 Map<TunnelAggregationKey, TunnelAggregation> tunnelsConfig = itmConfig != null
170 ? itmConfig.getTunnelAggregation() : null;
171 if (tunnelsConfig != null) {
172 for (TunnelAggregation tnlCfg : tunnelsConfig.values()) {
173 Class<? extends TunnelTypeBase> tunType = ItmUtils.getTunnelType(tnlCfg.key().getTunnelType());
174 if (tunType.isAssignableFrom(TunnelTypeVxlan.class)) {
175 tunnelAggregationConfigEnabled = tnlCfg.isEnabled();
176 LOG.info("MULTIPLE_VxLAN_TUNNELS: tunnelAggregationEnabled {}", tunnelAggregationConfigEnabled);
181 tunnelAggregationEnabled = tunnelAggregationConfigEnabled;
184 private Group prepareLogicalTunnelSelectGroup(String interfaceName, int lportTag) {
185 long groupId = interfaceManager.getLogicalTunnelSelectGroupId(lportTag);
186 return MDSALUtil.buildGroup(groupId, interfaceName, GroupTypes.GroupSelect,
187 MDSALUtil.buildBucketLists(Collections.emptyList()));
190 private Bucket createBucket(String interfaceName, IfTunnel ifTunnel, int bucketId, int portNumber) {
191 List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(interfaceName);
192 if (listActionInfo == null) {
193 listActionInfo = Collections.emptyList();
195 if (listActionInfo.isEmpty()) {
196 LOG.warn("MULTIPLE_VxLAN_TUNNELS: could not build Egress bucket for {}", interfaceName);
198 Integer portWeight = ifTunnel.getWeight() != null ? ifTunnel.getWeight().toJava() : DEFAULT_WEIGHT;
199 return MDSALUtil.buildBucket(MDSALUtil.buildActions(listActionInfo), portWeight, bucketId,
200 portNumber, MDSALUtil.WATCH_GROUP);
203 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
204 justification = "https://github.com/spotbugs/spotbugs/issues/811")
205 private void updateTunnelAggregationGroup(TypedWriteTransaction<Configuration> tx,
206 InterfaceParentEntry parentEntry) {
207 String logicTunnelName = parentEntry.getParentInterface();
208 InternalTunnel logicInternalTunnel = ItmUtils.ITM_CACHE.getInternalTunnel(logicTunnelName);
209 if (logicInternalTunnel == null) {
210 LOG.debug("MULTIPLE_VxLAN_TUNNELS: {} not found in internal tunnels list", logicTunnelName);
213 InterfaceInfo ifLogicTunnel = interfaceManager.getInterfaceInfoFromOperationalDataStore(logicTunnelName);
214 long groupId = ifLogicTunnel != null
215 ? interfaceManager.getLogicalTunnelSelectGroupId(ifLogicTunnel.getInterfaceTag()) : INVALID_ID;
216 Uint64 srcDpnId = logicInternalTunnel.getSourceDPN();
217 List<Bucket> listBuckets = new ArrayList<>();
218 @Nullable Map<InterfaceChildEntryKey, InterfaceChildEntry> interfaceChildEntries =
219 parentEntry.getInterfaceChildEntry();
220 if (interfaceChildEntries == null || interfaceChildEntries.isEmpty()) {
221 LOG.debug("MULTIPLE_VxLAN_TUNNELS: empty child list in group {}", parentEntry.getParentInterface());
224 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries.values()) {
225 String curChildName = interfaceChildEntry.getChildInterface();
226 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
227 childIface = ItmUtils.getInterface(curChildName, interfaceManager);
228 IfTunnel ifTunnel = childIface != null ? childIface.augmentation(IfTunnel.class) : null;
229 if (ifTunnel == null || !ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
230 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not tunnel interface {} found in group {}",
231 curChildName, logicTunnelName);
234 ParentRefs parentRefs = childIface.augmentation(ParentRefs.class);
235 if (parentRefs == null) {
236 LOG.debug("MULTIPLE_VxLAN_TUNNELS: parent refs not specified for interface {} in group {}",
237 curChildName, logicTunnelName);
240 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(curChildName);
241 if (ifInfo == null) {
242 LOG.debug("MULTIPLE_VxLAN_TUNNELS: interface state not found for {} in groupId {}",
243 curChildName, groupId);
247 List<InterfaceChildEntry> val = new ArrayList<>(interfaceChildEntries.values());
248 int bucketId = val.indexOf(interfaceChildEntry);
250 LOG.debug("MULTIPLE_VxLAN_TUNNELS: updateTunnelAggregationGroup - add bucketId {} to groupId {}",
252 listBuckets.add(createBucket(curChildName, ifTunnel, bucketId, ifInfo.getPortNo()));
254 if (!listBuckets.isEmpty()) {
255 Group group = MDSALUtil.buildGroup(groupId, logicTunnelName, GroupTypes.GroupSelect,
256 MDSALUtil.buildBucketLists(listBuckets));
257 mdsalManager.addGroup(tx, srcDpnId, group);
261 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
262 justification = "https://github.com/spotbugs/spotbugs/issues/811")
263 private void updateTunnelAggregationGroupBucket(Interface ifaceState, IfTunnel ifTunnel,
264 ParentRefs parentRefs, InterfaceParentEntry groupParentEntry,
265 int action, TypedReadWriteTransaction<Configuration> tx)
266 throws ExecutionException, InterruptedException {
267 String logicTunnelName = parentRefs.getParentInterface();
268 @Nullable Map<InterfaceChildEntryKey, InterfaceChildEntry> interfaceChildEntries =
269 groupParentEntry.getInterfaceChildEntry();
270 if (interfaceChildEntries == null) {
271 LOG.debug("MULTIPLE_VxLAN_TUNNELS: empty child list in group {}", groupParentEntry.getParentInterface());
274 String ifaceName = ifaceState.getName();
275 InterfaceChildEntry childEntry = new InterfaceChildEntryBuilder().setChildInterface(ifaceName)
276 .withKey(new InterfaceChildEntryKey(ifaceName)).build();
277 List<InterfaceChildEntry> val = new ArrayList<>(interfaceChildEntries.values());
278 int bucketId = val.indexOf(childEntry);
280 if (bucketId == -1) {
281 LOG.debug("MULTIPLE_VxLAN_TUNNELS: wrong child id for {} in group {}", ifaceName,
282 groupParentEntry.getParentInterface());
285 InterfaceInfo ifLogicTunnel = interfaceManager.getInterfaceInfoFromOperationalDataStore(logicTunnelName);
286 long groupId = ifLogicTunnel != null
287 ? interfaceManager.getLogicalTunnelSelectGroupId(ifLogicTunnel.getInterfaceTag()) : INVALID_ID;
288 if (groupId == INVALID_ID) {
289 LOG.warn("MULTIPLE_VxLAN_TUNNELS: unknown group id for logic tunnel {}", logicTunnelName);
292 String lowerLayerIf = ifaceState.getLowerLayerIf().get(0); // openflow:dpnid:portnum
293 String[] split = lowerLayerIf.split(IfmConstants.OF_URI_SEPARATOR);
294 Uint64 srcDpnId = Uint64.valueOf(split[1]);
295 int portNumber = Integer.parseInt(split[2]);
296 if (action == ADD_TUNNEL) {
297 if (!mdsalManager.groupExists(srcDpnId, groupId)) {
298 createLogicalTunnelSelectGroup(tx, srcDpnId, logicTunnelName, ifLogicTunnel.getInterfaceTag());
300 Bucket buckt = createBucket(ifaceName, ifTunnel, bucketId, portNumber);
301 LOG.debug("MULTIPLE_VxLAN_TUNNELS: add bucketId {} to groupId {}", bucketId, groupId);
302 mdsalManager.addBucket(tx, srcDpnId, groupId, buckt);
304 LOG.debug("MULTIPLE_VxLAN_TUNNELS: remove bucketId {} from groupId {}", bucketId, groupId);
305 mdsalManager.removeBucket(tx, srcDpnId, groupId, bucketId);
309 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
310 justification = "https://github.com/spotbugs/spotbugs/issues/811")
311 private void updateLogicalTunnelGroupOperStatus(String logicalTunnelIfaceName, Interface ifaceState,
312 InterfaceParentEntry parentEntry, TypedReadWriteTransaction<Operational> tx)
313 throws ExecutionException, InterruptedException {
314 if (parentEntry == null) {
315 LOG.debug("MULTIPLE_VxLAN_TUNNELS: uninitialized parent entry {}", logicalTunnelIfaceName);
318 OperStatus newOperStatus = getAggregatedOperStatus(ifaceState, parentEntry);
319 if (logicalTunnelIfaceName.equals(ifaceState.getName())) { //the current interface is logical tunnel itself
320 if (ifaceState.getOperStatus() != newOperStatus) {
321 updateInterfaceOperStatus(logicalTunnelIfaceName, ifaceState, newOperStatus, tx);
324 InterfaceInfo ifLogicInfo =
325 interfaceManager.getInterfaceInfoFromOperationalDataStore(logicalTunnelIfaceName);
326 if (isLogicalTunnelStateUpdateNeeded(newOperStatus, ifLogicInfo)) {
327 InstanceIdentifier<Interface> id = ItmUtils.buildStateInterfaceId(logicalTunnelIfaceName);
328 Optional<Interface> ifState = tx.read(id).get();
329 if (ifState.isPresent()) {
330 Interface ifStateLogicTunnel = ifState.get();
331 updateInterfaceOperStatus(logicalTunnelIfaceName, ifStateLogicTunnel, newOperStatus, tx);
337 private boolean isLogicalTunnelStateUpdateNeeded(OperStatus newOperStatus, InterfaceInfo ifLogicInfo) {
338 return ifLogicInfo != null && (ifLogicInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP
339 && newOperStatus == OperStatus.Down
340 || ifLogicInfo.getOpState() == InterfaceInfo.InterfaceOpState.DOWN && newOperStatus == OperStatus.Up);
343 private OperStatus getAggregatedOperStatus(Interface ifaceState, InterfaceParentEntry parentEntry) {
344 String logicalTunnelName = parentEntry.getParentInterface();
345 if (!Objects.equals(logicalTunnelName, ifaceState.getName()) && ifaceState.getOperStatus() == OperStatus.Up) {
346 return OperStatus.Up;
349 @Nullable Map<InterfaceChildEntryKey, InterfaceChildEntry> interfaceChildEntries =
350 parentEntry.getInterfaceChildEntry();
351 if (interfaceChildEntries == null || interfaceChildEntries.isEmpty()) {
352 LOG.debug("MULTIPLE_VxLAN_TUNNELS: OperStatus is Down, because of the empty child list in group {}",
353 parentEntry.getParentInterface());
354 return OperStatus.Down;
356 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries.values()) {
357 String curChildInterface = interfaceChildEntry.getChildInterface();
358 if (!Objects.equals(curChildInterface, ifaceState.getName())) {
359 InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(curChildInterface);
360 if (ifInfo != null && InterfaceInfo.InterfaceOpState.UP.equals(ifInfo.getOpState())) {
361 return OperStatus.Up;
365 return OperStatus.Down;
368 private void updateInterfaceOperStatus(String ifaceName, Interface ifaceState,
369 OperStatus st, TypedWriteTransaction<Operational> tx) {
370 LOG.debug("MULTIPLE_VxLAN_TUNNELS: update OperStatus to be {} for {}", st.toString(), ifaceName);
371 InstanceIdentifier<Interface> idLogicGroup = ItmUtils.buildStateInterfaceId(ifaceName);
372 InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder(ifaceState);
373 ifaceBuilderChild.setOperStatus(st);
374 tx.mergeParentStructureMerge(idLogicGroup, ifaceBuilderChild.build());
377 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
378 justification = "https://github.com/spotbugs/spotbugs/issues/811")
379 private void updateLogicalTunnelAdminStatus(String logicalTunnelName, Interface ifOrigin,
380 Interface ifUpdated, InterfaceParentEntry parentEntry, TypedWriteTransaction<Operational> tx) {
382 if (ifOrigin == null || ifUpdated == null || ifOrigin.getAdminStatus() == ifUpdated.getAdminStatus()) {
385 @Nullable Map<InterfaceChildEntryKey, InterfaceChildEntry> interfaceChildEntries =
386 parentEntry.getInterfaceChildEntry();
387 if (interfaceChildEntries == null || interfaceChildEntries.isEmpty()) {
388 LOG.debug("MULTIPLE_VxLAN_TUNNELS: empty child list in group {}", logicalTunnelName);
391 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries.values()) {
392 String curChildInterface = interfaceChildEntry.getChildInterface();
393 updateInterfaceAdminStatus(curChildInterface, ifUpdated.getAdminStatus(), tx);
397 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
398 justification = "https://github.com/spotbugs/spotbugs/issues/811")
399 private void updateInterfaceAdminStatus(String logicalTunnelName, Interface ifState,
400 TypedWriteTransaction<Operational> tx) {
401 InterfaceInfo ifLogicTunnelInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(logicalTunnelName);
402 if (ifLogicTunnelInfo == null) {
405 if (ifState.getAdminStatus() == AdminStatus.Up
406 && ifLogicTunnelInfo.getAdminState() != InterfaceAdminState.ENABLED) {
407 updateInterfaceAdminStatus(ifState.getName(), AdminStatus.Down, tx);
411 private void updateInterfaceAdminStatus(String ifaceName, AdminStatus st, TypedWriteTransaction<Operational> tx) {
412 LOG.debug("MULTIPLE_VxLAN_TUNNELS: update AdminStatus to be {} for {}", st.toString(), ifaceName);
413 InstanceIdentifier<Interface> id = ItmUtils.buildStateInterfaceId(ifaceName);
414 InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
415 ifaceBuilderChild.withKey(new InterfaceKey(ifaceName));
416 ifaceBuilderChild.setAdminStatus(st);
417 tx.mergeParentStructureMerge(id, ifaceBuilderChild.build());
420 private class TunnelAggregationUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
422 private final Interface ifStateOrigin;
423 private final Interface ifStateUpdated;
424 private final ManagedNewTransactionRunner txRunner;
425 private final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
426 .interfaces.rev140508.interfaces.Interface ifaceConfig;
427 private final int ifaceAction;
428 private final InterfaceParentEntry parentEntry;
430 TunnelAggregationUpdateWorker(Interface ifStateOrig, Interface ifStateUpdated,
431 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
432 .interfaces.Interface iface, InterfaceParentEntry entry, int action, DataBroker broker) {
433 this.ifStateOrigin = ifStateOrig;
434 this.ifStateUpdated = ifStateUpdated;
435 this.ifaceConfig = iface;
436 this.ifaceAction = action;
437 this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
438 this.parentEntry = entry;
442 public List<ListenableFuture<Void>> call() {
443 List<ListenableFuture<Void>> futures = new ArrayList<>();
444 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
445 if (ifaceAction == MOD_GROUP_TUNNEL) {
446 updateTunnelAggregationGroup(confTx, parentEntry);
449 IfTunnel ifTunnel = ifaceConfig != null ? ifaceConfig.augmentation(IfTunnel.class) : null;
450 if (ifTunnel == null) {
451 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not tunnel interface {}", ifaceConfig.getName());
454 if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
455 String logicTunnelIfaceName = ifStateUpdated.getName();
456 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
457 final InterfaceParentEntry interfaceParentEntry =
458 getInterfaceParentEntry(logicTunnelIfaceName, confTx);
459 updateLogicalTunnelGroupOperStatus(logicTunnelIfaceName, ifStateUpdated,
460 interfaceParentEntry,
462 updateLogicalTunnelAdminStatus(logicTunnelIfaceName, ifStateOrigin, ifStateUpdated,
463 interfaceParentEntry, operTx);
467 if (!ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
468 LOG.debug("MULTIPLE_VxLAN_TUNNELS: wrong tunnel type {}", ifTunnel.getTunnelInterfaceType());
471 ParentRefs parentRefs = ifaceConfig.augmentation(ParentRefs.class);
472 if (parentRefs == null) {
473 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not updated parent ref for {}", ifaceConfig.getName());
476 String logicTunnelIfaceName = parentRefs.getParentInterface();
477 InterfaceParentEntry groupEntry = getInterfaceParentEntry(logicTunnelIfaceName, confTx);
478 if (groupEntry == null) {
479 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not found InterfaceParentEntry for {}",
480 logicTunnelIfaceName);
483 if (ifaceAction == ADD_TUNNEL) {
484 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
485 operTx -> updateInterfaceAdminStatus(logicTunnelIfaceName, ifStateUpdated, operTx)));
486 updateTunnelAggregationGroupBucket(ifStateUpdated, ifTunnel, parentRefs, groupEntry,
489 } else if (ifaceAction == DEL_TUNNEL) {
490 updateTunnelAggregationGroupBucket(ifStateUpdated, ifTunnel, parentRefs, groupEntry,
494 futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
495 operTx -> updateLogicalTunnelGroupOperStatus(logicTunnelIfaceName, ifStateUpdated, groupEntry,
501 private InterfaceParentEntry getInterfaceParentEntry(String logicalGroupName,
502 TypedReadTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
503 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(logicalGroupName);
504 InstanceIdentifier.InstanceIdentifierBuilder<InterfaceParentEntry> intfIdBuilder =
505 InstanceIdentifier.builder(InterfaceChildInfo.class)
506 .child(InterfaceParentEntry.class, interfaceParentEntryKey);
507 InstanceIdentifier<InterfaceParentEntry> intfId = intfIdBuilder.build();
508 return tx.read(intfId).get().orElse(null);