Merge "L2 Gw create changes related to ITM Tunnels creation in neutronvpn module"
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / commons / InterfaceManagerCommonUtils.java
1 /*
2  * Copyright (c) 2015 - 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.vpnservice.interfacemgr.commons;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
19 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
20 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
21 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
22 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
23 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
24 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
25 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
26 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
27 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
28 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
29 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
30 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnelBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeMplsOverGre;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 import com.google.common.base.Optional;
60 import com.google.common.util.concurrent.ListenableFuture;
61
62 public class InterfaceManagerCommonUtils {
63     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
64     public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
65                                                                     DataBroker dataBroker) {
66         NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
67         InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
68                 .child(Node.class, new NodeKey(nodeId))
69                 .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
70
71         Optional<NodeConnector> nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
72                 ncIdentifier, dataBroker);
73         if (!nodeConnectorOptional.isPresent()) {
74             return null;
75         }
76         return nodeConnectorOptional.get();
77     }
78
79     public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
80         InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
81                 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
82         return interfaceInstanceIdentifierBuilder.build();
83     }
84
85     public static List<Interface> getAllTunnelInterfaces(DataBroker dataBroker, InterfaceInfo.InterfaceType interfaceType) {
86         List<Interface> vxlanList = new ArrayList<Interface>();
87         InstanceIdentifier<Interfaces> interfacesInstanceIdentifier =  InstanceIdentifier.builder(Interfaces.class).build();
88         Optional<Interfaces> interfacesOptional  = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfacesInstanceIdentifier, dataBroker);
89         if (!interfacesOptional.isPresent()) {
90             return vxlanList;
91         }
92         Interfaces interfaces = interfacesOptional.get();
93         List<Interface> interfacesList = interfaces.getInterface();
94         for (Interface iface : interfacesList) {
95             if(IfmUtil.getInterfaceType(iface) == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE &&
96                     iface.getAugmentation(IfTunnel.class).isInternal()) {
97                 vxlanList.add(iface);
98             }
99         }
100         return vxlanList;
101     }
102     public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
103         InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
104         Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
105         if (!interfaceOptional.isPresent()) {
106             return null;
107         }
108
109         return interfaceOptional.get();
110     }
111
112     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName, DataBroker dataBroker) {
113         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
114                 IfmUtil.buildStateInterfaceId(interfaceName);
115         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional =
116                 IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
117         if (!ifStateOptional.isPresent()) {
118             return null;
119         }
120
121         return ifStateOptional.get();
122     }
123     public static void makeTunnelIngressFlow(List<ListenableFuture<Void>> futures, IMdsalApiManager mdsalApiManager,
124                                              IfTunnel tunnel, BigInteger dpnId, long portNo, Interface iface, int ifIndex, int addOrRemoveFlow) {
125         LOG.debug("make tunnel ingress flow for {}",iface.getName());
126         String flowRef = InterfaceManagerCommonUtils.getTunnelInterfaceFlowRef(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, iface.getName());
127         List<MatchInfo> matches = new ArrayList<MatchInfo>();
128         List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
129         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
130             matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] {
131                     dpnId, BigInteger.valueOf(portNo) }));
132             mkInstructions.add(new InstructionInfo(
133                     InstructionType.write_metadata, new BigInteger[] {
134                             MetaDataUtil.getLportTagMetaData(ifIndex).or(BigInteger.ONE),
135                             MetaDataUtil.METADATA_MASK_LPORT_TAG_SH_FLAG}));
136             short tableId = tunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeMplsOverGre.class) ? NwConstants.L3_LFIB_TABLE :
137                     tunnel.isInternal() ? NwConstants.INTERNAL_TUNNEL_TABLE : NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL;
138             mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] {tableId}));
139         }
140
141         BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
142         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, flowRef,
143                 IfmConstants.DEFAULT_FLOW_PRIORITY, iface.getName(), 0, 0, COOKIE_VM_INGRESS_TABLE, matches, mkInstructions);
144         if (NwConstants.ADD_FLOW == addOrRemoveFlow) {
145             futures.add(mdsalApiManager.installFlow(dpnId, flowEntity));
146         } else {
147             futures.add(mdsalApiManager.removeFlow(dpnId, flowEntity));
148         }
149     }
150     public static String getTunnelInterfaceFlowRef(BigInteger dpnId, short tableId, String ifName) {
151         return new StringBuilder().append(dpnId).append(tableId).append(ifName).toString();
152     }
153
154     public static void setOpStateForInterface(DataBroker broker, String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus opStatus) {
155         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = IfmUtil.buildStateInterfaceId(interfaceName);
156         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setKey(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
157         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceData = ifaceBuilder.setOperStatus(opStatus).build();
158         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
159     }
160
161     public static void updateTunnelMonitorDetailsInConfigDS(DataBroker broker, String interfaceName, boolean monitorEnabled, long monitorInterval) {
162         InstanceIdentifier<Interface> id = IfmUtil.buildId(interfaceName);
163         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder ifaceBuilder = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder();
164         ifaceBuilder.setKey(new InterfaceKey(interfaceName));
165         IfTunnelBuilder ifTunnelBuilder = new IfTunnelBuilder();
166         ifTunnelBuilder.setMonitorEnabled(monitorEnabled);
167         ifTunnelBuilder.setMonitorInterval(monitorInterval);
168         ifaceBuilder.addAugmentation(IfTunnel.class, ifTunnelBuilder.build());
169
170         LOG.trace("Updating trunk interface {} in Config DS", interfaceName);
171         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, id, ifaceBuilder.build());
172     }
173
174     public static void createInterfaceChildEntry( WriteTransaction t,
175                                                   String parentInterface, String childInterface){
176         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
177         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
178         InstanceIdentifier<InterfaceChildEntry> intfId =
179                 InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
180         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
181                 .setChildInterface(childInterface);
182         t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(),true);
183     }
184
185     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus
186            updateStateEntry(Interface interfaceNew, DataBroker dataBroker, WriteTransaction transaction,
187                           org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
188         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus;
189         if (!interfaceNew.isEnabled()) {
190             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
191         } else {
192             String ncStr = ifState.getLowerLayerIf().get(0);
193             NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
194             NodeConnector nodeConnector =
195                     InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
196             FlowCapableNodeConnector flowCapableNodeConnector =
197                     nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
198             //State state = flowCapableNodeConnector.getState();
199             operStatus = flowCapableNodeConnector == null ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down : org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up;
200         }
201
202         String ifName = interfaceNew.getName();
203         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
204                 IfmUtil.buildStateInterfaceId(interfaceNew.getName());
205         InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
206         ifaceBuilder.setOperStatus(operStatus);
207         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
208         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
209         return operStatus;
210     }
211
212     public static void updateOperStatus(String interfaceName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
213                                         WriteTransaction transaction) {
214         LOG.debug("updating operational status for interface {}",interfaceName);
215         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
216                 IfmUtil.buildStateInterfaceId(interfaceName);
217         InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
218         ifaceBuilderChild.setOperStatus(operStatus);
219         ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
220         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilderChild.build());
221     }
222
223     public static void addStateEntry(String interfaceName, WriteTransaction transaction, DataBroker dataBroker, IdManagerService idManager,
224                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
225         LOG.debug("adding interface state for {}",interfaceName);
226         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus = ifState.getOperStatus();
227         PhysAddress physAddress = ifState.getPhysAddress();
228         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus = ifState.getAdminStatus();
229         NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
230         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
231         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface interfaceInfo =
232                 InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
233
234         if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
235             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
236         }
237
238         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
239                 IfmUtil.buildStateInterfaceId(interfaceName);
240         List<String> childLowerLayerIfList = new ArrayList<>();
241         childLowerLayerIfList.add(0, nodeConnectorId.getValue());
242         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus)
243                 .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
244
245         Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, interfaceName);
246         ifaceBuilder.setIfIndex(ifIndex);
247
248         if(interfaceInfo != null){
249             ifaceBuilder.setType(interfaceInfo.getType());
250         }
251         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
252         transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
253
254         // create lportTag Interface Map
255         InterfaceMetaUtils.createLportTagInterfaceMap(transaction, interfaceName, ifIndex);
256
257         // install ingress flow
258         BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
259         long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
260         if(interfaceInfo.isEnabled() && ifState.getOperStatus() == org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up) {
261             List<MatchInfo> matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, interfaceInfo);
262             FlowBasedServicesUtils.installVlanFlow(dpId, portNo, interfaceInfo, transaction, matches, ifIndex);
263         }
264     }
265
266     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
267                   addStateEntry(Interface interfaceInfo, String portName, WriteTransaction transaction, IdManagerService idManager,
268                                      PhysAddress physAddress, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus,
269                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus adminStatus,
270                                      NodeConnectorId nodeConnectorId) {
271         LOG.debug("adding interface state for {}",portName);
272         if (interfaceInfo != null && !interfaceInfo.isEnabled()) {
273             operStatus = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
274         }
275         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
276                 IfmUtil.buildStateInterfaceId(portName);
277         List<String> childLowerLayerIfList = new ArrayList<>();
278         childLowerLayerIfList.add(0, nodeConnectorId.getValue());
279         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus)
280                 .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
281
282         Integer ifIndex = IfmUtil.allocateId(idManager, IfmConstants.IFM_IDPOOL_NAME, portName);
283         ifaceBuilder.setIfIndex(ifIndex);
284
285         if(interfaceInfo != null){
286             ifaceBuilder.setType(interfaceInfo.getType());
287         }
288         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
289         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = ifaceBuilder.build();
290         transaction.put(LogicalDatastoreType.OPERATIONAL, ifStateId,ifState , true);
291
292         // allocate lport tag and set in if-index
293         InterfaceMetaUtils.createLportTagInterfaceMap(transaction, portName, ifIndex);
294         return ifState;
295     }
296
297     public static void deleteStateEntry(String interfaceName, WriteTransaction transaction) {
298         LOG.debug("removing interface state for {}",interfaceName);
299         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
300                 IfmUtil.buildStateInterfaceId(interfaceName);
301         transaction.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
302     }
303
304     // For trunk interfaces, binding to a parent interface which is already bound to another trunk interface should not
305     // be allowed
306     public static boolean createInterfaceChildEntryIfNotPresent( DataBroker dataBroker, WriteTransaction t,
307                                                String parentInterface, String childInterface){
308         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
309         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier =
310                 InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
311         InterfaceParentEntry interfaceParentEntry =
312                 InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
313
314         if(interfaceParentEntry != null){
315             LOG.error("Trying to bind the same parent interface {} to multiple trunk interfaces. ", parentInterface);
316             return false;
317         }
318
319         LOG.info("First vlan trunk {} bound on parent-interface {}", childInterface, parentInterface);
320         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
321         InstanceIdentifier<InterfaceChildEntry> intfId =
322                 InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
323         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
324                 .setChildInterface(childInterface);
325         t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(),true);
326         return true;
327     }
328
329     public static boolean deleteParentInterfaceEntry( WriteTransaction t, String parentInterface){
330         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
331         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier = InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
332         t.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier);
333         return true;
334     }
335
336     public static void deleteInterfaceChildEntry(WriteTransaction transaction, DataBroker dataBroker, String parentInterface, String childInterface){
337         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
338         InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIid =
339                 InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
340         InterfaceParentEntry interfaceParentEntry =
341                 InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIid, dataBroker);
342
343         if(interfaceParentEntry == null){
344             return;
345         }
346
347         List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
348         if (interfaceChildEntries.size() <= 1) {
349             transaction.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIid);
350         } else {
351             InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
352             InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryIid =
353                     InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
354             transaction.delete(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryIid);
355         }
356     }
357
358     /*
359      * update operational state of interface based on events like tunnel monitoring
360      */
361     public static void updateOpState(WriteTransaction transaction, String interfaceName,
362                                      org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus operStatus){
363         LOG.debug("updating tep interface state for {}", interfaceName);
364         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
365                 IfmUtil.buildStateInterfaceId(interfaceName);
366         InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus);
367         ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceName));
368         transaction.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
369     }
370
371 }