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