Ns3 Projects for B.E/B.Tech M.E/M.Tech PhD Scholars.  Phone-Number:9790238391   E-mail: ns3simulation@gmail.com

How to Implement MPLS protocol in ns3

To implement MPLS (Multiprotocol Label Switching) in ns3, we need to create a custom module as ns3 does not natively support MPLS. But you can incorporate the behaviour of MPLS by simulating label switching that manipulates packet. Here are the steps to implement a basic MPLS-like functionality in ns3.

Steps for implementing MPLS in ns3

  1. Set up your environment

Make sure that ns3 is installed in the computer. If not, install it from the official ns3 website.

  1. Create a new ns3 script

On your ns3 installation, create a new simulation script in the scratch directory. For example, create a file named mpls-simulation.cc.

cd ns-3.xx

cd scratch

touch mpls-simulation.cc

  1. Include necessary headers

Include the necessary headers on the mpls-simulation.cc for your simulation.

#include “ns3/core-module.h”

#include “ns3/network-module.h”

#include “ns3/internet-module.h”

#include “ns3/point-to-point-module.h”

#include “ns3/applications-module.h”

#include “ns3/mpls-module.h”

using namespace ns3;

 

  1. Create MPLS header

To attach labels to packets, create a custom MPLS header. Create a new directory named mpls in the src directory and then create the header file mpls-header.h.

#ifndef MPLS_HEADER_H

#define MPLS_HEADER_H

#include “ns3/header.h”

namespace ns3 {

class MplsHeader : public Header

{

public:

  MplsHeader ();

  virtual ~MplsHeader ();

  void SetLabel (uint32_t label);

  uint32_t GetLabel () const;

  static TypeId GetTypeId (void);

  virtual TypeId GetInstanceTypeId () const;

  virtual void Print (std::ostream &os) const;

  virtual void Serialize (Buffer::Iterator start) const;

  virtual uint32_t Deserialize (Buffer::Iterator start);

  virtual uint32_t GetSerializedSize () const;

private:

  uint32_t m_label;

};

} // namespace ns3

#endif /* MPLS_HEADER_H */

Create the source file mpls-header.cc in the same directory.

#include “mpls-header.h”

#include “ns3/address-utils.h”

#include “ns3/packet.h”

namespace ns3 {

NS_OBJECT_ENSURE_REGISTERED (MplsHeader);

MplsHeader::MplsHeader ()

  : m_label (0)

{

}

MplsHeader::~MplsHeader ()

{

}

TypeId

MplsHeader::GetTypeId (void)

{

  static TypeId tid = TypeId (“ns3::MplsHeader”)

    .SetParent<Header> ()

    .SetGroupName(“Mpls”)

    .AddConstructor<MplsHeader> ();

  return tid;

}

TypeId

MplsHeader::GetInstanceTypeId () const

{

  return GetTypeId ();

}

void

MplsHeader::SetLabel (uint32_t label)

{

  m_label = label;

}

uint32_t

MplsHeader::GetLabel () const

{

  return m_label;

}

void

MplsHeader::Print (std::ostream &os) const

{

  os << “Label: ” << m_label;

}

void

MplsHeader::Serialize (Buffer::Iterator start) const

{

  start.WriteHtonU32 (m_label);

}

uint32_t

MplsHeader::Deserialize (Buffer::Iterator start)

{

  m_label = start.ReadNtohU32 ();

  return GetSerializedSize ();

}

uint32_t

MplsHeader::GetSerializedSize () const

{

  return 4; // 4 bytes for the label

}

} // namespace ns3

  1. Define MPLS Forwarding

In the mpls directory, create the MPLS forwarding logic. Create the header file mpls-forwarding.h.

#ifndef MPLS_FORWARDING_H

#define MPLS_FORWARDING_H

#include “ns3/ipv4-routing-protocol.h”

#include “ns3/ipv4-address.h”

#include “ns3/node.h”

#include “ns3/net-device.h”

#include “ns3/ipv4-header.h”

#include “ns3/ipv4-routing-table-entry.h”

#include “mpls-header.h”

namespace ns3 {

class MplsForwarding : public Ipv4RoutingProtocol

{

public:

  static TypeId GetTypeId (void);

  MplsForwarding ();

  virtual ~MplsForwarding ();

  void AddRoute (uint32_t label, Ipv4Address nextHop, uint32_t interface);

  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);

  virtual bool RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,

                           UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb);

  virtual void NotifyInterfaceUp (uint32_t interface);

  virtual void NotifyInterfaceDown (uint32_t interface);

  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);

  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);

  virtual void SetIpv4 (Ptr<Ipv4> ipv4);

private:

  Ptr<Ipv4> m_ipv4;

  std::map<uint32_t, Ipv4RoutingTableEntry> m_forwardingTable;

  void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;

};

} // namespace ns3

#endif /* MPLS_FORWARDING_H */

Create the source file mpls-forwarding.cc in the same directory.

#include “mpls-forwarding.h”

#include “ns3/log.h”

#include “ns3/ipv4-route.h”

#include “ns3/simulator.h”

namespace ns3 {

NS_LOG_COMPONENT_DEFINE (“MplsForwarding”);

NS_OBJECT_ENSURE_REGISTERED (MplsForwarding);

TypeId

MplsForwarding::GetTypeId (void)

{

  static TypeId tid = TypeId (“ns3::MplsForwarding”)

    .SetParent<Ipv4RoutingProtocol> ()

    .SetGroupName(“Mpls”)

    .AddConstructor<MplsForwarding> ();

  return tid;

}

MplsForwarding::MplsForwarding ()

{

}

MplsForwarding::~MplsForwarding ()

{

}

void

MplsForwarding::SetIpv4 (Ptr<Ipv4> ipv4)

{

  m_ipv4 = ipv4;

}

void

MplsForwarding::AddRoute (uint32_t label, Ipv4Address nextHop, uint32_t interface)

{

  Ipv4RoutingTableEntry entry (Ipv4Address (), Ipv4Mask (), nextHop, interface);

  m_forwardingTable[label] = entry;

}

Ptr<Ipv4Route>

MplsForwarding::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)

{

  // For simplicity, just pass the packet to the next hop based on the label

  MplsHeader mplsHeader;

  p->PeekHeader (mplsHeader);

  uint32_t label = mplsHeader.GetLabel ();

  auto it = m_forwardingTable.find (label);

  if (it != m_forwardingTable.end ())

    {

      Ipv4RoutingTableEntry entry = it->second;

      Ptr<Ipv4Route> route = Create<Ipv4Route> ();

      route->SetDestination (header.GetDestination ());

      route->SetGateway (entry.GetGateway ());

      route->SetOutputDevice (m_ipv4->GetNetDevice (entry.GetInterface ()));

      return route;

    }

  sockerr = Socket::ERROR_NOROUTETOHOST;

  return nullptr;

}

bool

MplsForwarding::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,

                            UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)

{

  // Handle the incoming packet with MPLS label

  MplsHeader mplsHeader;

  p->PeekHeader (mplsHeader);

  uint32_t label = mplsHeader.GetLabel ();

  auto it = m_forwardingTable.find (label);

  if (it != m_forwardingTable.end ())

    {

      Ipv4RoutingTableEntry entry = it->second;

      Ptr<Ipv4Route> route = Create<Ipv4Route> ();

      route->SetDestination (header.GetDestination ());

      route->SetGateway (entry.GetGateway ());

      route->SetOutputDevice (m_ipv4->GetNetDevice (entry.GetInterface ()));

      ucb (route, p, header);

      return true;

    }

  ecb (p, header, Socket::ERROR_NOROUTETOHOST);

  return false;

}

void

MplsForwarding::NotifyInterfaceUp (uint32_t interface)

{

}

void

MplsForwarding::NotifyInterfaceDown (uint32_t interface)

{

}

void

MplsForwarding::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)

{

}

void

MplsForwarding::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)

{

}

void

MplsForwarding::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const

{

  *stream->GetStream () << “MPLS Forwarding Table” << std::endl;

  for (auto it = m_forwardingTable.begin (); it != m_forwardingTable.end (); ++it)

    {

      *stream->GetStream () << “Label: ” << it->first << ” -> ” << it->second.GetGateway () << ” via ” << it->second.GetInterface () << std::endl;

    }

}

} // namespace ns3

 

 

  1. Integrate MPLS Forwarding into ns-3 Simulation

Now by using the MPLS forwarding module, create a simulation script. Create the script mpls-simulation.cc in the scratch directory.

#include “ns3/core-module.h”

#include “ns3/network-module.h”

#include “ns3/internet-module.h”

#include “ns3/point-to-point-module.h”

#include “ns3/applications-module.h”

#include “mpls-forwarding.h”

using namespace ns3;

int main (int argc, char *argv[])

{

  CommandLine cmd;

  cmd.Parse (argc, argv);

  NodeContainer nodes;

  nodes.Create (4);

  PointToPointHelper pointToPoint;

  pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));

  pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));

  NetDeviceContainer devices;

  devices = pointToPoint.Install (nodes.Get(0), nodes.Get(1));

  devices.Add (pointToPoint.Install (nodes.Get(1), nodes.Get(2)));

  devices.Add (pointToPoint.Install (nodes.Get(2), nodes.Get(3)));

  InternetStackHelper stack;

  stack.Install (nodes);

  Ipv4AddressHelper address;

  address.SetBase (“10.1.1.0”, “255.255.255.0”);

  Ipv4InterfaceContainer interfaces = address.Assign (devices);

  Ptr<MplsForwarding> mpls1 = CreateObject<MplsForwarding> ();

  Ptr<MplsForwarding> mpls2 = CreateObject<MplsForwarding> ();

  mpls1->AddRoute (1, Ipv4Address (“10.1.1.2”), 1);

  mpls1->AddRoute (2, Ipv4Address (“10.1.1.2”), 2);

  mpls2->AddRoute (1, Ipv4Address (“10.1.1.3”), 1);

  mpls2->AddRoute (2, Ipv4Address (“10.1.1.3”), 2);

  nodes.Get (1)->AggregateObject (mpls1);

  nodes.Get (2)->AggregateObject (mpls2);

  // Set up applications (e.g., a UDP echo server and client)

  UdpEchoServerHelper echoServer (9);

  ApplicationContainer serverApps = echoServer.Install (nodes.Get (3));

  serverApps.Start (Seconds (1.0));

  serverApps.Stop (Seconds (10.0));

  UdpEchoClientHelper echoClient (interfaces.GetAddress (3), 9);

  echoClient.SetAttribute (“MaxPackets”, UintegerValue (1));

  echoClient.SetAttribute (“Interval”, TimeValue (Seconds (1.0)));

  echoClient.SetAttribute (“PacketSize”, UintegerValue (1024));

  ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));

  clientApps.Start (Seconds (2.0));

  clientApps.Stop (Seconds (10.0));

  // Enable tracing

  AsciiTraceHelper ascii;

  pointToPoint.EnableAsciiAll (ascii.CreateFileStream (“mpls-simulation.tr”));

  pointToPoint.EnablePcapAll (“mpls-simulation”);

  // Run the simulation

  Simulator::Run ();

  Simulator::Destroy ();

  return 0;

}

  1. Update CMakeList.txt

In the ns3 build system, add a new MPLS module. Edit src/CMakeLists.txt and add the following line:

add_subdirectory (mpls)

Create src/mpls/CMakeLists.txt with the following content:

ns3_add_library (mpls

    model/mpls-header.cc

    model/mpls-forwarding.cc

)

target_link_libraries (mpls)

  1. Build and run the simulation

Build and run your script after writing.

./waf build

./waf –run scratch/mpls-simulation

Overall, we had successfully analyzed our implementation results which incorporates the behavior of MPLS by manipulating packets and routing in a way that simulates label switching.

Also, we offer more related information on MPLS protocol. We work on all projects related to MPLS protocol in ns3