Working with OVS
[vpnservice.git] / interfacemgr / interfacemgr-impl / src / main / java / org / opendaylight / vpnservice / interfacemgr / rpcservice / InterfaceManagerRpcService.java
1 /*
2  * Copyright (c) 2015 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.rpcservice;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.Futures;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
16 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
17 import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
18 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
19 import org.opendaylight.vpnservice.mdsalutil.ActionType;
20 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
21 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.opendaylight.yangtools.yang.common.RpcResult;
49 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 import java.math.BigInteger;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.List;
57 import java.util.concurrent.Future;
58
59 public class InterfaceManagerRpcService implements OdlInterfaceRpcService {
60     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerRpcService.class);
61     DataBroker dataBroker;
62     public InterfaceManagerRpcService(DataBroker dataBroker) {
63         this.dataBroker = dataBroker;
64     }
65
66     @Override
67     public Future<RpcResult<GetDpidFromInterfaceOutput>> getDpidFromInterface(GetDpidFromInterfaceInput input) {
68         String interfaceName = input.getIntfName();
69         RpcResultBuilder<GetDpidFromInterfaceOutput> rpcResultBuilder;
70         try {
71             BigInteger dpId = null;
72             InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
73             Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
74             if (Tunnel.class.equals(interfaceInfo.getType())) {
75                 ParentRefs parentRefs = interfaceInfo.getAugmentation(ParentRefs.class);
76                 dpId = parentRefs.getDatapathNodeIdentifier();
77             } else {
78                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
79                         InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
80                 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
81                 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
82                 dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
83             }
84             GetDpidFromInterfaceOutputBuilder output = new GetDpidFromInterfaceOutputBuilder().setDpid(
85                     (dpId));
86             rpcResultBuilder = RpcResultBuilder.success();
87             rpcResultBuilder.withResult(output.build());
88         } catch (Exception e) {
89             LOG.error("Retrieval of datapath id for the key {} failed due to {}", interfaceName, e);
90             rpcResultBuilder = RpcResultBuilder.failed();
91         }
92         return Futures.immediateFuture(rpcResultBuilder.build());
93     }
94
95     @Override
96     public Future<RpcResult<GetEndpointIpForDpnOutput>> getEndpointIpForDpn(GetEndpointIpForDpnInput input) {
97         RpcResultBuilder<GetEndpointIpForDpnOutput> rpcResultBuilder;
98         try {
99             BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(input.getDpid());
100             InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
101                     InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
102             BridgeEntry bridgeEntry =
103                     InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
104                             dataBroker);
105             // local ip of any of the bridge interface entry will be the dpn end point ip
106             BridgeInterfaceEntry bridgeInterfaceEntry = bridgeEntry.getBridgeInterfaceEntry().get(0);
107             InterfaceKey interfaceKey = new InterfaceKey(bridgeInterfaceEntry.getInterfaceName());
108             Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
109             IfTunnel tunnel = interfaceInfo.getAugmentation(IfTunnel.class);
110             GetEndpointIpForDpnOutputBuilder endpointIpForDpnOutput = new GetEndpointIpForDpnOutputBuilder().setLocalIps(Arrays.asList(tunnel.getTunnelSource()));
111             rpcResultBuilder = RpcResultBuilder.success();
112             rpcResultBuilder.withResult(endpointIpForDpnOutput.build());
113         }catch(Exception e){
114             LOG.error("Retrieval of endpoint of for dpn {} failed due to {}" ,input.getDpid(), e);
115             rpcResultBuilder = RpcResultBuilder.failed();
116         }
117         return Futures.immediateFuture(rpcResultBuilder.build());
118     }
119
120     @Override
121     public Future<RpcResult<GetEgressInstructionsForInterfaceOutput>> getEgressInstructionsForInterface(GetEgressInstructionsForInterfaceInput input) {
122         RpcResultBuilder<GetEgressInstructionsForInterfaceOutput> rpcResultBuilder;
123         try {
124             List<InstructionInfo> instructionInfo = new ArrayList<InstructionInfo>();
125             List<ActionInfo> actionInfo = getEgressActionInfosForInterface(input.getIntfName());
126             instructionInfo.add(new InstructionInfo(InstructionType.write_actions, actionInfo));
127                     GetEgressInstructionsForInterfaceOutputBuilder output = new GetEgressInstructionsForInterfaceOutputBuilder().
128                     setInstruction(buildInstructions(instructionInfo));
129             rpcResultBuilder = RpcResultBuilder.success();
130             rpcResultBuilder.withResult(output.build());
131         }catch(Exception e){
132             LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e);
133             rpcResultBuilder = RpcResultBuilder.failed();
134         }
135         return Futures.immediateFuture(rpcResultBuilder.build());
136     }
137
138     @Override
139     public Future<RpcResult<GetEgressActionsForInterfaceOutput>> getEgressActionsForInterface(GetEgressActionsForInterfaceInput input) {
140         RpcResultBuilder<GetEgressActionsForInterfaceOutput> rpcResultBuilder;
141         try {
142             List<Action> actionsList = getEgressActionsForInterface(input.getIntfName());
143             GetEgressActionsForInterfaceOutputBuilder output = new GetEgressActionsForInterfaceOutputBuilder().
144                     setAction(actionsList);
145             rpcResultBuilder = RpcResultBuilder.success();
146             rpcResultBuilder.withResult(output.build());
147         }catch(Exception e){
148             LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e);
149             rpcResultBuilder = RpcResultBuilder.failed();
150         }
151         return Futures.immediateFuture(rpcResultBuilder.build());
152     }
153
154     public static InstanceIdentifier<InterfaceChildEntry> getInterfaceChildEntryIdentifier(InterfaceParentEntryKey parentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) {
155         InstanceIdentifier.InstanceIdentifierBuilder<InterfaceChildEntry> interfaceChildEntryInstanceIdentifierBuilder =
156                 InstanceIdentifier.builder(InterfaceChildInfo.class).child(InterfaceParentEntry.class, parentEntryKey).child(InterfaceChildEntry.class, interfaceChildEntryKey);
157         return interfaceChildEntryInstanceIdentifierBuilder.build();
158     }
159
160     public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(String interfaceName,
161                                                          DataBroker dataBroker) {
162         InterfaceParentEntryKey parentEntryKey = new InterfaceParentEntryKey(interfaceName);
163         InterfaceChildEntryKey childEntryKey = new InterfaceChildEntryKey(interfaceName);
164         InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryInstanceIdentifier = getInterfaceChildEntryIdentifier(parentEntryKey, childEntryKey);
165         Optional<InterfaceChildEntry> interfaceChildEntryOptional =
166                 IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryInstanceIdentifier, dataBroker);
167         if (!interfaceChildEntryOptional.isPresent()) {
168             return null;
169         }
170         return interfaceChildEntryOptional.get();
171     }
172
173     @Override
174     public Future<RpcResult<GetPortFromInterfaceOutput>> getPortFromInterface(GetPortFromInterfaceInput input) {
175         RpcResultBuilder<GetPortFromInterfaceOutput> rpcResultBuilder;
176         String interfaceName = input.getIntfName();
177         try {
178             BigInteger dpId = null;
179             long portNo = 0;
180             org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
181                         InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
182             String lowerLayerIf = ifState.getLowerLayerIf().get(0);
183             NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
184             dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
185             portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
186             // FIXME Assuming portName and interfaceName are same
187             GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId).
188                     setPortname(interfaceName).setPortno(Long.valueOf(portNo));
189             rpcResultBuilder = RpcResultBuilder.success();
190             rpcResultBuilder.withResult(output.build());
191         }catch(Exception e){
192             LOG.error("Retrieval of lport tag for the key {} failed due to {}" ,input.getIntfName(), e);
193             rpcResultBuilder = RpcResultBuilder.failed();
194         }
195         return Futures.immediateFuture(rpcResultBuilder.build());
196     }
197
198     @Override
199     public Future<RpcResult<GetInterfaceFromPortOutput>> getInterfaceFromPort(GetInterfaceFromPortInput input) {
200         /*RpcResultBuilder<GetInterfaceFromPortOutput> rpcResultBuilder;
201         try {
202             Interface interfaceInfo = null;
203             NodeId nodeId = IfmUtil.buildDpnNodeId(input.getDpid());
204             Node node = getNodeFromInventoryOperDS(nodeId, dataBroker);
205             ChildInterfaceNames childInterfaceNames = node.getAugmentation(ChildInterfaceNames.class);
206             for(OfInterfaceRefInfo ofInterfaceRefInfo : childInterfaceNames.getOfInterfaceRefInfo()){
207                interfaceInfo = getInterfaceFromTunnelKey(ofInterfaceRefInfo.getOfIntfName(), input.getInterfaceId(),
208                        input.getInterfaceType());
209             }
210             GetInterfaceFromPortOutputBuilder output = new GetInterfaceFromPortOutputBuilder().
211                     setInterfaceName(interfaceInfo == null ? null : interfaceInfo.getName());
212             rpcResultBuilder = RpcResultBuilder.success();
213             rpcResultBuilder.withResult(output.build());
214         }catch(Exception e){
215             LOG.error("Retrieval of interface for the key {} failed due to {}" ,input.getPortno(), e);
216             rpcResultBuilder = RpcResultBuilder.failed();
217         }
218         return Futures.immediateFuture(rpcResultBuilder.build());
219         */
220         return null;
221     }
222
223     public List<ActionInfo> getEgressActionInfosForInterface(String interfaceName) {
224         Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
225                 dataBroker);
226         List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
227         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
228                 InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
229
230         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
231         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
232         String portNo = IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId);
233         Class<? extends InterfaceType> ifType = interfaceInfo.getType();
234         if(L2vlan.class.equals(ifType)){
235             IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
236             LOG.trace("L2Vlan: {}",vlanIface);
237             long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue();
238             if (vlanVid != 0) {
239                 listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
240                 listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
241                         new String[] { Long.toString(vlanVid) }));
242             }
243             listActionInfo.add(new ActionInfo(ActionType.output, new String[] {portNo}));
244         }else if(Tunnel.class.equals(ifType)){
245             listActionInfo.add(new ActionInfo(ActionType.output, new String[] { portNo}));
246         }
247         return listActionInfo;
248     }
249
250     public List<Action> getEgressActionsForInterface(String interfaceName) {
251             List<ActionInfo> listActionInfo = getEgressActionInfosForInterface(interfaceName);
252             List<Action> actionsList = new ArrayList<>();
253             for (ActionInfo actionInfo : listActionInfo) {
254                 actionsList.add(actionInfo.buildAction());
255             }
256             return actionsList;
257     }
258
259     protected static List<Instruction> buildInstructions(List<InstructionInfo> listInstructionInfo) {
260         if (listInstructionInfo != null) {
261             List<Instruction> instructions = new ArrayList<Instruction>();
262             int instructionKey = 0;
263
264             for (InstructionInfo instructionInfo : listInstructionInfo) {
265                 instructions.add(instructionInfo.buildInstruction(instructionKey));
266                 instructionKey++;
267             }
268             return instructions;
269         }
270
271         return null;
272     }
273
274     public static Node getNodeFromInventoryOperDS(NodeId nodeId, DataBroker dataBroker) {
275         InstanceIdentifier<Node> nodeIdentifier = InstanceIdentifier.builder(Nodes.class)
276                 .child(Node.class, new NodeKey(nodeId)).build();
277
278         Optional<Node> nodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
279                 nodeIdentifier, dataBroker);
280         if (!nodeOptional.isPresent()) {
281             return null;
282         }
283         return nodeOptional.get();
284     }
285
286     public Interface getInterfaceFromTunnelKey(String interfaceName, BigInteger tunnelKey,
287                                                Class<? extends TunnelTypeBase> ifType){
288
289         /*Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
290
291         if(ifType.isAssignableFrom(IfL2vlan.class)){
292             IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
293             LOG.trace("L2Vlan: {}",vlanIface);
294             long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId();
295             if(tunnelKey.intValue() == vlanVid){
296                return interfaceInfo;
297             }
298         }else if(ifType.isAssignableFrom(TunnelTypeBase.class)){
299             IfTunnel ifTunnel = interfaceInfo.getAugmentation(IfTunnel.class);
300             TunnelResources tunnelResources = ifTunnel.getTunnelResources();
301             if(ifType.isAssignableFrom(TunnelTypeGre.class)) {
302                 IfGre ifGre = tunnelResources.getAugmentation(IfGre.class);
303                 if (ifGre.getGreKey() == tunnelKey) {
304                     return interfaceInfo;
305                 }
306             }else if(ifType.isAssignableFrom(TunnelTypeVxlan.class)){
307                 IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
308                 if(ifVxlan.getVni() == tunnelKey){
309                     return interfaceInfo;
310                 }
311             }
312         }
313         return null;*/
314         return null;
315     }
316 }