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

How to Implement OSPF routing in ns3

To implement OSPF (Open Shortest Path First) routing in ns3, we have to create a custom routing protocol class which has similar behavior of OSPF, which incorporates link-state advertisements and Dijkstra’s algorithm for calculating the shortest path.

The built-in implementation of OSPF called OSPF Routing Protocol is already supported by ns3, but for the learning purpose, let’s implement a basic version of OSPF in ns3.

Steps for implementation

  1. Set up your ns3 :
  • Make sure that ns3 is installed in the computer. If not, install it.
  1. Include necessary libraries :
  • In your script, include the necessary libraries.
  1. Define network topology :
  • For your network topology, create the nodes and links.
  1. Install Internet Stack :
  • On your nodes, install the internet stack.
  1. Implement the OSPF Routing Protocol :
  • Create a custom routing protocol class to implement the behavior of OSPF.
  1. Integrate the Custom Routing Protocol :
  • On the ns3 stack, integrate your custom routing protocol.
  1. Set Up Applications :
  • To generate traffic and test the routing, install applications.
  1. Run the Simulation :
  • Define the simulation parameters and run it.

 

Example implementation in C++

 

Here is a complete example on implementing a basic OSPF-like routing protocol in ns3:

Include libraries :

#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/ipv4-routing-protocol.h”

#include “ns3/ipv4-list-routing-helper.h”

#include <map>

#include <vector>

Define network topology

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 devices01 = pointToPoint.Install(nodes.Get(0), nodes.Get(1));

NetDeviceContainer devices12 = pointToPoint.Install(nodes.Get(1), nodes.Get(2));

NetDeviceContainer devices23 = pointToPoint.Install(nodes.Get(2), nodes.Get(3));

NetDeviceContainer devices30 = pointToPoint.Install(nodes.Get(3), nodes.Get(0));

InternetStackHelper stack;

stack.Install(nodes);

Ipv4AddressHelper address;

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

Ipv4InterfaceContainer interfaces01 = address.Assign(devices01);

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

Ipv4InterfaceContainer interfaces12 = address.Assign(devices12);

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

Ipv4InterfaceContainer interfaces23 = address.Assign(devices23);

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

Ipv4InterfaceContainer interfaces30 = address.Assign(devices30);

Implement the OSPF Routing Protocol :

Create a new header file ospf-routing.h :

#ifndef OSPF_ROUTING_H

#define OSPF_ROUTING_H

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

#include “ns3/ipv4.h”

#include “ns3/net-device.h”

#include “ns3/ptr.h”

#include “ns3/socket.h”

#include <map>

#include <vector>

#include <set>

namespace ns3 {

class OspfRouting : public Ipv4RoutingProtocol {

public:

static TypeId GetTypeId(void);

OspfRouting();

virtual ~OspfRouting();

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);

void Start();

private:

void SendLinkStateAdvertisement();

void ReceiveLinkStateAdvertisement(Ptr<Socket> socket);

void CalculateShortestPaths();

void UpdateRoutingTable();

Ptr<Ipv4> m_ipv4;

std::map<Ipv4Address, std::set<Ipv4Address>> m_linkStateDatabase;

std::map<Ipv4Address, Ipv4Address> m_routingTable;

std::map<uint32_t, Ptr<Socket>> m_socketMap;

Time m_updateInterval;

EventId m_updateEvent;

};

}

#endif // OSPF_ROUTING_H

Create the corresponding implementation file ospf-routing.cc:

#include “ospf-routing.h”

#include “ns3/log.h”

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

#include “ns3/simulator.h”

#include “ns3/inet-socket-address.h”

#include “ns3/ipv4-header.h”

namespace ns3 {

NS_LOG_COMPONENT_DEFINE(“OspfRouting”);

NS_OBJECT_ENSURE_REGISTERED(OspfRouting);

TypeId OspfRouting::GetTypeId(void) {

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

.SetParent<Ipv4RoutingProtocol>()

.SetGroupName(“Internet”)

.AddConstructor<OspfRouting>();

return tid;

}

OspfRouting::OspfRouting() : m_updateInterval(Seconds(10)) {

NS_LOG_FUNCTION(this);

Simulator::Schedule(Seconds(1.0), &OspfRouting::Start, this);

}

OspfRouting::~OspfRouting() {

NS_LOG_FUNCTION(this);

}

void OspfRouting::SetIpv4(Ptr<Ipv4> ipv4) {

NS_LOG_FUNCTION(this << ipv4);

m_ipv4 = ipv4;

}

void OspfRouting::Start() {

NS_LOG_FUNCTION(this);

SendLinkStateAdvertisement();

m_updateEvent = Simulator::Schedule(m_updateInterval, &OspfRouting::Start, this);

}

void OspfRouting::SendLinkStateAdvertisement() {

NS_LOG_FUNCTION(this);

Ptr<Packet> packet = Create<Packet>();

for (auto const &entry : m_linkStateDatabase) {

Ipv4Address node = entry.first;

for (auto const &neighbor : entry.second) {

Ipv4Header header;

header.SetSource(node);

header.SetDestination(neighbor);

packet->AddHeader(header);

}

}

for (uint32_t i = 0; i < m_ipv4->GetNInterfaces(); ++i) {

Ptr<Socket> socket = m_socketMap[i];

socket->SendTo(packet, 0, InetSocketAddress(Ipv4Address::GetBroadcast(), 80));

}

}

void OspfRouting::ReceiveLinkStateAdvertisement(Ptr<Socket> socket) {

NS_LOG_FUNCTION(this);

Ptr<Packet> packet = socket->Recv();

Ipv4Header header;

packet->RemoveHeader(header);

Ipv4Address source = header.GetSource();

Ipv4Address dest = header.GetDestination();

m_linkStateDatabase.insert(dest);

CalculateShortestPaths();

}

void OspfRouting::CalculateShortestPaths() {

NS_LOG_FUNCTION(this);

// Implement Dijkstra’s algorithm to calculate shortest paths

// This is a simplified example and may need more details

// for a complete OSPF implementation

std::map<Ipv4Address, uint32_t> distances;

std::map<Ipv4Address, Ipv4Address> previous;

for (auto const &entry : m_linkStateDatabase) {

distances[entry.first] = std::numeric_limits<uint32_t>::max();

}

Ipv4Address source = m_ipv4->GetAddress(1, 0).GetLocal();

distances = 0;

std::set<Ipv4Address> nodes;

for (auto const &entry : m_linkStateDatabase) {

nodes.insert(entry.first);

}

while (!nodes.empty()) {

Ipv4Address u;

uint32_t minDistance = std::numeric_limits<uint32_t>::max();

for (auto const &node : nodes) {

if (distances[node] < minDistance) {

minDistance = distances[node];

u = node;

}

}

nodes.erase(u);

for (auto const &neighbor : m_linkStateDatabase[u]) {

uint32_t alt = distances[u] + 1; // Assuming unit weight for each edge

if (alt < distances[neighbor]) {

distances[neighbor] = alt;

previous[neighbor] = u;

}

}

}

m_routingTable.clear();

for (auto const &entry : previous) {

m_routingTable[entry.first] = entry.second;

}

}

Ptr<Ipv4Route> OspfRouting::RouteOutput(

Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif,

Socket::SocketErrno &sockerr) {

NS_LOG_FUNCTION(this << p << header << oif << sockerr);

Ipv4Address dest = header.GetDestination();

if (m_routingTable.find(dest) == m_routingTable.end()) {

sockerr = Socket::ERROR_NOROUTETOHOST;

return 0;

}

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

route->SetDestination(dest);

route->SetGateway(m_routingTable[dest]);

route->SetOutputDevice(oif);

return route;

}

bool OspfRouting::RouteInput(

Ptr<const Packet> p, const Ipv4Header &header,

Ptr<const NetDevice> idev, UnicastForwardCallback ucb,

MulticastForwardCallback mcb, LocalDeliverCallback lcb,

ErrorCallback ecb) {

NS_LOG_FUNCTION(this << p << header << idev << ucb << mcb

<< lcb << ecb);

Ipv4Address dest = header.GetDestination();

if (dest == m_ipv4->GetAddress(1, 0).GetLocal()) {

lcb(p, header, idev);

return true;

}

if (m_routingTable.find(dest) == m_routingTable.end()) {

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

return false;

}

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

route->SetDestination(dest);

route->SetGateway(m_routingTable[dest]);

route->SetOutputDevice(idev);

ucb(route, p, header);

return true;

}

void OspfRouting::NotifyInterfaceUp(uint32_t interface) {

NS_LOG_FUNCTION(this << interface);

Ptr<Socket> socket = Socket::CreateSocket(GetObject<Node>(), TypeId::LookupByName(“ns3::UdpSocketFactory”));

socket->SetAllowBroadcast(true);

socket->BindToNetDevice(m_ipv4->GetNetDevice(interface));

socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 80));

socket->SetRecvCallback(MakeCallback(&OspfRouting::ReceiveLinkStateAdvertisement, this));

m_socketMap[interface] = socket;

}

void OspfRouting::NotifyInterfaceDown(uint32_t interface) {

NS_LOG_FUNCTION(this << interface);

m_socketMap[interface]->Close();

m_socketMap.erase(interface);

}

void OspfRouting::NotifyAddAddress(uint32_t interface,

Ipv4InterfaceAddress address) {

NS_LOG_FUNCTION(this << interface << address);

}

void OspfRouting::NotifyRemoveAddress(uint32_t interface,

Ipv4InterfaceAddress address) {

NS_LOG_FUNCTION(this << interface << address);

}

}

Integrate the Custom Routing Protocol :

#include “ospf-routing.h”

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 devices01 = pointToPoint.Install(nodes.Get(0), nodes.Get(1));

NetDeviceContainer devices12 = pointToPoint.Install(nodes.Get(1), nodes.Get(2));

NetDeviceContainer devices23 = pointToPoint.Install(nodes.Get(2), nodes.Get(3));

NetDeviceContainer devices30 = pointToPoint.Install(nodes.Get(3), nodes.Get(0));

InternetStackHelper stack;

OspfRoutingHelper ospfRouting;

Ipv4ListRoutingHelper list;

list.Add(ospfRouting, 0);

stack.SetRoutingHelper(list);

stack.Install(nodes);

Ipv4AddressHelper address;

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

address.Assign(devices01);

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

address.Assign(devices12);

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

address.Assign(devices23);

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

address.Assign(devices30);

// Set up applications

uint16_t port = 9;

UdpEchoServerHelper server(port);

ApplicationContainer apps = server.Install(nodes.Get(3));

apps.Start(Seconds(1.0));

apps.Stop(Seconds(10.0));

UdpEchoClientHelper client(address.GetAddress(3), port);

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

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

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

apps = client.Install(nodes.Get(0));

apps.Start(Seconds(2.0));

apps.Stop(Seconds(10.0));

Simulator::Run();

Simulator::Destroy();

return 0;

}

Explanation

  1. Network Topology :

The four nodes connected in a ring, to set up the network topology.

  1. OSPF Routing Protocol :

A custom OSPF-like routing protocol class (OspfRouting) is implemented for handling route computation and distribution on the basis of link-state advertisements and Dijkstra’s algorithm for shortest path calculation.

  1. Route Computation :

To compute the shortest paths based on the link-state database, the CalculateShortestPaths method implemented Dijkstra’s algorithm.

  1. Link State Advertisements :

The SendLinkStateAdvertisement method is used to send the current link-state database to neighbors, and the ReceiveLinkStateAdvertisement method is used to processe incoming link-state advertisements and update the link-state database.

  1. Route Input and Output :

To handle packet routing based on the routing table, the RouteInput and RouteOutput methods are used.

  1. Integrate Custom Routing Protocol :

The custom routing protocol is integrated into the ns3 stack using the OspfRoutingHelper.

  1. Applications :

To set up to test the routing, UdpEchoServer and UdpEchoClient applications are used.

Running the Code :

Save your script to a file, for example, ospf-routing.cc and Compile the script using the ns3 build system

./waf configure –enable-examples

./waf build

./waf –run scratch/ospf-routing

Overall, we had successfully learned on implementing OSPF (Open Shortest Path First) routing in ns3 which incorporates creating a custom routing protocol class that mimics the behavior of OSPF. OSPF (Open Shortest Path First) routing in ns3 is quiet high we grant best results, for your programming.