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.netvirt.natservice.internal;
11 import java.math.BigInteger;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Future;
18 import org.opendaylight.controller.liblldp.NetUtils;
19 import org.opendaylight.controller.liblldp.PacketException;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
22 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
23 import org.opendaylight.genius.mdsalutil.ActionInfo;
24 import org.opendaylight.genius.mdsalutil.FlowEntity;
25 import org.opendaylight.genius.mdsalutil.InstructionInfo;
26 import org.opendaylight.genius.mdsalutil.MDSALUtil;
27 import org.opendaylight.genius.mdsalutil.MatchInfo;
28 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
29 import org.opendaylight.genius.mdsalutil.NwConstants;
30 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
31 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
32 import org.opendaylight.genius.mdsalutil.actions.ActionSetDestinationIp;
33 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
34 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
35 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
36 import org.opendaylight.genius.mdsalutil.actions.ActionSetSourceIp;
37 import org.opendaylight.genius.mdsalutil.actions.ActionSetTcpDestinationPort;
38 import org.opendaylight.genius.mdsalutil.actions.ActionSetTcpSourcePort;
39 import org.opendaylight.genius.mdsalutil.actions.ActionSetUdpDestinationPort;
40 import org.opendaylight.genius.mdsalutil.actions.ActionSetUdpSourcePort;
41 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
42 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
43 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
44 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
45 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
46 import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
47 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
48 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source;
49 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
50 import org.opendaylight.genius.mdsalutil.matches.MatchTcpDestinationPort;
51 import org.opendaylight.genius.mdsalutil.matches.MatchTcpSourcePort;
52 import org.opendaylight.genius.mdsalutil.matches.MatchUdpDestinationPort;
53 import org.opendaylight.genius.mdsalutil.matches.MatchUdpSourcePort;
54 import org.opendaylight.genius.mdsalutil.packet.Ethernet;
55 import org.opendaylight.genius.mdsalutil.packet.IPv4;
56 import org.opendaylight.genius.mdsalutil.packet.TCP;
57 import org.opendaylight.genius.mdsalutil.packet.UDP;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
69 import org.opendaylight.yangtools.yang.common.RpcResult;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
73 public class NaptEventHandler {
74 private static final Logger LOG = LoggerFactory.getLogger(NaptEventHandler.class);
75 private final DataBroker dataBroker;
76 private static IMdsalApiManager mdsalManager;
77 private final PacketProcessingService pktService;
78 private final OdlInterfaceRpcService interfaceManagerRpc;
79 private final NaptManager naptManager;
80 private IInterfaceManager interfaceManager;
82 public NaptEventHandler(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
83 final NaptManager naptManager,
84 final PacketProcessingService pktService,
85 final OdlInterfaceRpcService interfaceManagerRpc,
86 final IInterfaceManager interfaceManager) {
87 this.dataBroker = dataBroker;
88 NaptEventHandler.mdsalManager = mdsalManager;
89 this.naptManager = naptManager;
90 this.pktService = pktService;
91 this.interfaceManagerRpc = interfaceManagerRpc;
92 this.interfaceManager = interfaceManager;
95 // TODO Clean up the exception handling
96 @SuppressWarnings("checkstyle:IllegalCatch")
97 public void handleEvent(NAPTEntryEvent naptEntryEvent) {
99 Flow programming logic of the OUTBOUND NAPT TABLE :
100 1) Get the internal IP address, port number, router ID from the event.
101 2) Use the NAPT service getExternalAddressMapping() to get the External IP and the port.
102 3) Build the flow for replacing the Internal IP and port with the External IP and port.
103 a) Write the matching criteria.
104 b) Match the router ID in the metadata.
105 d) Write the VPN ID to the metadata.
106 e) Write the other data.
107 f) Set the apply actions instruction with the action setfield.
108 4) Write the flow to the OUTBOUND NAPT Table and forward to FIB table for routing the traffic.
110 Flow programming logic of the INBOUND NAPT TABLE :
111 Same as Outbound table logic except that :
112 1) Build the flow for replacing the External IP and port with the Internal IP and port.
113 2) Match the VPN ID in the metadata.
114 3) Write the router ID to the metadata.
115 5) Write the flow to the INBOUND NAPT Table and forward to FIB table for routing the traffic.
118 Long routerId = naptEntryEvent.getRouterId();
119 LOG.info("NAT Service : handleEvent() entry for IP {}, port {}, routerID {}",
120 naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), routerId);
121 // Get the External Gateway MAC Address
122 String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterId(dataBroker, routerId);
123 if (extGwMacAddress != null) {
124 LOG.debug("NAT Service : External Gateway MAC address {} found for External Router ID {}",
125 extGwMacAddress, routerId);
127 LOG.error("NAT Service : No External Gateway MAC address found for External Router ID {}", routerId);
131 BigInteger dpnId = NatUtil.getPrimaryNaptfromRouterId(dataBroker, routerId);
132 long bgpVpnId = NatConstants.INVALID_ID;
134 LOG.warn("NAT Service : dpnId is null. Assuming the router ID {} as the BGP VPN ID and proceeding....",
137 LOG.debug("NAT Service : BGP VPN ID {}", bgpVpnId);
138 String vpnName = NatUtil.getRouterName(dataBroker, bgpVpnId);
139 String routerName = NatUtil.getRouterIdfromVpnInstance(dataBroker, vpnName);
140 if (routerName == null) {
141 LOG.error("NAT Service: Unable to find router for VpnName {}", vpnName);
144 routerId = NatUtil.getVpnId(dataBroker, routerName);
145 LOG.debug("NAT Service : Router ID {}", routerId);
146 dpnId = NatUtil.getPrimaryNaptfromRouterId(dataBroker, routerId);
148 LOG.error("NAT Service : dpnId is null for the router {}", routerId);
152 if (naptEntryEvent.getOperation() == NAPTEntryEvent.Operation.ADD) {
153 LOG.debug("NAT Service : Inside Add operation of NaptEventHandler");
155 //Get the external network ID from the ExternalRouter model
156 Uuid networkId = NatUtil.getNetworkIdFromRouterId(dataBroker, routerId);
157 if (networkId == null) {
158 LOG.error("NAT Service : networkId is null");
162 //Get the VPN ID from the ExternalNetworks model
163 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
164 if (vpnUuid == null) {
165 LOG.error("NAT Service : vpnUuid is null");
168 Long vpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
170 //Get the internal IpAddress, internal port number from the event
171 String internalIpAddress = naptEntryEvent.getIpAddress();
172 int internalPort = naptEntryEvent.getPortNumber();
173 SessionAddress internalAddress = new SessionAddress(internalIpAddress, internalPort);
174 NAPTEntryEvent.Protocol protocol = naptEntryEvent.getProtocol();
176 //Get the external IP address for the corresponding internal IP address
177 SessionAddress externalAddress =
178 naptManager.getExternalAddressMapping(routerId, internalAddress, naptEntryEvent.getProtocol());
179 if (externalAddress == null) {
180 LOG.error("NAT Service : externalAddress is null");
183 // Build and install the NAPT translation flows in the Outbound and Inbound NAPT tables
184 if (!naptEntryEvent.isPktProcessed()) {
185 // Added External Gateway MAC Address
186 buildAndInstallNatFlows(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, vpnId, routerId, bgpVpnId,
187 internalAddress, externalAddress, protocol, extGwMacAddress);
188 buildAndInstallNatFlows(dpnId, NwConstants.INBOUND_NAPT_TABLE, vpnId, routerId, bgpVpnId,
189 externalAddress, internalAddress, protocol, extGwMacAddress);
192 //Send Packetout - tcp or udp packets which got punted to controller.
193 BigInteger metadata = naptEntryEvent.getPacketReceived().getMatch().getMetadata().getMetadata();
194 byte[] inPayload = naptEntryEvent.getPacketReceived().getPayload();
195 Ethernet ethPkt = new Ethernet();
196 if (inPayload != null) {
198 ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NumBitsInAByte);
199 } catch (Exception e) {
200 LOG.warn("NAT Service : Failed to decode Packet", e);
206 long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
207 LOG.debug("NAT Service : portTag from incoming packet is {}", portTag);
208 String interfaceName = getInterfaceNameFromTag(portTag);
209 LOG.debug("NAT Service : interfaceName fetched from portTag is {}", interfaceName);
210 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
211 .interfaces.Interface iface = null;
213 iface = interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
215 LOG.error("NAT Service : Unable to read interface {} from config DataStore", interfaceName);
218 IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
219 if (ifL2vlan != null && ifL2vlan.getVlanId() != null) {
220 vlanId = ifL2vlan.getVlanId().getValue() == null ? 0 : ifL2vlan.getVlanId().getValue();
222 InterfaceInfo infInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
223 if (infInfo != null) {
224 LOG.debug("NAT Service : portName fetched from interfaceManager is {}", infInfo.getPortName());
227 byte[] pktOut = buildNaptPacketOut(ethPkt);
229 List<ActionInfo> actionInfos = new ArrayList<ActionInfo>();
230 if (ethPkt.getPayload() instanceof IPv4) {
231 IPv4 ipPkt = (IPv4) ethPkt.getPayload();
232 if ((ipPkt.getPayload() instanceof TCP) || (ipPkt.getPayload() instanceof UDP)) {
233 if (ethPkt.getEtherType() != (short) NwConstants.ETHTYPE_802_1Q) {
235 if (infInfo != null) {
236 LOG.debug("NAT Service : vlanId is {}", vlanId);
239 actionInfos.add(new ActionPushVlan(0));
240 actionInfos.add(new ActionSetFieldVlanVid(1, vlanId));
242 LOG.debug("NAT Service : No vlanId {}, may be untagged", vlanId);
245 LOG.error("NAT Service : error in getting interfaceInfo");
250 LOG.debug("NAT Service : This is VLAN Trunk port case - need not do VLAN tagging again");
254 if (pktOut != null) {
255 sendNaptPacketOut(pktOut, infInfo, actionInfos, routerId);
257 LOG.warn("NAT Service : Unable to send Packet Out");
261 LOG.debug("NAT Service : Inside delete Operation of NaptEventHandler");
262 removeNatFlows(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId, naptEntryEvent.getIpAddress(),
263 naptEntryEvent.getPortNumber());
266 LOG.info("NAT Service : handleNaptEvent() exited for IP {}, port {}, routerID : {}",
267 naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), routerId);
268 } catch (Exception e) {
269 LOG.error("NAT Service :Exception in NaptEventHandler.handleEvent() payload {}", naptEntryEvent, e);
273 public static void buildAndInstallNatFlows(BigInteger dpnId, short tableId, long vpnId, long routerId,
274 long bgpVpnId, SessionAddress actualSourceAddress,
275 SessionAddress translatedSourceAddress,
276 NAPTEntryEvent.Protocol protocol, String extGwMacAddress) {
277 LOG.debug("NAT Service : Build and install NAPT flows in InBound and OutBound tables for "
278 + "dpnId {} and routerId {}", dpnId, routerId);
279 //Build the flow for replacing the actual IP and port with the translated IP and port.
281 if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
282 idleTimeout = NatConstants.DEFAULT_NAPT_IDLE_TIMEOUT;
285 if (bgpVpnId != NatConstants.INVALID_ID) {
286 intranetVpnId = bgpVpnId;
288 intranetVpnId = routerId;
290 LOG.debug("NAT Service : Intranet VPN ID {}", intranetVpnId);
291 LOG.debug("NAT Service : Router ID {}", routerId);
292 String translatedIp = translatedSourceAddress.getIpAddress();
293 int translatedPort = translatedSourceAddress.getPortNumber();
294 String actualIp = actualSourceAddress.getIpAddress();
295 int actualPort = actualSourceAddress.getPortNumber();
296 String switchFlowRef =
297 NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), actualIp, actualPort);
298 FlowEntity snatFlowEntity = MDSALUtil.buildFlowEntity(dpnId, tableId, switchFlowRef,
299 NatConstants.DEFAULT_NAPT_FLOW_PRIORITY, NatConstants.NAPT_FLOW_NAME, idleTimeout, 0,
300 NatUtil.getCookieNaptFlow(routerId),
301 buildAndGetMatchInfo(actualIp, actualPort, tableId, protocol, intranetVpnId, vpnId),
302 buildAndGetSetActionInstructionInfo(translatedIp, translatedPort, intranetVpnId, vpnId, tableId,
303 protocol, extGwMacAddress));
305 snatFlowEntity.setSendFlowRemFlag(true);
307 LOG.debug("NAT Service : Installing the NAPT flow in the table {} for the switch with the DPN ID {} ",
309 mdsalManager.syncInstallFlow(snatFlowEntity, 1);
310 LOG.trace("NAT Service : Exited buildAndInstallNatflows");
313 private static List<MatchInfo> buildAndGetMatchInfo(String ip, int port, short tableId,
314 NAPTEntryEvent.Protocol protocol, long segmentId, long vpnId) {
315 MatchInfo ipMatchInfo = null;
316 MatchInfo portMatchInfo = null;
317 MatchInfo protocolMatchInfo = null;
318 InetAddress ipAddress = null;
319 String ipAddressAsString = null;
321 ipAddress = InetAddress.getByName(ip);
322 ipAddressAsString = ipAddress.getHostAddress();
324 } catch (UnknownHostException e) {
325 LOG.error("NAT Service : UnknowHostException in buildAndGetMatchInfo. Failed to build NAPT Flow for "
326 + "ip {}", ipAddress);
330 MatchInfo metaDataMatchInfo = null;
331 if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
332 ipMatchInfo = new MatchIpv4Source(ipAddressAsString, "32");
333 if (protocol == NAPTEntryEvent.Protocol.TCP) {
334 protocolMatchInfo = MatchIpProtocol.TCP;
335 portMatchInfo = new MatchTcpSourcePort(port);
336 } else if (protocol == NAPTEntryEvent.Protocol.UDP) {
337 protocolMatchInfo = MatchIpProtocol.UDP;
338 portMatchInfo = new MatchUdpSourcePort(port);
341 new MatchMetadata(MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID);
343 ipMatchInfo = new MatchIpv4Destination(ipAddressAsString, "32");
344 if (protocol == NAPTEntryEvent.Protocol.TCP) {
345 protocolMatchInfo = MatchIpProtocol.TCP;
346 portMatchInfo = new MatchTcpDestinationPort(port);
347 } else if (protocol == NAPTEntryEvent.Protocol.UDP) {
348 protocolMatchInfo = MatchIpProtocol.UDP;
349 portMatchInfo = new MatchUdpDestinationPort(port);
351 //metaDataMatchInfo = new MatchMetadata(BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID);
353 ArrayList<MatchInfo> matchInfo = new ArrayList<>();
354 matchInfo.add(MatchEthernetType.IPV4);
355 matchInfo.add(ipMatchInfo);
356 matchInfo.add(protocolMatchInfo);
357 matchInfo.add(portMatchInfo);
358 if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
359 matchInfo.add(metaDataMatchInfo);
364 private static List<InstructionInfo> buildAndGetSetActionInstructionInfo(String ipAddress, int port,
365 long segmentId, long vpnId,
367 NAPTEntryEvent.Protocol protocol,
368 String extGwMacAddress) {
369 ActionInfo ipActionInfo = null;
370 ActionInfo macActionInfo = null;
371 ActionInfo portActionInfo = null;
372 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
373 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
375 case NwConstants.OUTBOUND_NAPT_TABLE:
376 ipActionInfo = new ActionSetSourceIp(ipAddress);
377 // Added External Gateway MAC Address
378 macActionInfo = new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress));
379 if (protocol == NAPTEntryEvent.Protocol.TCP) {
380 portActionInfo = new ActionSetTcpSourcePort(port);
381 } else if (protocol == NAPTEntryEvent.Protocol.UDP) {
382 portActionInfo = new ActionSetUdpSourcePort(port);
384 // reset the split-horizon bit to allow traffic from tunnel to be sent back to the provider port
385 instructionInfo.add(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnId),
386 MetaDataUtil.METADATA_MASK_VRFID.or(MetaDataUtil.METADATA_MASK_SH_FLAG)));
389 case NwConstants.INBOUND_NAPT_TABLE:
390 ipActionInfo = new ActionSetDestinationIp(ipAddress);
391 if (protocol == NAPTEntryEvent.Protocol.TCP) {
392 portActionInfo = new ActionSetTcpDestinationPort(port);
393 } else if (protocol == NAPTEntryEvent.Protocol.UDP) {
394 portActionInfo = new ActionSetUdpDestinationPort(port);
396 instructionInfo.add(new InstructionWriteMetadata(
397 MetaDataUtil.getVpnIdMetadata(segmentId), MetaDataUtil.METADATA_MASK_VRFID));
401 LOG.error("NAT Service : Neither OUTBOUND_NAPT_TABLE nor INBOUND_NAPT_TABLE matches with "
402 + "input table id {}", tableId);
406 listActionInfo.add(ipActionInfo);
407 listActionInfo.add(portActionInfo);
408 if (macActionInfo != null) {
409 listActionInfo.add(macActionInfo);
410 LOG.debug("NAT Service : External GW MAC Address {} is found ", macActionInfo);
412 instructionInfo.add(new InstructionApplyActions(listActionInfo));
413 instructionInfo.add(new InstructionGotoTable(NwConstants.NAPT_PFIB_TABLE));
415 return instructionInfo;
418 void removeNatFlows(BigInteger dpnId, short tableId ,long segmentId, String ip, int port) {
419 if (dpnId == null || dpnId.equals(BigInteger.ZERO)) {
420 LOG.error("NAT Service : DPN ID {} is invalid" , dpnId);
422 LOG.debug("NAT Service : Remove NAPT flows for dpnId {}, segmentId {}, ip {} and port {} ",
423 dpnId, segmentId, ip, port);
425 //Build the flow with the port IP and port as the match info.
426 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(segmentId), ip, port);
427 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
428 LOG.debug("NAT Service : Remove the flow in the table {} for the switch with the DPN ID {}",
429 NwConstants.INBOUND_NAPT_TABLE, dpnId);
430 mdsalManager.removeFlow(snatFlowEntity);
434 protected byte[] buildNaptPacketOut(Ethernet etherPkt) {
435 LOG.debug("NAT Service : About to build Napt Packet Out");
436 if (etherPkt.getPayload() instanceof IPv4) {
438 IPv4 ipPkt = (IPv4) etherPkt.getPayload();
439 if ((ipPkt.getPayload() instanceof TCP) || (ipPkt.getPayload() instanceof UDP)) {
441 rawPkt = etherPkt.serialize();
443 } catch (PacketException e2) {
444 LOG.error("failed to build NAPT Packet out ", e2);
448 LOG.error("NAT Service : Unable to build NaptPacketOut since its neither TCP nor UDP");
452 LOG.error("NAT Service : Unable to build NaptPacketOut since its not IPv4 packet");
456 private void sendNaptPacketOut(byte[] pktOut, InterfaceInfo infInfo, List<ActionInfo> actionInfos, Long routerId) {
457 LOG.trace("NAT Service: Sending packet out DpId {}, interfaceInfo {}", infInfo.getDpId(), infInfo);
458 // set inPort, and action as OFPP_TABLE so that it starts from table 0 (lowest table as per spec)
459 actionInfos.add(new ActionSetFieldTunnelId(2, BigInteger.valueOf(routerId)));
460 actionInfos.add(new ActionOutput(3, new Uri("0xfffffff9")));
461 NodeConnectorRef inPort = MDSALUtil.getNodeConnRef(infInfo.getDpId(), String.valueOf(infInfo.getPortNo()));
462 LOG.debug("NAT Service : inPort for packetout is being set to {}", String.valueOf(infInfo.getPortNo()));
463 TransmitPacketInput output = MDSALUtil.getPacketOut(actionInfos, pktOut, infInfo.getDpId().longValue(), inPort);
464 LOG.trace("NAT Service: Transmitting packet: {}",output);
465 this.pktService.transmitPacket(output);
468 private String getInterfaceNameFromTag(long portTag) {
469 String interfaceName = null;
470 GetInterfaceFromIfIndexInput input =
471 new GetInterfaceFromIfIndexInputBuilder().setIfIndex(new Integer((int)portTag)).build();
472 Future<RpcResult<GetInterfaceFromIfIndexOutput>> futureOutput =
473 interfaceManagerRpc.getInterfaceFromIfIndex(input);
475 GetInterfaceFromIfIndexOutput output = futureOutput.get().getResult();
476 interfaceName = output.getInterfaceName();
477 } catch (InterruptedException | ExecutionException e) {
478 LOG.error("NAT Service : Error while retrieving the interfaceName from tag using "
479 + "getInterfaceFromIfIndex RPC");
481 LOG.trace("NAT Service : Returning interfaceName {} for tag {} form getInterfaceNameFromTag",
482 interfaceName, portTag);
483 return interfaceName;