Bump versions by 0.1.0 for next dev cycle
[vpnservice.git] / natservice / natservice-impl / src / main / java / org / opendaylight / vpnservice / natservice / internal / NaptPacketInHandler.java
1 /*
2  * Copyright (c) 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.natservice.internal;
9
10 import org.opendaylight.controller.liblldp.NetUtils;
11 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
12 import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
13 import org.opendaylight.vpnservice.mdsalutil.packet.IPv4;
14 import org.opendaylight.vpnservice.mdsalutil.packet.TCP;
15 import org.opendaylight.vpnservice.mdsalutil.packet.UDP;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 import java.math.BigInteger;
22 import java.util.HashSet;
23 import com.google.common.primitives.Ints;
24
25 public class NaptPacketInHandler implements PacketProcessingListener {
26
27     private static final Logger LOG = LoggerFactory.getLogger(NaptPacketInHandler.class);
28     private final static HashSet<String> incomingPacketMap = new HashSet<>();
29     private final EventDispatcher naptEventdispatcher;
30
31     public NaptPacketInHandler(EventDispatcher eventDispatcher) {
32         this.naptEventdispatcher = eventDispatcher;
33     }
34
35     @Override
36     public void onPacketReceived(PacketReceived packetReceived) {
37         String internalIPAddress = "";
38         int portNumber = 0;
39         long routerId = 0L;
40         NAPTEntryEvent.Operation operation = NAPTEntryEvent.Operation.ADD;
41         NAPTEntryEvent.Protocol protocol;
42
43         Short tableId = packetReceived.getTableId().getValue();
44
45         if (LOG.isTraceEnabled()) {
46             LOG.trace("packet: {}, tableId {}", packetReceived, tableId);
47         }
48
49         if (tableId == NatConstants.OUTBOUND_NAPT_TABLE) {
50             LOG.debug("NAT Service : NAPTPacketInHandler Packet for Outbound NAPT Table");
51             byte[] inPayload = packetReceived.getPayload();
52             Ethernet ethPkt = new Ethernet();
53             if (inPayload != null) {
54                 try {
55                     ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NumBitsInAByte);
56                 } catch (Exception e) {
57                     LOG.warn("Failed to decode Packet", e);
58                     return;
59                 }
60                 if (ethPkt.getPayload() instanceof IPv4) {
61                     IPv4 ipPkt = (IPv4) ethPkt.getPayload();
62                     byte[] ipSrc = Ints.toByteArray(ipPkt.getSourceAddress());
63
64                     internalIPAddress = NatUtil.toStringIpAddress(ipSrc, LOG);
65                     LOG.trace("Retrieved internalIPAddress {}", internalIPAddress);
66                     if (ipPkt.getPayload() instanceof TCP) {
67                         TCP tcpPkt = (TCP) ipPkt.getPayload();
68                         portNumber = tcpPkt.getSourcePort();
69                         if(portNumber < 0){
70                             portNumber = 32767 + portNumber + 32767 + 2;
71                             LOG.trace("Retrieved and extracted TCP portNumber {}", portNumber);
72                         }
73                         protocol = NAPTEntryEvent.Protocol.TCP;
74                         LOG.trace("Retrieved TCP portNumber {}", portNumber);
75                     } else if (ipPkt.getPayload() instanceof UDP) {
76                         UDP udpPkt = (UDP) ipPkt.getPayload();
77                         portNumber = udpPkt.getSourcePort();
78                         if(portNumber < 0){
79                             portNumber = 32767 + portNumber + 32767 + 2;
80                             LOG.trace("Retrieved and extracted UDP portNumber {}", portNumber);
81                         }
82                         protocol = NAPTEntryEvent.Protocol.UDP;
83                         LOG.trace("Retrieved UDP portNumber {}", portNumber);
84                     } else {
85                         LOG.error("Incoming Packet is neither TCP or UDP packet");
86                         return;
87                     }
88                 } else {
89                     LOG.error("Incoming Packet is not IPv4 packet");
90                     return;
91                 }
92
93                 if(internalIPAddress != null) {
94                     String sourceIPPortKey = internalIPAddress + ":" + portNumber;
95                     LOG.debug("NAT Service : sourceIPPortKey {} mapping maintained in the map", sourceIPPortKey);
96                     if (!incomingPacketMap.contains(sourceIPPortKey)) {
97                         incomingPacketMap.add(internalIPAddress + portNumber);
98
99                         BigInteger metadata = packetReceived.getMatch().getMetadata().getMetadata();
100                         routerId = (metadata.and(MetaDataUtil.METADATA_MASK_VRFID)).longValue();
101                         if( routerId <= 0) {
102                             LOG.error("Nat Service : Router ID is invalid");
103                             return;
104                         }
105                         //send to Event Queue
106                         NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress,portNumber,routerId,
107                                 operation,protocol);
108                         naptEventdispatcher.addNaptEvent(naptEntryEvent);
109                     } else {
110                         LOG.trace("Ignore the packet, already processed");
111                     }
112                 }else {
113                     LOG.error("Nullpointer exception in retrieving internalIPAddress");
114                 }
115             }
116         }else {
117             LOG.trace("Packet is not from the Outbound NAPT table");
118         }
119     }
120
121     public void removeIncomingPacketMap(String sourceIPPortKey) {
122         incomingPacketMap.remove(sourceIPPortKey);
123         LOG.debug("NAT Service : sourceIPPortKey {} mapping is removed from map", sourceIPPortKey);
124     }
125 }