2 * Copyright © 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
9 package org.opendaylight.genius.interfacemanager.commons;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19 import java.util.stream.Collectors;
20 import org.apache.commons.lang3.BooleanUtils;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.genius.interfacemanager.IfmConstants;
25 import org.opendaylight.genius.interfacemanager.IfmUtil;
26 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
27 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils;
28 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
29 import org.opendaylight.genius.mdsalutil.FlowEntity;
30 import org.opendaylight.genius.mdsalutil.InstructionInfo;
31 import org.opendaylight.genius.mdsalutil.MDSALUtil;
32 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
33 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
34 import org.opendaylight.genius.mdsalutil.NwConstants;
35 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
36 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
37 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
38 import org.opendaylight.genius.mdsalutil.matches.MatchInPort;
39 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchTunnelDestinationIp;
40 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchTunnelSourceIp;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
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.meta.rev160406.dpn.to._interface.list.DpnToInterface;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
75 public final class InterfaceManagerCommonUtils {
76 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
77 private static ConcurrentHashMap<String, Interface> interfaceConfigMap = new ConcurrentHashMap<>();
78 private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf
79 .params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceStateMap =
80 new ConcurrentHashMap<>();
81 private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
82 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus> bfdStateMap =
83 new ConcurrentHashMap<>();
85 private static final String NOVA_PORT_REGEX = "(tap|vhu)[0-9a-f]{8}-[0-9a-f]{2}";
86 private static final String TUNNEL_PORT_REGEX = "tun[0-9a-f]{11}";
87 private static final String NOVA_OR_TUNNEL_PORT_REGEX = NOVA_PORT_REGEX + "|" + TUNNEL_PORT_REGEX;
89 private static final Pattern NOVA_OR_TUNNEL_PORT_PATTERN = Pattern.compile(NOVA_OR_TUNNEL_PORT_REGEX);
90 private static final Pattern TUNNEL_PORT_PATTERN = Pattern.compile(TUNNEL_PORT_REGEX);
91 private static final Pattern NOVA_PORT_PATTERN = Pattern.compile(NOVA_PORT_REGEX);
93 private InterfaceManagerCommonUtils() {
96 public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
97 DataBroker dataBroker) {
98 NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
99 InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
100 .child(Node.class, new NodeKey(nodeId))
101 .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
103 return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ncIdentifier, dataBroker).orNull();
106 public static boolean isNodePresent(DataBroker dataBroker, NodeConnectorId nodeConnectorId) {
107 NodeId nodeID = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
108 InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
109 .child(Node.class, new NodeKey(nodeID)).build();
110 return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier, dataBroker).isPresent();
113 public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
114 InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder = InstanceIdentifier
115 .builder(Interfaces.class).child(Interface.class, interfaceKey);
116 return interfaceInstanceIdentifierBuilder.build();
119 public static List<Interface> getAllTunnelInterfaces(DataBroker dataBroker,
120 InterfaceInfo.InterfaceType interfaceType) {
121 List<Interface> vxlanList = new ArrayList<>();
122 InstanceIdentifier<Interfaces> interfacesInstanceIdentifier = InstanceIdentifier.builder(Interfaces.class)
124 Optional<Interfaces> interfacesOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION,
125 interfacesInstanceIdentifier, dataBroker);
126 if (!interfacesOptional.isPresent()) {
129 Interfaces interfaces = interfacesOptional.get();
130 List<Interface> interfacesList = interfaces.getInterface();
131 for (Interface iface : interfacesList) {
132 if (IfmUtil.getInterfaceType(iface) == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE
133 && iface.getAugmentation(IfTunnel.class).isInternal()) {
134 vxlanList.add(iface);
140 public static List<Interface> getAllTunnelInterfacesFromCache() {
141 return interfaceConfigMap.values().stream()
142 .filter(iface -> IfmUtil.getInterfaceType(iface) == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE
143 && iface.getAugmentation(IfTunnel.class).isInternal())
144 .collect(Collectors.toList());
147 public static List<Interface> getAllVlanInterfacesFromCache() {
148 return interfaceConfigMap.values().stream()
149 .filter(iface -> IfmUtil.getInterfaceType(iface) == InterfaceInfo.InterfaceType.VLAN_INTERFACE)
150 .collect(Collectors.toList());
154 * Searches for an interface by its name.
156 * @param interfaceName
157 * name of the interface to search for
159 * data tree store to start searching for the interface
160 * @return the Interface object
162 public static Interface getInterfaceFromConfigDS(String interfaceName, DataBroker dataBroker) {
163 Interface iface = interfaceConfigMap.get(interfaceName);
167 InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(new InterfaceKey(interfaceName));
168 Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId,
170 if (interfaceOptional.isPresent()) {
171 iface = interfaceOptional.get();
172 interfaceConfigMap.put(iface.getName(), iface);
178 public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
179 return getInterfaceFromConfigDS(interfaceKey.getName(), dataBroker);
182 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
183 .Interface getInterfaceStateFromCache(
184 String interfaceName) {
185 return interfaceStateMap.get(interfaceName);
188 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
189 .Interface getInterfaceStateFromOperDS(String interfaceName, DataBroker dataBroker) {
190 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
191 ifState = getInterfaceStateFromCache(interfaceName);
192 if (ifState != null) {
195 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
196 .Interface> ifStateOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
197 IfmUtil.buildStateInterfaceId(interfaceName), dataBroker);
198 if (ifStateOptional.isPresent()) {
199 ifState = ifStateOptional.get();
200 interfaceStateMap.put(ifState.getName(), ifState);
206 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
207 .ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
208 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
209 .ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId,
210 DataBroker dataBroker) {
211 return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker).orNull();
214 public static void makeTunnelIngressFlow(List<ListenableFuture<Void>> futures, IMdsalApiManager mdsalApiManager,
215 IfTunnel tunnel, BigInteger dpnId, long portNo, String interfaceName, int ifIndex, int addOrRemoveFlow) {
216 LOG.debug("make tunnel ingress flow for {}", interfaceName);
217 String flowRef = InterfaceManagerCommonUtils.getTunnelInterfaceFlowRef(dpnId,
218 NwConstants.VLAN_INTERFACE_INGRESS_TABLE, interfaceName);
219 List<MatchInfoBase> matches = new ArrayList<>();
220 List<InstructionInfo> mkInstructions = new ArrayList<>();
221 if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
222 matches.add(new MatchInPort(dpnId, portNo));
223 if (BooleanUtils.isTrue(tunnel.isTunnelRemoteIpFlow())) {
224 matches.add(new NxMatchTunnelSourceIp(tunnel.getTunnelDestination().getIpv4Address()));
226 if (BooleanUtils.isTrue(tunnel.isTunnelSourceIpFlow())) {
227 matches.add(new NxMatchTunnelDestinationIp(tunnel.getTunnelSource().getIpv4Address()));
231 new InstructionWriteMetadata(MetaDataUtil.getLportTagMetaData(ifIndex).or(BigInteger.ONE),
232 MetaDataUtil.METADATA_MASK_LPORT_TAG_SH_FLAG));
233 short tableId = tunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class)
234 ? NwConstants.L3_LFIB_TABLE
235 : tunnel.isInternal() ? NwConstants.INTERNAL_TUNNEL_TABLE : NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL;
236 mkInstructions.add(new InstructionGotoTable(tableId));
239 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, flowRef,
240 IfmConstants.DEFAULT_FLOW_PRIORITY, interfaceName, 0, 0, NwConstants.COOKIE_VM_INGRESS_TABLE, matches,
242 if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
243 mdsalApiManager.batchedAddFlow(dpnId, flowEntity);
245 mdsalApiManager.batchedRemoveFlow(dpnId, flowEntity);
249 public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
250 return String.valueOf(dpnId) + tableId + ifName;
253 public static void setOpStateForInterface(DataBroker broker, String interfaceName,
254 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
255 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opStatus) {
256 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
257 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = IfmUtil
258 .buildStateInterfaceId(interfaceName);
259 InterfaceBuilder ifaceBuilder = new InterfaceBuilder()
260 .setKey(new org.opendaylight.yang.gen.v1.urn
261 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
263 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
264 .ietf.interfaces.rev140508.interfaces.state.Interface interfaceData = ifaceBuilder
265 .setOperStatus(opStatus).build();
266 MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
269 public static void createInterfaceChildEntry(String parentInterface, String childInterface,
270 Optional<WriteTransaction> txOptional) {
271 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
272 InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
273 InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
274 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
275 InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
276 .setChildInterface(childInterface);
277 if (!txOptional.isPresent()) {
278 BatchingUtils.write(intfId, entryBuilder.build(), BatchingUtils.EntityType.DEFAULT_CONFIG);
280 txOptional.get().put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(), true);
284 public static void deleteInterfaceChildEntry(String parentInterface, String childInterface) {
285 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
286 InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
287 InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
288 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
289 BatchingUtils.delete(intfId, BatchingUtils.EntityType.DEFAULT_CONFIG);
292 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
293 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus updateStateEntry(
294 Interface interfaceNew, DataBroker dataBroker, WriteTransaction transaction,
295 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
296 .ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
297 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
298 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus;
299 if (!interfaceNew.isEnabled()) {
300 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
301 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
303 String ncStr = ifState.getLowerLayerIf().get(0);
304 NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
305 NodeConnector nodeConnector = InterfaceManagerCommonUtils
306 .getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
307 FlowCapableNodeConnector flowCapableNodeConnector = nodeConnector
308 .getAugmentation(FlowCapableNodeConnector.class);
309 // State state = flowCapableNodeConnector.getState();
310 operStatus = flowCapableNodeConnector == null
311 ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
312 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down
313 : org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
314 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up;
317 String ifName = interfaceNew.getName();
318 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
319 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
320 .buildStateInterfaceId(interfaceNew.getName());
321 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
322 ifaceBuilder.setOperStatus(operStatus);
323 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
324 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
328 public static void updateOperStatus(String interfaceName,
329 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
330 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
331 WriteTransaction transaction) {
332 LOG.debug("updating operational status for interface {}", interfaceName);
333 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
334 .ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId = IfmUtil
335 .buildStateInterfaceId(interfaceName);
336 InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
337 ifaceBuilderChild.setOperStatus(operStatus);
338 ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
339 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilderChild.build());
342 public static void addStateEntry(String interfaceName, DataBroker dataBroker,
343 IdManagerService idManager, List<ListenableFuture<Void>> futures,
344 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
345 .ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
346 WriteTransaction interfaceOperShardTransaction = dataBroker.newWriteOnlyTransaction();
347 addStateEntry(interfaceName, dataBroker, interfaceOperShardTransaction, idManager, futures, ifState);
348 futures.add(interfaceOperShardTransaction.submit());
351 public static void addStateEntry(String interfaceName, DataBroker dataBroker,
352 WriteTransaction interfaceOperShardTransaction,
353 IdManagerService idManager, List<ListenableFuture<Void>> futures,
354 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
355 .ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
356 // allocate lport tag and create interface-if-index map.
357 // This is done even if interface-state is not present, so that there is
359 // on id allocation even when multiple southbound port_up events come in
361 Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
362 InterfaceMetaUtils.createLportTagInterfaceMap(interfaceOperShardTransaction, interfaceName, ifIndex);
363 if (ifState == null) {
364 LOG.debug("received null ifState (for parent), cannot add state for {}", interfaceName);
367 LOG.debug("adding interface state for {}", interfaceName);
368 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
369 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus = ifState
371 PhysAddress physAddress = ifState.getPhysAddress();
372 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
373 .ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus = ifState
375 NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
376 InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
377 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
378 .ietf.interfaces.rev140508.interfaces.Interface interfaceInfo = InterfaceManagerCommonUtils
379 .getInterfaceFromConfigDS(interfaceKey, dataBroker);
381 if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
382 operStatus = org.opendaylight.yang.gen.v1.urn
383 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
386 List<String> childLowerLayerIfList = new ArrayList<>();
387 childLowerLayerIfList.add(0, nodeConnectorId.getValue());
388 InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
389 .setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
390 ifaceBuilder.setIfIndex(ifIndex);
392 if (interfaceInfo != null) {
393 ifaceBuilder.setType(interfaceInfo.getType());
395 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
396 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
397 .ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
398 .buildStateInterfaceId(interfaceName);
399 interfaceOperShardTransaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
401 // install ingress flow
402 BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
403 long portNo = IfmUtil.getPortNumberFromNodeConnectorId(nodeConnectorId);
404 if (interfaceInfo != null && interfaceInfo.isEnabled() && ifState
405 .getOperStatus() == org.opendaylight.yang.gen.v1.urn
406 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up) {
407 FlowBasedServicesUtils.installLportIngressFlow(dpId, portNo, interfaceInfo, futures, dataBroker, ifIndex);
408 FlowBasedServicesUtils.bindDefaultEgressDispatcherService(dataBroker, futures,
409 interfaceInfo, Long.toString(portNo), interfaceName, ifIndex);
412 // Update the DpnToInterfaceList OpDS
413 createOrUpdateDpnToInterface(dpId, interfaceName,interfaceOperShardTransaction);
416 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
417 .ietf.interfaces.rev140508.interfaces.state.Interface addStateEntry(
418 Interface interfaceInfo, String interfaceName, WriteTransaction transaction, IdManagerService idManager,
419 PhysAddress physAddress, OperStatus operStatus, AdminStatus adminStatus, NodeConnectorId nodeConnectorId) {
420 LOG.debug("adding interface state for {}", interfaceName);
421 InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
423 if (interfaceInfo != null) {
424 if (!interfaceInfo.isEnabled()) {
425 operStatus = OperStatus.Down;
427 ifaceBuilder.setType(interfaceInfo.getType());
428 // retrieve if-index only for northbound configured interfaces
429 ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
430 ifaceBuilder.setIfIndex(ifIndex);
431 InterfaceMetaUtils.createLportTagInterfaceMap(transaction, interfaceName, ifIndex);
433 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
434 .ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
435 .buildStateInterfaceId(interfaceName);
436 List<String> childLowerLayerIfList = new ArrayList<>();
437 childLowerLayerIfList.add(0, nodeConnectorId.getValue());
438 ifaceBuilder.setAdminStatus(adminStatus).setOperStatus(operStatus).setPhysAddress(physAddress)
439 .setLowerLayerIf(childLowerLayerIfList);
440 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
441 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
442 .ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifaceBuilder
444 if (InterfaceManagerCommonUtils.isTunnelInterface(interfaceInfo)) {
445 BatchingUtils.write(ifStateId, ifState, BatchingUtils.EntityType.DEFAULT_OPERATIONAL);
447 transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifState, true);
450 BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
451 // Update the DpnToInterfaceList OpDS
452 createOrUpdateDpnToInterface(dpId, interfaceName, transaction);
456 public static boolean checkIfBfdStateIsDown(String interfaceName) {
457 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
458 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus = InterfaceManagerCommonUtils
459 .getBfdStateFromCache(interfaceName);
460 return operStatus == org.opendaylight.yang.gen.v1.urn
461 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
465 public static void deleteStateEntry(String interfaceName, WriteTransaction transaction) {
466 LOG.debug("removing interface state entry for {}", interfaceName);
467 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
468 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId = IfmUtil
469 .buildStateInterfaceId(interfaceName);
470 transaction.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
473 public static void deleteInterfaceStateInformation(String interfaceName, WriteTransaction transaction,
474 IdManagerService idManagerService) {
475 LOG.debug("removing interface state information for {}", interfaceName);
476 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn
477 .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
478 .buildStateInterfaceId(interfaceName);
479 transaction.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
480 InterfaceMetaUtils.removeLportTagInterfaceMap(idManagerService, transaction, interfaceName);
483 // For trunk interfaces, binding to a parent interface which is already
484 // bound to another trunk interface should not
486 public static boolean createInterfaceChildEntryIfNotPresent(DataBroker dataBroker, WriteTransaction tx,
487 String parentInterface, String childInterface,
488 IfL2vlan.L2vlanMode l2vlanMode) {
489 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
490 InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils
491 .getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
492 InterfaceParentEntry interfaceParentEntry = InterfaceMetaUtils
493 .getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
495 if (interfaceParentEntry != null) {
496 List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
497 if (interfaceChildEntries != null && interfaceChildEntries.contains(childInterface)) {
498 LOG.trace("Child entry for interface {} already exists", childInterface);
502 if (l2vlanMode == IfL2vlan.L2vlanMode.Trunk && interfaceChildEntries != null) {
503 for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
504 String curChildInterface = interfaceChildEntry.getChildInterface();
505 Interface iface = getInterfaceFromConfigDS(curChildInterface, dataBroker);
506 if (isTrunkInterface(iface)) {
508 "Trying to bind child interface {} of type Trunk to parent interface {},"
509 + "but it is already bound to a trunk interface {}",
510 childInterface, parentInterface, curChildInterface);
517 LOG.info("Creating child interface {} of type {} bound on parent-interface {}",
518 childInterface, l2vlanMode, parentInterface);
519 createInterfaceChildEntry(parentInterface, childInterface, Optional.of(tx));
523 public static boolean isTrunkInterface(Interface iface) {
525 IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
526 return ifL2vlan != null && IfL2vlan.L2vlanMode.Trunk.equals(ifL2vlan.getL2vlanMode());
532 public static boolean deleteParentInterfaceEntry(String parentInterface) {
533 if (parentInterface == null) {
536 InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
537 InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils
538 .getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
539 BatchingUtils.delete(interfaceParentEntryIdentifier, BatchingUtils.EntityType.DEFAULT_CONFIG);
544 * update operational state of interface based on events like tunnel
547 public static void updateOpState(WriteTransaction transaction, String interfaceName,
548 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
549 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
550 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
551 .ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
552 .buildStateInterfaceId(interfaceName);
553 LOG.debug("updating tep interface state as {} for {}", operStatus.name(), interfaceName);
554 InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus);
555 ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
556 transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
559 public static boolean isTunnelInterface(Interface interfaceInfo) {
560 return interfaceInfo != null && interfaceInfo.getAugmentation(IfTunnel.class) != null;
563 public static boolean isVlanInterface(Interface interfaceInfo) {
564 return interfaceInfo != null && interfaceInfo.getAugmentation(IfL2vlan.class) != null;
567 // Cache Util methods
568 public static void addInterfaceToCache(Interface iface) {
569 interfaceConfigMap.put(iface.getName(), iface);
572 public static void removeFromInterfaceCache(Interface iface) {
573 interfaceConfigMap.remove(iface.getName());
576 public static void addInterfaceStateToCache(
577 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
578 .ietf.interfaces.rev140508.interfaces.state.Interface iface) {
579 interfaceStateMap.put(iface.getName(), iface);
582 public static void removeFromInterfaceStateCache(
583 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
584 .ietf.interfaces.rev140508.interfaces.state.Interface iface) {
585 interfaceStateMap.remove(iface.getName());
588 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
589 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus getBfdStateFromCache(String interfaceName) {
590 return bfdStateMap.get(interfaceName);
593 public static void addBfdStateToCache(String interfaceName,
594 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
595 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
596 bfdStateMap.put(interfaceName, operStatus);
599 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
600 .ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus removeBfdStateFromCache(
601 String interfaceName) {
602 return bfdStateMap.remove(interfaceName);
605 public static boolean isNovaOrTunnelPort(String portName) {
606 Matcher matcher = NOVA_OR_TUNNEL_PORT_PATTERN.matcher(portName);
607 return matcher.matches();
610 public static boolean isNovaPort(String portName) {
611 Matcher matcher = NOVA_PORT_PATTERN.matcher(portName);
612 return matcher.matches();
615 public static boolean isTunnelPort(String portName) {
616 Matcher matcher = TUNNEL_PORT_PATTERN.matcher(portName);
617 return matcher.matches();
620 public static void createOrUpdateDpnToInterface(BigInteger dpId, String infName, WriteTransaction transaction) {
621 DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
622 InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
623 InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
624 .child(DpnToInterface.class, dpnToInterfaceKey)
625 .child(InterfaceNameEntry.class, interfaceNameEntryKey)
627 InterfaceNameEntryBuilder entryBuilder =
628 new InterfaceNameEntryBuilder().setKey(interfaceNameEntryKey).setInterfaceName(infName);
629 BatchingUtils.write(intfid, entryBuilder.build(), BatchingUtils.EntityType.DEFAULT_OPERATIONAL);
632 public static void deleteDpnToInterface(DataBroker dataBroker,
633 BigInteger dpId, String infName, WriteTransaction transaction) {
634 DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
635 InstanceIdentifier<DpnToInterface> dpnToInterfaceId = InstanceIdentifier.builder(DpnToInterfaceList.class)
636 .child(DpnToInterface.class, dpnToInterfaceKey).build();
637 Optional<DpnToInterface> dpnToInterfaceOptional =
638 IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId, dataBroker);
639 if (!dpnToInterfaceOptional.isPresent()) {
640 LOG.debug("DPN {} is already removed from the Operational DS", dpId);
644 List<InterfaceNameEntry> interfaceNameEntries = dpnToInterfaceOptional.get().getInterfaceNameEntry();
645 InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
646 InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
647 .child(DpnToInterface.class, dpnToInterfaceKey)
648 .child(InterfaceNameEntry.class, interfaceNameEntryKey)
650 transaction.delete(LogicalDatastoreType.OPERATIONAL, intfid);
652 if (interfaceNameEntries.size() <= 1) {
653 transaction.delete(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId);
657 public static String getPortNameForInterface(NodeConnectorId nodeConnectorId, String portName) {
658 if (isNovaOrTunnelPort(portName)) {
661 return getDpnPrefixedPortName(nodeConnectorId, portName);
665 public static String getPortNameForInterface(String dpnId, String portName) {
666 if (isNovaOrTunnelPort(portName)) {
669 return getDpnPrefixedPortName(dpnId, portName);
673 private static String getDpnPrefixedPortName(NodeConnectorId nodeConnectorId, String portName) {
674 String dpnId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId).toString();
675 return getDpnPrefixedPortName(dpnId, portName);
678 private static String getDpnPrefixedPortName(String dpnId, String portName) {
679 return dpnId + IfmConstants.OF_URI_SEPARATOR + portName;