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
8 package org.opendaylight.netvirt.natservice.internal;
10 import org.opendaylight.controller.liblldp.NetUtils;
11 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
12 import org.opendaylight.genius.mdsalutil.NwConstants;
13 import org.opendaylight.genius.mdsalutil.packet.Ethernet;
14 import org.opendaylight.genius.mdsalutil.packet.IPv4;
15 import org.opendaylight.genius.mdsalutil.packet.TCP;
16 import org.opendaylight.genius.mdsalutil.packet.UDP;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 import java.math.BigInteger;
23 import java.util.HashSet;
24 import com.google.common.primitives.Ints;
26 public class NaptPacketInHandler implements PacketProcessingListener {
28 private static final Logger LOG = LoggerFactory.getLogger(NaptPacketInHandler.class);
29 private final static HashSet<String> incomingPacketMap = new HashSet<>();
30 private final EventDispatcher naptEventdispatcher;
32 public NaptPacketInHandler(EventDispatcher eventDispatcher) {
33 this.naptEventdispatcher = eventDispatcher;
37 public void onPacketReceived(PacketReceived packetReceived) {
38 String internalIPAddress = "";
41 NAPTEntryEvent.Operation operation = NAPTEntryEvent.Operation.ADD;
42 NAPTEntryEvent.Protocol protocol;
44 Short tableId = packetReceived.getTableId().getValue();
46 if (LOG.isTraceEnabled()) {
47 LOG.trace("packet: {}, tableId {}", packetReceived, tableId);
50 if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
51 LOG.debug("NAT Service : NAPTPacketInHandler Packet for Outbound NAPT Table");
52 byte[] inPayload = packetReceived.getPayload();
53 Ethernet ethPkt = new Ethernet();
54 if (inPayload != null) {
56 ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NumBitsInAByte);
57 } catch (Exception e) {
58 LOG.warn("Failed to decode Packet", e);
61 if (ethPkt.getPayload() instanceof IPv4) {
62 IPv4 ipPkt = (IPv4) ethPkt.getPayload();
63 byte[] ipSrc = Ints.toByteArray(ipPkt.getSourceAddress());
65 internalIPAddress = NatUtil.toStringIpAddress(ipSrc, LOG);
66 LOG.trace("Retrieved internalIPAddress {}", internalIPAddress);
67 if (ipPkt.getPayload() instanceof TCP) {
68 TCP tcpPkt = (TCP) ipPkt.getPayload();
69 portNumber = tcpPkt.getSourcePort();
71 portNumber = 32767 + portNumber + 32767 + 2;
72 LOG.trace("Retrieved and extracted TCP portNumber {}", portNumber);
74 protocol = NAPTEntryEvent.Protocol.TCP;
75 LOG.trace("Retrieved TCP portNumber {}", portNumber);
76 } else if (ipPkt.getPayload() instanceof UDP) {
77 UDP udpPkt = (UDP) ipPkt.getPayload();
78 portNumber = udpPkt.getSourcePort();
80 portNumber = 32767 + portNumber + 32767 + 2;
81 LOG.trace("Retrieved and extracted UDP portNumber {}", portNumber);
83 protocol = NAPTEntryEvent.Protocol.UDP;
84 LOG.trace("Retrieved UDP portNumber {}", portNumber);
86 LOG.error("Incoming Packet is neither TCP or UDP packet");
90 LOG.error("Incoming Packet is not IPv4 packet");
94 if(internalIPAddress != null) {
95 String sourceIPPortKey = internalIPAddress + ":" + portNumber;
96 LOG.debug("NAT Service : sourceIPPortKey {} mapping maintained in the map", sourceIPPortKey);
97 if (!incomingPacketMap.contains(sourceIPPortKey)) {
98 incomingPacketMap.add(internalIPAddress + portNumber);
99 LOG.trace("NAT Service : Processing new Packet");
100 BigInteger metadata = packetReceived.getMatch().getMetadata().getMetadata();
101 routerId = (metadata.and(MetaDataUtil.METADATA_MASK_VRFID)).longValue();
103 LOG.error("NAT Service : Router ID is invalid");
106 //send to Event Queue
107 LOG.trace("NAT Service : Creating NaptEvent for routerId {} and sourceIp {} and Port {}", routerId,
108 internalIPAddress, portNumber);
109 NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress,portNumber,routerId,
110 operation,protocol, packetReceived, false);
111 naptEventdispatcher.addNaptEvent(naptEntryEvent);
112 LOG.trace("NAT Service : PacketInHandler sent event to NaptEventHandler");
114 LOG.trace("NAT Service : Packet already processed");
115 NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress,portNumber,routerId,
116 operation,protocol, packetReceived, true);
117 LOG.trace("NAT Service : PacketInHandler sent event to NaptEventHandler");
120 LOG.error("Nullpointer exception in retrieving internalIPAddress");
124 LOG.trace("Packet is not from the Outbound NAPT table");
128 public void removeIncomingPacketMap(String sourceIPPortKey) {
129 incomingPacketMap.remove(sourceIPPortKey);
130 LOG.debug("NAT Service : sourceIPPortKey {} mapping is removed from map", sourceIPPortKey);