ELAN FT Support for BE
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / IfmUtil.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 package org.opendaylight.vpnservice.interfacemgr;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.Future;
15
16 import com.google.common.base.Optional;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
22 import org.opendaylight.vpnservice.interfacemgr.globals.VlanInterfaceInfo;
23 import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeBase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeGre;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdPools;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan.L2vlanMode;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
51 import org.opendaylight.yangtools.yang.binding.DataObject;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
54 import org.opendaylight.yangtools.yang.common.RpcResult;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 public class IfmUtil {
59     private static final Logger LOG = LoggerFactory.getLogger(IfmUtil.class);
60     private static final int INVALID_ID = 0;
61     public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
62         /*
63          * NodeConnectorId is of form 'openflow:dpnid:portnum'
64          */
65         String[] split = portId.getValue().split(IfmConstants.OF_URI_SEPARATOR);
66         return split[1];
67     }
68
69     public static String getPortNoFromNodeConnectorId(NodeConnectorId portId) {
70         /*
71          * NodeConnectorId is of form 'openflow:dpnid:portnum'
72          */
73         String[] split = portId.getValue().split(IfmConstants.OF_URI_SEPARATOR);
74         return split[2];
75     }
76
77     public static NodeId buildDpnNodeId(BigInteger dpnId) {
78         return new NodeId(IfmConstants.OF_URI_PREFIX + dpnId);
79     }
80
81     public static InstanceIdentifier<Interface> buildId(String interfaceName) {
82         //TODO Make this generic and move to AbstractDataChangeListener or Utils.
83         InstanceIdentifierBuilder<Interface> idBuilder =
84                 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
85         InstanceIdentifier<Interface> id = idBuilder.build();
86         return id;
87     }
88
89     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
90         InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
91                 InstanceIdentifier.builder(InterfacesState.class)
92                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
93                         new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
94         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
95         return id;
96     }
97
98     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
99                     String name) {
100         return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
101     }
102
103     public static InstanceIdentifier<IdPool> getPoolId(String poolName){
104         InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
105                         InstanceIdentifier.builder(IdPools.class).child(IdPool.class, new IdPoolKey(poolName));
106         InstanceIdentifier<IdPool> id = idBuilder.build();
107         return id;
108     }
109
110     public static List<String> getPortNameAndSuffixFromInterfaceName(String intfName) {
111         List<String> strList = new ArrayList<>(2);
112         int index = intfName.indexOf(":");
113         if (index != -1) {
114             strList.add(0, intfName.substring(0, index));
115             strList.add(1, intfName.substring(index));
116         }
117         return strList;
118     }
119
120     public static long getGroupId(long ifIndex, InterfaceInfo.InterfaceType infType) {
121         if (infType == InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE) {
122             return ifIndex + IfmConstants.LOGICAL_GROUP_START;
123         }
124         else if (infType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
125             return ifIndex + IfmConstants.VLAN_GROUP_START;
126         } else {
127             return ifIndex + IfmConstants.TRUNK_GROUP_START;
128         }
129     }
130
131     public static List<String> getDpIdPortNameAndSuffixFromInterfaceName(String intfName) {
132         List<String> strList = new ArrayList<>(3);
133         int index1 = intfName.indexOf(":");
134         if (index1 != -1) {
135             int index2 = intfName.indexOf(":", index1 + 1 );
136             strList.add(0, intfName.substring(0, index1));
137             if (index2 != -1) {
138                 strList.add(1, intfName.substring(index1, index2));
139                 strList.add(2, intfName.substring(index2));
140             } else {
141                 strList.add(1, intfName.substring(index1));
142                 strList.add(2, "");
143             }
144         }
145         return strList;
146     }
147
148     public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
149                                                           InstanceIdentifier<T> path, DataBroker broker) {
150
151         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
152
153         Optional<T> result = Optional.absent();
154         try {
155             result = tx.read(datastoreType, path).get();
156         } catch (Exception e) {
157             throw new RuntimeException(e);
158         }
159
160         return result;
161     }
162
163     public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
164         return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
165     }
166
167     public static BigInteger[] mergeOpenflowMetadataWriteInstructions(List<Instruction> instructions) {
168         BigInteger metadata = new BigInteger("0", 16);
169         BigInteger metadataMask = new BigInteger("0", 16);
170         if (instructions != null && !instructions.isEmpty()) {
171             // check if metadata write instruction is present
172             for (Instruction instruction : instructions) {
173                 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction actualInstruction = instruction.getInstruction();
174                 if (actualInstruction instanceof WriteMetadataCase) {
175                     WriteMetadataCase writeMetaDataInstruction = (WriteMetadataCase) actualInstruction ;
176                     WriteMetadata availableMetaData = writeMetaDataInstruction.getWriteMetadata();
177                     metadata = metadata.or(availableMetaData.getMetadata());
178                     metadataMask = metadataMask.or(availableMetaData.getMetadataMask());
179                 }
180             }
181         }
182         return new BigInteger[] { metadata, metadataMask };
183     }
184
185     public static Integer allocateId(IdManagerService idManager, String poolName, String idKey) {
186         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
187                 .setPoolName(poolName)
188                 .setIdKey(idKey).build();
189         try {
190             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
191             RpcResult<AllocateIdOutput> rpcResult = result.get();
192             if(rpcResult.isSuccessful()) {
193                 return rpcResult.getResult().getIdValue().intValue();
194             } else {
195                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
196             }
197         } catch (InterruptedException | ExecutionException e) {
198             LOG.warn("Exception when getting Unique Id",e);
199         }
200         return INVALID_ID;
201     }
202
203     public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
204         ReleaseIdInput idInput = new ReleaseIdInputBuilder()
205                 .setPoolName(poolName)
206                 .setIdKey(idKey).build();
207         try {
208             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
209             RpcResult<Void> rpcResult = result.get();
210             if(!rpcResult.isSuccessful()) {
211                 LOG.warn("RPC Call to release Id {} with Key {} returned with Errors {}",
212                         idKey, rpcResult.getErrors());
213             }
214         } catch (InterruptedException | ExecutionException e) {
215             LOG.warn("Exception when releasing Id for key {}", idKey, e);
216         }
217     }
218
219     public static BigInteger getDpnId(DatapathId datapathId){
220         if (datapathId != null) {
221             String dpIdStr = datapathId.getValue().replace(":", "");
222             return new BigInteger(dpIdStr, 16);
223         }
224         return null;
225     }
226
227     public static NodeConnectorId getNodeConnectorIdFromInterface(Interface iface, DataBroker dataBroker) {
228         return FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
229     }
230
231     public static InterfaceInfo.InterfaceType getInterfaceType(Interface iface) {
232         InterfaceInfo.InterfaceType interfaceType =
233                 org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE;
234         Class<? extends org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType> ifType = iface.getType();
235
236         if (ifType.isAssignableFrom(L2vlan.class)) {
237             interfaceType =  org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType.VLAN_INTERFACE;
238         } else if (ifType.isAssignableFrom(Tunnel.class)) {
239             IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
240             Class<? extends  org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase> tunnelType = ifTunnel.getTunnelInterfaceType();
241             if (tunnelType.isAssignableFrom(TunnelTypeVxlan.class)) {
242                 interfaceType = InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE;
243             } else if (tunnelType.isAssignableFrom(TunnelTypeGre.class)) {
244                 interfaceType = InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE;
245             }
246         }
247         // TODO: Check if the below condition is still needed/valid
248         //else if (ifType.isAssignableFrom(InterfaceGroup.class)) {
249         //    interfaceType =  org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE;
250         //}
251         return interfaceType;
252     }
253
254     public static VlanInterfaceInfo getVlanInterfaceInfo(String interfaceName, Interface iface, BigInteger dpId){
255         IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
256
257         short vlanId = 0;
258         //FIXME :Use this below thing properly
259         VlanInterfaceInfo vlanInterfaceInfo = new VlanInterfaceInfo(dpId, "someString", vlanId);
260
261         if (vlanIface != null) {
262             vlanId = vlanIface.getVlanId() == null ? 0 : vlanIface.getVlanId().getValue().shortValue();
263             L2vlanMode l2VlanMode = vlanIface.getL2vlanMode();
264
265             if (l2VlanMode == L2vlanMode.Transparent) {
266                 vlanInterfaceInfo.setVlanTransparent(true);
267             }
268             if (l2VlanMode == L2vlanMode.NativeUntagged) {
269                 vlanInterfaceInfo.setUntaggedVlan(true);
270             }
271             vlanInterfaceInfo.setVlanId(vlanId);
272
273         }
274         return vlanInterfaceInfo;
275     }
276
277
278
279 }