2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.genius.interfacemanager.rpcservice;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.interfacemanager.IfmConstants;
17 import org.opendaylight.genius.interfacemanager.IfmUtil;
18 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
19 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
20 import org.opendaylight.genius.mdsalutil.InstructionInfo;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.genius.mdsalutil.MatchInfo;
23 import org.opendaylight.genius.mdsalutil.NwConstants;
24 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
25 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
26 import org.opendaylight.genius.mdsalutil.matches.MatchMplsLabel;
27 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.DpnToInterfaceList;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntryKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterface;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.DpnToInterfaceKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.dpn.to._interface.list.dpn.to._interface.InterfaceNameEntry;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.*;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.opendaylight.yangtools.yang.common.RpcError;
51 import org.opendaylight.yangtools.yang.common.RpcResult;
52 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 import javax.inject.Inject;
57 import javax.inject.Singleton;
58 import java.math.BigInteger;
59 import java.util.ArrayList;
60 import java.util.Collections;
61 import java.util.List;
62 import java.util.concurrent.Future;
63 import java.util.stream.Collectors;
66 public class InterfaceManagerRpcService implements OdlInterfaceRpcService {
68 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerRpcService.class);
70 private final DataBroker dataBroker;
71 private final IMdsalApiManager mdsalMgr;
74 public InterfaceManagerRpcService(final DataBroker dataBroker, final IMdsalApiManager iMdsalApiManager) {
75 this.dataBroker = dataBroker;
76 this.mdsalMgr = iMdsalApiManager;
80 public Future<RpcResult<GetDpidFromInterfaceOutput>> getDpidFromInterface(GetDpidFromInterfaceInput input) {
81 String interfaceName = input.getIntfName();
82 RpcResultBuilder<GetDpidFromInterfaceOutput> rpcResultBuilder;
84 BigInteger dpId = null;
85 InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
86 Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
87 if (interfaceInfo == null) {
88 rpcResultBuilder = getRpcErrorResultForGetDpnIdRpc(interfaceName,
89 "missing Interface in Config DataStore");
90 return Futures.immediateFuture(rpcResultBuilder.build());
92 if (Tunnel.class.equals(interfaceInfo.getType())) {
93 ParentRefs parentRefs = interfaceInfo.getAugmentation(ParentRefs.class);
94 dpId = parentRefs.getDatapathNodeIdentifier();
96 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
98 = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
99 if (ifState != null) {
100 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
101 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
102 dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
104 rpcResultBuilder = getRpcErrorResultForGetDpnIdRpc(interfaceName, "missing Interface-state");
105 return Futures.immediateFuture(rpcResultBuilder.build());
108 GetDpidFromInterfaceOutputBuilder output = new GetDpidFromInterfaceOutputBuilder().setDpid(dpId);
109 rpcResultBuilder = RpcResultBuilder.success();
110 rpcResultBuilder.withResult(output.build());
111 } catch (Exception e) {
112 rpcResultBuilder = getRpcErrorResultForGetDpnIdRpc(interfaceName, e.getMessage());
114 return Futures.immediateFuture(rpcResultBuilder.build());
117 private RpcResultBuilder<GetDpidFromInterfaceOutput> getRpcErrorResultForGetDpnIdRpc(String interfaceName,
119 errMsg = String.format("Retrieval of datapath id for the key {%s} failed due to %s", interfaceName, errMsg);
121 RpcResultBuilder<GetDpidFromInterfaceOutput> rpcResultBuilder = RpcResultBuilder
122 .<GetDpidFromInterfaceOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
123 return rpcResultBuilder;
127 public Future<RpcResult<GetEndpointIpForDpnOutput>> getEndpointIpForDpn(GetEndpointIpForDpnInput input) {
128 RpcResultBuilder<GetEndpointIpForDpnOutput> rpcResultBuilder;
130 BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(input.getDpid());
131 InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier = InterfaceMetaUtils
132 .getBridgeEntryIdentifier(bridgeEntryKey);
133 BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
135 // local ip of any of the bridge interface entry will be the dpn end
137 BridgeInterfaceEntry bridgeInterfaceEntry = bridgeEntry.getBridgeInterfaceEntry().get(0);
138 InterfaceKey interfaceKey = new InterfaceKey(bridgeInterfaceEntry.getInterfaceName());
139 Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
140 IfTunnel tunnel = interfaceInfo.getAugmentation(IfTunnel.class);
141 GetEndpointIpForDpnOutputBuilder endpointIpForDpnOutput = new GetEndpointIpForDpnOutputBuilder()
142 .setLocalIps(Collections.singletonList(tunnel.getTunnelSource()));
143 rpcResultBuilder = RpcResultBuilder.success();
144 rpcResultBuilder.withResult(endpointIpForDpnOutput.build());
145 } catch (Exception e) {
146 LOG.error("Retrieval of endpoint of for dpn {} failed due to {}", input.getDpid(), e);
147 rpcResultBuilder = RpcResultBuilder.failed();
149 return Futures.immediateFuture(rpcResultBuilder.build());
153 public Future<RpcResult<GetEgressInstructionsForInterfaceOutput>> getEgressInstructionsForInterface(
154 GetEgressInstructionsForInterfaceInput input) {
155 RpcResultBuilder<GetEgressInstructionsForInterfaceOutput> rpcResultBuilder;
157 List<Instruction> instructions = IfmUtil.getEgressInstructionsForInterface(input.getIntfName(),
158 input.getTunnelKey(), dataBroker, false);
159 GetEgressInstructionsForInterfaceOutputBuilder output = new GetEgressInstructionsForInterfaceOutputBuilder()
160 .setInstruction(instructions);
161 rpcResultBuilder = RpcResultBuilder.success();
162 rpcResultBuilder.withResult(output.build());
163 } catch (Exception e) {
164 String errMsg = String.format("Retrieval of egress instructions for the key {%s} failed due to %s", input.getIntfName(),
167 rpcResultBuilder = RpcResultBuilder
168 .<GetEgressInstructionsForInterfaceOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
170 return Futures.immediateFuture(rpcResultBuilder.build());
174 public Future<RpcResult<GetInterfaceTypeOutput>> getInterfaceType(GetInterfaceTypeInput input) {
175 String interfaceName = input.getIntfName();
176 RpcResultBuilder<GetInterfaceTypeOutput> rpcResultBuilder;
178 InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
179 Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
180 if (interfaceInfo == null) {
181 String errMsg = String.format("Retrieval of Interface Type for the key {%s} failed due to "
182 + "missing Interface in Config DataStore", interfaceName);
184 rpcResultBuilder = RpcResultBuilder.<GetInterfaceTypeOutput>failed()
185 .withError(RpcError.ErrorType.APPLICATION, errMsg);
186 return Futures.immediateFuture(rpcResultBuilder.build());
188 GetInterfaceTypeOutputBuilder output = new GetInterfaceTypeOutputBuilder()
189 .setInterfaceType(interfaceInfo.getType());
190 rpcResultBuilder = RpcResultBuilder.success();
191 rpcResultBuilder.withResult(output.build());
192 } catch (Exception e) {
193 LOG.error("Retrieval of interface type for the key {} failed due to {}", interfaceName, e);
194 rpcResultBuilder = RpcResultBuilder.failed();
196 return Futures.immediateFuture(rpcResultBuilder.build());
200 public Future<RpcResult<GetTunnelTypeOutput>> getTunnelType(GetTunnelTypeInput input) {
201 String interfaceName = input.getIntfName();
202 RpcResultBuilder<GetTunnelTypeOutput> rpcResultBuilder;
204 InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
205 Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
206 if (interfaceInfo == null) {
207 String errMsg = String.format(
208 "Retrieval of Tunnel Type for the key {%s} failed due to missing Interface in Config DataStore",
211 rpcResultBuilder = RpcResultBuilder.<GetTunnelTypeOutput>failed()
212 .withError(RpcError.ErrorType.APPLICATION, errMsg);
213 return Futures.immediateFuture(rpcResultBuilder.build());
215 if (Tunnel.class.equals(interfaceInfo.getType())) {
216 IfTunnel tnl = interfaceInfo.getAugmentation(IfTunnel.class);
217 Class<? extends TunnelTypeBase> tunType = tnl.getTunnelInterfaceType();
218 GetTunnelTypeOutputBuilder output = new GetTunnelTypeOutputBuilder().setTunnelType(tunType);
219 rpcResultBuilder = RpcResultBuilder.success();
220 rpcResultBuilder.withResult(output.build());
222 LOG.error("Retrieval of interface type for the key {} failed", interfaceName);
223 rpcResultBuilder = RpcResultBuilder.failed();
225 } catch (Exception e) {
226 LOG.error("Retrieval of interface type for the key {} failed due to {}", interfaceName, e);
227 rpcResultBuilder = RpcResultBuilder.failed();
229 return Futures.immediateFuture(rpcResultBuilder.build());
233 public Future<RpcResult<GetEgressActionsForInterfaceOutput>> getEgressActionsForInterface(
234 GetEgressActionsForInterfaceInput input) {
235 RpcResultBuilder<GetEgressActionsForInterfaceOutput> rpcResultBuilder;
237 LOG.debug("Get Egress Action for interface {} with key {}", input.getIntfName(), input.getTunnelKey());
238 List<Action> actionsList = IfmUtil.getEgressActionsForInterface(input.getIntfName(), input.getTunnelKey(),
239 input.getActionKey(), dataBroker, false);
240 GetEgressActionsForInterfaceOutputBuilder output = new GetEgressActionsForInterfaceOutputBuilder()
241 .setAction(actionsList);
242 rpcResultBuilder = RpcResultBuilder.success();
243 rpcResultBuilder.withResult(output.build());
244 } catch (Exception e) {
245 String errMsg = String.format("Retrieval of egress actions for {%s} failed due to %s", input.getIntfName(),
248 rpcResultBuilder = RpcResultBuilder
249 .<GetEgressActionsForInterfaceOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
251 return Futures.immediateFuture(rpcResultBuilder.build());
255 public Future<RpcResult<GetPortFromInterfaceOutput>> getPortFromInterface(GetPortFromInterfaceInput input) {
256 RpcResultBuilder<GetPortFromInterfaceOutput> rpcResultBuilder;
257 String interfaceName = input.getIntfName();
259 BigInteger dpId = null;
261 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
262 .Interface ifState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName,
264 if (ifState != null) {
265 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
266 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
267 dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
268 portNo = IfmUtil.getPortNumberFromNodeConnectorId(nodeConnectorId);
269 String phyAddress = ifState.getPhysAddress().getValue();
270 // FIXME Assuming portName and interfaceName are same
271 GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId)
272 .setPortname(interfaceName).setPortno(portNo).setPhyAddress(phyAddress);
273 rpcResultBuilder = RpcResultBuilder.success();
274 rpcResultBuilder.withResult(output.build());
276 rpcResultBuilder = getRpcErrorResultForGetPortRpc(interfaceName, "missing Interface state");
278 } catch (Exception e) {
279 rpcResultBuilder = getRpcErrorResultForGetPortRpc(interfaceName, e.getMessage());
281 return Futures.immediateFuture(rpcResultBuilder.build());
284 private RpcResultBuilder<GetPortFromInterfaceOutput> getRpcErrorResultForGetPortRpc(String interfaceName,
286 errMsg = String.format("Retrieval of Port for the key {%s} failed due to %s", interfaceName, errMsg);
288 RpcResultBuilder<GetPortFromInterfaceOutput> rpcResultBuilder = RpcResultBuilder
289 .<GetPortFromInterfaceOutput>failed().withError(RpcError.ErrorType.APPLICATION, errMsg);
290 return rpcResultBuilder;
294 public Future<RpcResult<GetNodeconnectorIdFromInterfaceOutput>> getNodeconnectorIdFromInterface(
295 GetNodeconnectorIdFromInterfaceInput input) {
296 String interfaceName = input.getIntfName();
297 RpcResultBuilder<GetNodeconnectorIdFromInterfaceOutput> rpcResultBuilder;
299 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
300 .Interface ifState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
301 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
302 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
304 GetNodeconnectorIdFromInterfaceOutputBuilder output = new GetNodeconnectorIdFromInterfaceOutputBuilder()
305 .setNodeconnectorId(nodeConnectorId);
306 rpcResultBuilder = RpcResultBuilder.success();
307 rpcResultBuilder.withResult(output.build());
308 } catch (Exception e) {
309 LOG.error("Retrieval of nodeconnector id for the key {} failed due to {}", interfaceName, e);
310 rpcResultBuilder = RpcResultBuilder.failed();
312 return Futures.immediateFuture(rpcResultBuilder.build());
316 public Future<RpcResult<GetInterfaceFromIfIndexOutput>> getInterfaceFromIfIndex(
317 GetInterfaceFromIfIndexInput input) {
318 Integer ifIndex = input.getIfIndex();
319 RpcResultBuilder<GetInterfaceFromIfIndexOutput> rpcResultBuilder = null;
321 InstanceIdentifier<IfIndexInterface> id = InstanceIdentifier.builder(IfIndexesInterfaceMap.class)
322 .child(IfIndexInterface.class, new IfIndexInterfaceKey(ifIndex)).build();
323 Optional<IfIndexInterface> ifIndexesInterface = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id,
325 if (ifIndexesInterface.isPresent()) {
326 String interfaceName = ifIndexesInterface.get().getInterfaceName();
327 GetInterfaceFromIfIndexOutputBuilder output = new GetInterfaceFromIfIndexOutputBuilder()
328 .setInterfaceName(interfaceName);
329 rpcResultBuilder = RpcResultBuilder.success();
330 rpcResultBuilder.withResult(output.build());
332 } catch (Exception e) {
333 LOG.error("Retrieval of interfaceName for the key {} failed due to {}", ifIndex, e);
334 rpcResultBuilder = RpcResultBuilder.failed();
336 return Futures.immediateFuture(rpcResultBuilder.build());
340 public Future<RpcResult<GetDpnInterfaceListOutput>> getDpnInterfaceList(GetDpnInterfaceListInput input) {
341 BigInteger dpnid = input.getDpid();
342 RpcResultBuilder<GetDpnInterfaceListOutput> rpcResultBuilder = null;
344 InstanceIdentifier<DpnToInterface> id = InstanceIdentifier.builder(DpnToInterfaceList.class)
345 .child(DpnToInterface.class, new DpnToInterfaceKey(dpnid)).build();
346 Optional<DpnToInterface> entry = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, dataBroker);
347 if (entry.isPresent()) {
348 List<InterfaceNameEntry> interfaceNameEntries = entry.get().getInterfaceNameEntry();
349 if (interfaceNameEntries != null && !interfaceNameEntries.isEmpty()) {
350 List<String> interfaceList = interfaceNameEntries.stream().map(InterfaceNameEntry::getInterfaceName)
351 .collect(Collectors.toList());
352 GetDpnInterfaceListOutputBuilder output = new GetDpnInterfaceListOutputBuilder()
353 .setInterfacesList(interfaceList);
354 rpcResultBuilder = RpcResultBuilder.success();
355 rpcResultBuilder.withResult(output.build());
358 } catch (Exception e) {
359 LOG.error("Retrieval of interfaceNameList for the dpnId {} failed due to {}", dpnid, e);
360 rpcResultBuilder = RpcResultBuilder.failed();
362 return Futures.immediateFuture(rpcResultBuilder.build());
365 protected static List<Instruction> buildInstructions(List<InstructionInfo> listInstructionInfo) {
366 if (listInstructionInfo != null) {
367 List<Instruction> instructions = new ArrayList<>();
368 int instructionKey = 0;
370 for (InstructionInfo instructionInfo : listInstructionInfo) {
371 instructions.add(instructionInfo.buildInstruction(instructionKey));
380 private ListenableFuture<Void> makeTerminatingServiceFlow(IfTunnel tunnelInfo, BigInteger dpnId,
381 BigInteger tunnelKey, List<Instruction> instruction, int addOrRemove) {
382 List<MatchInfo> mkMatches = new ArrayList<>();
383 mkMatches.add(new MatchTunnelId(tunnelKey));
384 short tableId = tunnelInfo.isInternal() ? NwConstants.INTERNAL_TUNNEL_TABLE : NwConstants.EXTERNAL_TUNNEL_TABLE;
385 final String flowRef = getFlowRef(dpnId, tableId, tunnelKey);
386 Flow terminatingSerFlow = MDSALUtil.buildFlowNew(tableId, flowRef, 5, "TST Flow Entry", 0, 0,
387 IfmConstants.TUNNEL_TABLE_COOKIE.add(tunnelKey), mkMatches, instruction);
388 if (addOrRemove == NwConstants.ADD_FLOW) {
389 return mdsalMgr.installFlow(dpnId, terminatingSerFlow);
392 return mdsalMgr.removeFlow(dpnId, terminatingSerFlow);
395 private ListenableFuture<Void> makeLFIBFlow(BigInteger dpnId, BigInteger tunnelKey, List<Instruction> instruction,
397 List<MatchInfo> mkMatches = new ArrayList<>();
398 mkMatches.add(MatchEthernetType.MPLS_UNICAST);
399 mkMatches.add(new MatchMplsLabel(tunnelKey.longValue()));
400 // Install the flow entry in L3_LFIB_TABLE
401 String flowRef = getFlowRef(dpnId, NwConstants.L3_LFIB_TABLE, tunnelKey);
403 Flow lfibFlow = MDSALUtil.buildFlowNew(NwConstants.L3_LFIB_TABLE, flowRef, IfmConstants.DEFAULT_FLOW_PRIORITY,
404 "LFIB Entry", 0, 0, IfmConstants.COOKIE_VM_LFIB_TABLE, mkMatches, instruction);
405 if (addOrRemove == NwConstants.ADD_FLOW) {
406 return mdsalMgr.installFlow(dpnId, lfibFlow);
408 return mdsalMgr.removeFlow(dpnId, lfibFlow);
411 private String getFlowRef(BigInteger dpnId, short tableId, BigInteger tunnelKey) {
412 return IfmConstants.TUNNEL_TABLE_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
413 + NwConstants.FLOWID_SEPARATOR + tunnelKey;