75fdc04d0dfe2f85f577d9600db2d433ad5a04b4
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / commons / InterfaceManagerCommonUtils.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.genius.interfacemanager.commons;
10
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.LinkedList;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Objects;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
22
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.genius.interfacemanager.IfmConstants;
27 import org.opendaylight.genius.interfacemanager.IfmUtil;
28 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
29 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
30 import org.opendaylight.genius.mdsalutil.FlowEntity;
31 import org.opendaylight.genius.mdsalutil.InstructionInfo;
32 import org.opendaylight.genius.mdsalutil.InstructionType;
33 import org.opendaylight.genius.mdsalutil.MDSALUtil;
34 import org.opendaylight.genius.mdsalutil.MatchFieldType;
35 import org.opendaylight.genius.mdsalutil.MatchInfo;
36 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
37 import org.opendaylight.genius.mdsalutil.NwConstants;
38 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntryKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterface;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntryKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72 public class InterfaceManagerCommonUtils {
73     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
74     private static ConcurrentHashMap<String, Interface> interfaceConfigMap = new ConcurrentHashMap<>();
75     private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceStateMap = new ConcurrentHashMap<>();
76     private static ConcurrentHashMap<String, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus> bfdStateMap =
77             new ConcurrentHashMap<>();
78
79     private static final String NOVA_OR_TUNNEL_PORT_REGEX = "(tap|vhu)[0-9a-f]{8}-[0-9a-f]{2}|tun[0-9a-f]{11}";
80     private static final Pattern pattern = Pattern.compile(NOVA_OR_TUNNEL_PORT_REGEX);
81
82     public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
83             DataBroker dataBroker) {
84         NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
85         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
86                 .child(Node.class, new NodeKey(nodeId))
87                 .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
88
89         Optional<NodeConnector> nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ncIdentifier,
90                 dataBroker);
91         if (!nodeConnectorOptional.isPresent()) {
92             return null;
93         }
94         return nodeConnectorOptional.get();
95     }
96
97     public static boolean isNodePresent(DataBroker dataBroker, NodeConnectorId nodeConnectorId) {
98         NodeId nodeID = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
99         InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifier.builder(Nodes.class)
100                 .child(Node.class, new NodeKey(nodeID)).build();
101         Optional<Node> node = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceIdentifier, dataBroker);
102
103         if (node.isPresent()) {
104             return true;
105         }
106         return false;
107     }
108
109     public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
110         InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder = InstanceIdentifier
111                 .builder(Interfaces.class).child(Interface.class, interfaceKey);
112         return interfaceInstanceIdentifierBuilder.build();
113     }
114
115     public static List<Interface> getAllTunnelInterfaces(DataBroker dataBroker,
116             InterfaceInfo.InterfaceType interfaceType) {
117         List<Interface> vxlanList = new ArrayList<>();
118         InstanceIdentifier<Interfaces> interfacesInstanceIdentifier = InstanceIdentifier.builder(Interfaces.class)
119                 .build();
120         Optional<Interfaces> interfacesOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION,
121                 interfacesInstanceIdentifier, dataBroker);
122         if (!interfacesOptional.isPresent()) {
123             return vxlanList;
124         }
125         Interfaces interfaces = interfacesOptional.get();
126         List<Interface> interfacesList = interfaces.getInterface();
127         for (Interface iface : interfacesList) {
128             if (IfmUtil.getInterfaceType(iface) == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE
129                     && iface.getAugmentation(IfTunnel.class).isInternal()) {
130                 vxlanList.add(iface);
131             }
132         }
133         return vxlanList;
134     }
135
136     /**
137      * Searches for an interface by its name
138      * @param interfaceName name of the interface to search for
139      * @param dataBroker data tree store to start searching for the interface
140      * @return the Interface object
141      *
142      */
143     public static Interface getInterfaceFromConfigDS (String interfaceName, DataBroker dataBroker) {
144         Interface iface = interfaceConfigMap.get(interfaceName);
145         if (iface != null) {
146             return iface;
147         }
148         InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(new InterfaceKey(interfaceName));
149         Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId,
150                 dataBroker);
151         if (interfaceOptional.isPresent()) {
152             iface = interfaceOptional.get();
153             interfaceConfigMap.put(iface.getName(), iface);
154         }
155         return iface;
156     }
157
158     @Deprecated
159     public static Interface getInterfaceFromConfigDS (InterfaceKey interfaceKey, DataBroker dataBroker) {
160         return getInterfaceFromConfigDS(interfaceKey.getName(), dataBroker);
161     }
162
163     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
164             String interfaceName, DataBroker dataBroker) {
165         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceStateMap
166                 .get(interfaceName);
167         if (ifState != null) {
168             return ifState;
169         }
170         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = IfmUtil
171                 .read(LogicalDatastoreType.OPERATIONAL, IfmUtil.buildStateInterfaceId(interfaceName), dataBroker);
172         if (ifStateOptional.isPresent()) {
173             ifState = ifStateOptional.get();
174             interfaceStateMap.put(ifState.getName(), ifState);
175         }
176         return ifState;
177     }
178
179     @Deprecated
180     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
181             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId,
182             DataBroker dataBroker) {
183         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = IfmUtil
184                 .read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
185         if (!ifStateOptional.isPresent()) {
186             return null;
187         }
188
189         return ifStateOptional.get();
190     }
191
192     public static void makeTunnelIngressFlow(List<ListenableFuture<Void>> futures, IMdsalApiManager mdsalApiManager,
193             IfTunnel tunnel, BigInteger dpnId, long portNo, String interfaceName, int ifIndex, int addOrRemoveFlow) {
194         LOG.debug("make tunnel ingress flow for {}", interfaceName);
195         String flowRef = InterfaceManagerCommonUtils.getTunnelInterfaceFlowRef(dpnId,
196                 NwConstants.VLAN_INTERFACE_INGRESS_TABLE, interfaceName);
197         List<MatchInfo> matches = new ArrayList<>();
198         List<InstructionInfo> mkInstructions = new ArrayList<>();
199         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
200             matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] { dpnId, BigInteger.valueOf(portNo) }));
201             mkInstructions.add(new InstructionInfo(InstructionType.write_metadata,
202                     new BigInteger[] { MetaDataUtil.getLportTagMetaData(ifIndex).or(BigInteger.ONE),
203                             MetaDataUtil.METADATA_MASK_LPORT_TAG_SH_FLAG }));
204             short tableId = (tunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class))
205                     ? NwConstants.L3_LFIB_TABLE
206                     : tunnel.isInternal() ? NwConstants.INTERNAL_TUNNEL_TABLE : NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL;
207             mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { tableId }));
208         }
209
210         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, flowRef,
211                 IfmConstants.DEFAULT_FLOW_PRIORITY, interfaceName, 0, 0, NwConstants.COOKIE_VM_INGRESS_TABLE, matches,
212                 mkInstructions);
213         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
214             futures.add(mdsalApiManager.installFlow(dpnId, flowEntity));
215         } else {
216             futures.add(mdsalApiManager.removeFlow(dpnId, flowEntity));
217         }
218     }
219
220     public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
221         return new StringBuilder().append(dpnId).append(tableId).append(ifName).toString();
222     }
223
224     public static void setOpStateForInterface(DataBroker broker, String interfaceName,
225             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opStatus) {
226         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = IfmUtil
227                 .buildStateInterfaceId(interfaceName);
228         InterfaceBuilder ifaceBuilder = new InterfaceBuilder()
229                 .setKey(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
230                         interfaceName));
231         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceData = ifaceBuilder
232                 .setOperStatus(opStatus).build();
233         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
234     }
235
236     public static void createInterfaceChildEntry(WriteTransaction t, String parentInterface, String childInterface) {
237         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
238         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
239         InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
240                 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
241         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
242                 .setChildInterface(childInterface);
243         t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(), true);
244     }
245
246     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus updateStateEntry(
247             Interface interfaceNew, DataBroker dataBroker, WriteTransaction transaction,
248             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
249         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus;
250         if (!interfaceNew.isEnabled()) {
251             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
252         } else {
253             String ncStr = ifState.getLowerLayerIf().get(0);
254             NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
255             NodeConnector nodeConnector = InterfaceManagerCommonUtils
256                     .getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
257             FlowCapableNodeConnector flowCapableNodeConnector = nodeConnector
258                     .getAugmentation(FlowCapableNodeConnector.class);
259             // State state = flowCapableNodeConnector.getState();
260             operStatus = flowCapableNodeConnector == null
261                     ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down
262                     : org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up;
263         }
264
265         String ifName = interfaceNew.getName();
266         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
267                 .buildStateInterfaceId(interfaceNew.getName());
268         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
269         ifaceBuilder.setOperStatus(operStatus);
270         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
271         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
272         return operStatus;
273     }
274
275     public static void updateOperStatus(String interfaceName,
276             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
277             WriteTransaction transaction) {
278         LOG.debug("updating operational status for interface {}", interfaceName);
279         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId = IfmUtil
280                 .buildStateInterfaceId(interfaceName);
281         InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
282         ifaceBuilderChild.setOperStatus(operStatus);
283         ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
284         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilderChild.build());
285     }
286
287     public static void addStateEntry(String interfaceName, DataBroker dataBroker,
288                                      IdManagerService idManager, List<ListenableFuture<Void>> futures,
289                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
290         WriteTransaction interfaceOperShardTransaction = dataBroker.newWriteOnlyTransaction();
291         addStateEntry(interfaceName, dataBroker, interfaceOperShardTransaction, idManager, futures, ifState);
292         futures.add(interfaceOperShardTransaction.submit());
293     }
294
295     public static void addStateEntry(String interfaceName, DataBroker dataBroker, WriteTransaction interfaceOperShardTransaction,
296                                      IdManagerService idManager, List<ListenableFuture<Void>> futures,
297                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
298         // allocate lport tag and create interface-if-index map.
299         // This is done even if interface-state is not present, so that there is
300         // no throttling
301         // on id allocation even when multiple southbound port_up events come in
302         // one shot
303         Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
304         InterfaceMetaUtils.createLportTagInterfaceMap(interfaceOperShardTransaction, interfaceName, ifIndex);
305         if (ifState == null) {
306             LOG.debug("could not retrieve interface state corresponding to {}", interfaceName);
307             return;
308         }
309         LOG.debug("adding interface state for {}", interfaceName);
310         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus = ifState
311                 .getOperStatus();
312         PhysAddress physAddress = ifState.getPhysAddress();
313         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus = ifState
314                 .getAdminStatus();
315         NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
316         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
317         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface interfaceInfo = InterfaceManagerCommonUtils
318                 .getInterfaceFromConfigDS(interfaceKey, dataBroker);
319
320         if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
321             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
322         }
323
324         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
325                 .buildStateInterfaceId(interfaceName);
326         List<String> childLowerLayerIfList = new ArrayList<>();
327         childLowerLayerIfList.add(0, nodeConnectorId.getValue());
328         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
329                 .setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
330         ifaceBuilder.setIfIndex(ifIndex);
331
332         if (interfaceInfo != null) {
333             ifaceBuilder.setType(interfaceInfo.getType());
334         }
335         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
336         interfaceOperShardTransaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
337
338         // install ingress flow
339         BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
340         long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
341         if (interfaceInfo != null && interfaceInfo.isEnabled() && ifState
342                 .getOperStatus() == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up) {
343             FlowBasedServicesUtils.installLportIngressFlow(dpId, portNo, interfaceInfo, futures, dataBroker, ifIndex);
344             FlowBasedServicesUtils.bindDefaultEgressDispatcherService(dataBroker, futures, interfaceInfo, Long.toString(portNo), interfaceName, ifIndex);
345         }
346
347         // Update the DpnToInterfaceList OpDS
348         createOrUpdateDpnToInterface(dpId, interfaceName,interfaceOperShardTransaction);
349     }
350
351     public static boolean checkIfBfdStateIsDown(String interfaceName){
352         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus =
353                 InterfaceManagerCommonUtils.getBfdStateFromCache(interfaceName);
354         return (operStatus == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
355     }
356
357     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface addStateEntry(
358             DataBroker dataBroker, Interface interfaceInfo, String interfaceName, WriteTransaction transaction, IdManagerService idManager,
359             PhysAddress physAddress,
360             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
361             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus,
362             NodeConnectorId nodeConnectorId) {
363         LOG.debug("adding interface state for {}", interfaceName);
364         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
365         Integer ifIndex = null;
366         if (interfaceInfo != null) {
367             if(!interfaceInfo.isEnabled() || (InterfaceManagerCommonUtils.isTunnelInterface(interfaceInfo) &&
368                     checkIfBfdStateIsDown(interfaceInfo.getName()))){
369                 operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
370             }
371
372             ifaceBuilder.setType(interfaceInfo.getType());
373             // retrieve if-index only for northbound configured interfaces
374             ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
375             ifaceBuilder.setIfIndex(ifIndex);
376             InterfaceMetaUtils.createLportTagInterfaceMap(transaction, interfaceName, ifIndex);
377         }
378         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
379                 .buildStateInterfaceId(interfaceName);
380         List<String> childLowerLayerIfList = new ArrayList<>();
381         childLowerLayerIfList.add(0, nodeConnectorId.getValue());
382         ifaceBuilder.setAdminStatus(adminStatus).setOperStatus(operStatus).setPhysAddress(physAddress)
383                 .setLowerLayerIf(childLowerLayerIfList);
384         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
385         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifaceBuilder
386                 .build();
387         transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifState, true);
388
389         BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
390         // Update the DpnToInterfaceList OpDS
391         createOrUpdateDpnToInterface(dpId, interfaceName, transaction);
392         return ifState;
393     }
394
395     public static void deleteStateEntry(String interfaceName, WriteTransaction transaction) {
396         LOG.debug("removing interface state entry for {}", interfaceName);
397         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId = IfmUtil
398                 .buildStateInterfaceId(interfaceName);
399         transaction.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
400     }
401
402     public static void deleteInterfaceStateInformation(String interfaceName, WriteTransaction transaction,
403             IdManagerService idManagerService) {
404         LOG.debug("removing interface state information for {}", interfaceName);
405         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
406                 .buildStateInterfaceId(interfaceName);
407         transaction.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
408         InterfaceMetaUtils.removeLportTagInterfaceMap(idManagerService, transaction, interfaceName);
409     }
410
411     // For trunk interfaces, binding to a parent interface which is already
412     // bound to another trunk interface should not
413     // be allowed
414     public static boolean createInterfaceChildEntryIfNotPresent(DataBroker dataBroker, WriteTransaction t,
415             String parentInterface, String childInterface) {
416         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
417         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils
418                 .getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
419         InterfaceParentEntry interfaceParentEntry = InterfaceMetaUtils
420                 .getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
421
422         if (interfaceParentEntry != null) {
423             if (!Objects.equals(parentInterface, interfaceParentEntry.getParentInterface())) {
424                 LOG.error("Trying to bind the same parent interface {} to multiple trunk interfaces. ", parentInterface);
425             } else {
426                 LOG.trace("Child entry for interface {} already exists", childInterface);
427             }
428             return false;
429         }
430
431         LOG.info("First vlan trunk {} bound on parent-interface {}", childInterface, parentInterface);
432         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
433         InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
434                 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
435         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
436                 .setChildInterface(childInterface);
437         t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(), true);
438         return true;
439     }
440
441     public static boolean deleteParentInterfaceEntry(WriteTransaction t, String parentInterface) {
442         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
443         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils
444                 .getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
445         t.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier);
446         return true;
447     }
448
449     /*
450      * update operational state of interface based on events like tunnel
451      * monitoring
452      */
453     public static void updateOpState(WriteTransaction transaction, String interfaceName,
454             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
455         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = IfmUtil
456                 .buildStateInterfaceId(interfaceName);
457         LOG.debug("updating tep interface state as {} for {}", operStatus.name(), interfaceName);
458         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus);
459         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
460         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), false);
461     }
462
463     public static boolean isTunnelInterface(Interface interfaceInfo) {
464         if (interfaceInfo != null && interfaceInfo.getAugmentation(IfTunnel.class) != null) {
465             return true;
466         }
467         return false;
468     }
469
470     public static boolean isVlanInterface(Interface interfaceInfo) {
471         if (interfaceInfo != null && interfaceInfo.getAugmentation(IfL2vlan.class) != null) {
472             return true;
473         }
474         return false;
475     }
476
477     // Cache Util methods
478     public static void addInterfaceToCache(Interface iface) {
479         interfaceConfigMap.put(iface.getName(), iface);
480     }
481
482     public static void removeFromInterfaceCache(Interface iface) {
483         interfaceConfigMap.remove(iface.getName());
484     }
485
486     public static void addInterfaceStateToCache(
487             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface) {
488         interfaceStateMap.put(iface.getName(), iface);
489     }
490
491     public static void removeFromInterfaceStateCache(
492             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface) {
493         interfaceStateMap.remove(iface.getName());
494     }
495
496     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus getBfdStateFromCache(String interfaceName) {
497         return bfdStateMap.get(interfaceName);
498     }
499
500     public static void addBfdStateToCache(String interfaceName,
501                                           org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus) {
502         bfdStateMap.put(interfaceName, operStatus);
503     }
504
505     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus removeBfdStateFromCache(String interfaceName){
506         return bfdStateMap.remove(interfaceName);
507     }
508
509     public static boolean isNovaOrTunnelPort(String portName) {
510
511         Matcher matcher = pattern.matcher(portName);
512         return matcher.matches();
513     }
514
515
516     public static void createOrUpdateDpnToInterface(BigInteger dpId, String infName, WriteTransaction transaction) {
517         DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
518         InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
519         InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
520                                                         .child(DpnToInterface.class, dpnToInterfaceKey)
521                                                         .child(InterfaceNameEntry.class, interfaceNameEntryKey)
522                                                         .build();
523         InterfaceNameEntryBuilder entryBuilder = new InterfaceNameEntryBuilder().setKey(interfaceNameEntryKey).setInterfaceName(infName);
524         transaction.put(LogicalDatastoreType.OPERATIONAL, intfid, entryBuilder.build(), true);
525     }
526
527     public static void deleteDpnToInterface(DataBroker dataBroker, BigInteger dpId, String infName, WriteTransaction transaction) {
528         DpnToInterfaceKey dpnToInterfaceKey = new DpnToInterfaceKey(dpId);
529         InstanceIdentifier<DpnToInterface> dpnToInterfaceId = InstanceIdentifier.builder(DpnToInterfaceList.class)
530                 .child(DpnToInterface.class, dpnToInterfaceKey).build();
531         Optional<DpnToInterface> dpnToInterfaceOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId, dataBroker);
532         if (!dpnToInterfaceOptional.isPresent()) {
533             LOG.debug("DPN {} is already removed from the Operational DS", dpId);
534             return;
535         }
536
537         List<InterfaceNameEntry> interfaceNameEntries = dpnToInterfaceOptional.get().getInterfaceNameEntry();
538         InterfaceNameEntryKey interfaceNameEntryKey = new InterfaceNameEntryKey(infName);
539         InstanceIdentifier<InterfaceNameEntry> intfid = InstanceIdentifier.builder(DpnToInterfaceList.class)
540                 .child(DpnToInterface.class, dpnToInterfaceKey)
541                 .child(InterfaceNameEntry.class, interfaceNameEntryKey)
542                 .build();
543         transaction.delete(LogicalDatastoreType.OPERATIONAL, intfid);
544
545         if (interfaceNameEntries.size() <=1) {
546             transaction.delete(LogicalDatastoreType.OPERATIONAL, dpnToInterfaceId);
547         }
548     }
549
550 }