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