A Discrete-Event Network Simulator
API
gtp-tunnel-app.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 University of Campinas (Unicamp)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Luciano Jerez Chaves <ljerezchaves@gmail.com>
18  */
19 
20 #include "gtp-tunnel-app.h"
21 
22 #include <ns3/epc-gtpu-header.h>
23 #include <ns3/tunnel-id-tag.h>
24 
25 namespace ns3
26 {
27 
28 NS_LOG_COMPONENT_DEFINE("GtpTunnelApp");
29 NS_OBJECT_ENSURE_REGISTERED(GtpTunnelApp);
30 
32 {
33  NS_LOG_FUNCTION(this << logicalPort << physicalDev);
34 
35  // Save the pointers and set the send callback.
36  m_logicalPort = logicalPort;
38  m_physicalDev = physicalDev;
39 }
40 
42 {
43  NS_LOG_FUNCTION(this);
44 }
45 
46 TypeId
48 {
49  static TypeId tid =
50  TypeId("ns3::GtpTunnelApp").SetParent<Application>().SetGroupName("OFSwitch13");
51  return tid;
52 }
53 
54 bool
56  const Address& source,
57  const Address& dest,
58  uint16_t protocolNo)
59 {
60  NS_LOG_FUNCTION(this << packet << source << dest << protocolNo);
61 
62  // Remove the TunnelId tag with TEID value and destination address.
63  TunnelIdTag tunnelIdTag;
64  bool foud = packet->RemovePacketTag(tunnelIdTag);
65  NS_ASSERT_MSG(foud, "Expected TunnelId tag not found.");
66 
67  // We expect that the destination address will be available in the 32 MSB of
68  // tunnelId, while the TEID will be available in the 32 LSB of tunnelId.
69  uint64_t tagValue = tunnelIdTag.GetTunnelId();
70  uint32_t teid = tagValue;
71  Ipv4Address ipv4Addr(tagValue >> 32);
72  InetSocketAddress inetAddr(ipv4Addr, m_port);
73 
74  // Add the GTP header.
75  GtpuHeader gtpu;
76  gtpu.SetTeid(teid);
77  gtpu.SetLength(packet->GetSize() + gtpu.GetSerializedSize() - 8);
78  packet->AddHeader(gtpu);
79 
80  NS_LOG_DEBUG("Send packet " << packet->GetUid() << " to tunnel with TEID " << teid << " IP "
81  << ipv4Addr << " port " << m_port);
82 
83  // Send the packet to the tunnel socket.
84  int bytes = m_tunnelSocket->SendTo(packet, 0, inetAddr);
85  if (bytes != static_cast<int>(packet->GetSize()))
86  {
87  NS_LOG_ERROR("Not all bytes were copied to the socket buffer.");
88  return false;
89  }
90  return true;
91 }
92 
93 void
95 {
96  NS_LOG_FUNCTION(this << socket);
97 
98  NS_ASSERT(socket == m_tunnelSocket);
99  Ptr<Packet> packet = socket->Recv();
100 
101  // Remove the GTP header.
102  GtpuHeader gtpu;
103  packet->RemoveHeader(gtpu);
104  NS_LOG_DEBUG("Received packet " << packet->GetUid() << " from tunnel with TEID "
105  << gtpu.GetTeid());
106 
107  // Attach the TunnelId tag with TEID value.
108  TunnelIdTag tunnelIdTag(gtpu.GetTeid());
109  packet->ReplacePacketTag(tunnelIdTag);
110 
111  // Add the Ethernet header to the packet, using the physical device MAC
112  // address as source. Note that the original Ethernet frame was removed by
113  // the physical device when this packet arrived at this node, so here we
114  // don't now the original MAC source and destination addresses. The
115  // destination address must be set to the packet by the OpenFlow pipeline,
116  // and the source address we set here using the physical device.
117  AddHeader(packet, Mac48Address::ConvertFrom(m_physicalDev->GetAddress()));
118 
119  // Send the packet to the OpenFlow switch over the logical port.
120  // Don't worry about source and destination addresses becasu they are note
121  // used by the receive method.
122  m_logicalPort->Receive(packet,
124  Mac48Address(),
125  Mac48Address(),
127 }
128 
129 void
131 {
132  NS_LOG_FUNCTION(this);
133 
134  m_tunnelSocket = nullptr;
135  m_logicalPort = nullptr;
136  m_physicalDev = nullptr;
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION(this);
143 
144  // Get the physical device address to bind the UDP socket.
145  Ptr<Node> node = m_physicalDev->GetNode();
146  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
147  int32_t idx = ipv4->GetInterfaceForDevice(m_physicalDev);
148  Ipv4Address ipv4Addr = ipv4->GetAddress(idx, 0).GetLocal();
149 
150  // Create and open the UDP socket for tunnel.
151  m_tunnelSocket = Socket::CreateSocket(GetNode(), TypeId::LookupByName("ns3::UdpSocketFactory"));
155 }
156 
157 void
159  Mac48Address source,
160  Mac48Address dest,
161  uint16_t protocolNo)
162 {
163  NS_LOG_FUNCTION(this << packet << source << dest << protocolNo);
164 
165  // All Ethernet frames must carry a minimum payload of 46 bytes. We need to
166  // pad out if we don't have enough bytes. These must be real bytes since they
167  // will be written to pcap files and compared in regression trace files.
168  if (packet->GetSize() < 46)
169  {
170  uint8_t buffer[46];
171  memset(buffer, 0, 46);
172  Ptr<Packet> padd = Create<Packet>(buffer, 46 - packet->GetSize());
173  packet->AddAtEnd(padd);
174  }
175 
176  EthernetHeader header(false);
177  header.SetSource(source);
178  header.SetDestination(dest);
179  header.SetLengthType(protocolNo);
180  packet->AddHeader(header);
181 
182  EthernetTrailer trailer;
183  if (Node::ChecksumEnabled())
184  {
185  trailer.EnableFcs(true);
186  }
187  trailer.CalcFcs(packet);
188  packet->AddTrailer(trailer);
189 }
190 
191 } // namespace ns3
a polymophic address class
Definition: address.h:100
The base class for all ns3 applications.
Definition: application.h:61
Ptr< Node > GetNode() const
Definition: application.cc:107
Packet header for Ethernet.
void SetDestination(Mac48Address destination)
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
Packet trailer for Ethernet.
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
bool RecvFromLogicalPort(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNo)
Method to be assigned to the send callback of the VirtualNetDevice implementing the OpenFlow logical ...
void RecvFromTunnelSocket(Ptr< Socket > socket)
Method to be assigned to the receive callback of the UDP tunnel socket.
static TypeId GetTypeId()
Register this type.
void StartApplication() override
Application specific startup code.
Ptr< CsmaNetDevice > m_physicalDev
Node physical network device.
void DoDispose() override
Destructor implementation.
Ptr< VirtualNetDevice > m_logicalPort
OpenFlow logical port device.
GtpTunnelApp(Ptr< VirtualNetDevice > logicalPort, Ptr< CsmaNetDevice > physicalDev)
Complete constructor.
Ptr< Socket > m_tunnelSocket
UDP tunnel socket.
void AddHeader(Ptr< Packet > packet, Mac48Address source=Mac48Address(), Mac48Address dest=Mac48Address(), uint16_t protocolNo=Ipv4L3Protocol::PROT_NUMBER)
Adds the necessary Ethernet headers and trailers to a packet of data.
~GtpTunnelApp() override
Dummy destructor, see DoDispose.
const uint16_t m_port
GTP tunnel port.
Implementation of the GPRS Tunnelling Protocol header according to GTPv1-U Release 10 as per 3Gpp TS ...
void SetTeid(uint32_t teid)
Set TEID function.
uint32_t GetSerializedSize() const override
uint32_t GetTeid() const
Get a tunnel endpoint identificator (TEID)
void SetLength(uint16_t length)
Set the length in octets of the payload.
an Inet address class
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
static bool ChecksumEnabled()
Definition: node.cc:290
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:324
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:994
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:126
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:325
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
Tag used to hold the tunnel metadata information (tunnel ID) when sending/receiving a packet to/from ...
Definition: tunnel-id-tag.h:36
uint64_t GetTunnelId() const
a unique identifier for an interface.
Definition: type-id.h:60
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:839
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
bool Receive(Ptr< Packet > packet, uint16_t protocol, const Address &source, const Address &destination, PacketType packetType)
void SetSendCallback(SendCallback transmitCb)
Set the user callback to be called when a L2 packet is to be transmitted.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707