How to Begin Implement XY Routing in NS3

To implement XY Routing using NS3 which is a simple and deterministic routing mechanism that frequently leveraged within network-on-chip (NoC) systems and mesh topologies. The algorithm functions with initial transmitting the packets through X-dimension (horizontal direction) and then sending through the Y-dimension (vertical direction) while waiting for the destination is attained. It is mainly designed for grid or mesh networks.

We can follow numerous steps to implement XY Routing using NS3:

Steps to Begin Implement XY Routing in NS3

Step 1: Understand XY Routing

  1. Key Concepts:
    • Deterministic Routing: Constantly selects the similar path for provided source and destination.
    • Routing Rules:
      • Transmit the packets initially through X-axis (horizontal direction).
      • When the X-coordinate equals the destination then the send through the Y-axis (vertical direction).
    • It successfully functions for 2D grid/mesh topologies.
  2. Advantages:
    • This approach is very simple for executing and determining the route.
    • Prevents deadlock once it utilized within mesh-based networks.
  3. Topology Requirement:
    • Make sure that the network is organized like a 2D grid or mesh to successfully function for XY routing.

Step 2: Set Up NS3

  1. Install NS3:

git clone https://gitlab.com/nsnam/ns-3-dev.git

cd ns-3-dev

./ns3 configure –enable-examples –enable-tests

./ns3 build

  1. Verify Installation: Confirm the installation by executing a simple example script:

./ns3 run examples/tutorial/first

Step 3: Plan the XY Routing Protocol

  1. Core Components:
    • Node Coordinates: Allocate the coordinates of X and Y to every single node within the grid.
    • XY Routing Algorithm: Execute the routing algorithm for computing the next hop according to the present and destination coordinates.
    • Packet Forwarding: Transmit the packets with the support of computed next hop.
  2. Workflow:
    • Find out the coordinates of present node.
    • Extort the terminus node’s coordinates.
    • Transmit at the side of the X-axis while waiting for the X-coordinates equalize.
    • It sends through Y-axis awaiting its equal for Y-coordinates.

Step 4: Implement XY Routing

Step 4.1: Define the Protocol Class

To execute the XY routing, we need to prolong the Ipv4RoutingProtocol class:

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

#include “ns3/socket.h”

#include <map>

#include <utility>

using namespace ns3;

class XYRouting : public Ipv4RoutingProtocol {

public:

static TypeId GetTypeId(void);

XYRouting();

virtual ~XYRouting();

virtual Ptr<Ipv4Route> RouteOutput(Ptr<Packet> packet, const Ipv4Header &header,

Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) override;

virtual bool RouteInput(Ptr<const Packet> packet, const Ipv4Header &header,

Ptr<const NetDevice> idev, UnicastForwardCallback ucb,

MulticastForwardCallback mcb, LocalDeliverCallback lcb,

ErrorCallback ecb) override;

void SetNodeCoordinates(Ipv4Address address, std::pair<int, int> coordinates);

void SetGridSize(int width, int height);

private:

std::map<Ipv4Address, std::pair<int, int>> m_coordinates; // Node -> (X, Y)

int m_width;

int m_height;

Ipv4Address GetNextHop(Ipv4Address current, Ipv4Address destination);

};

Step 4.2: Implement Core Functions

  • Set Node Coordinates: In the grid, allocate the coordinates to every single node.

void XYRouting::SetNodeCoordinates(Ipv4Address address, std::pair<int, int> coordinates) {

m_coordinates[address] = coordinates;

}

void XYRouting::SetGridSize(int width, int height) {

m_width = width;

m_height = height;

}

  • Next Hop Computation: Depends on the XY routing rules, we can compute the next hop.

Ipv4Address XYRouting::GetNextHop(Ipv4Address current, Ipv4Address destination) {

auto currentCoord = m_coordinates[current];

auto destCoord = m_coordinates[destination];

if (currentCoord.first < destCoord.first) {

// Route along the X-axis to the right

for (const auto &entry : m_coordinates) {

if (entry.second == std::make_pair(currentCoord.first + 1, currentCoord.second)) {

return entry.first;

}

}

} else if (currentCoord.first > destCoord.first) {

// Route along the X-axis to the left

for (const auto &entry : m_coordinates) {

if (entry.second == std::make_pair(currentCoord.first – 1, currentCoord.second)) {

return entry.first;

}

}

} else if (currentCoord.second < destCoord.second) {

// Route along the Y-axis upward

for (const auto &entry : m_coordinates) {

if (entry.second == std::make_pair(currentCoord.first, currentCoord.second + 1)) {

return entry.first;

}

}

} else if (currentCoord.second > destCoord.second) {

// Route along the Y-axis downward

for (const auto &entry : m_coordinates) {

if (entry.second == std::make_pair(currentCoord.first, currentCoord.second – 1)) {

return entry.first;

}

}

}

return Ipv4Address(); // No valid next hop found

}

  • Route Output: Find the route applying XY routing mechanisms for outgoing packets.

Ptr<Ipv4Route> XYRouting::RouteOutput(Ptr<Packet> packet, const Ipv4Header &header,

Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) {

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

Ipv4Address nextHop = GetNextHop(header.GetSource(), header.GetDestination());

if (nextHop.IsBroadcast() || nextHop.IsAny()) {

sockerr = Socket::ERROR_NOROUTETOHOST;

return nullptr;

}

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

route->SetGateway(nextHop);

route->SetOutputDevice(oif);

return route;

}

  • Route Input: Transmit the packets according to the XY routing rules.

bool XYRouting::RouteInput(Ptr<const Packet> packet, const Ipv4Header &header,

Ptr<const NetDevice> idev, UnicastForwardCallback ucb,

MulticastForwardCallback mcb, LocalDeliverCallback lcb,

ErrorCallback ecb) {

if (header.GetDestination() == GetNode()->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal()) {

lcb(packet, header, idev); // Deliver locally

return true;

}

Ipv4Address nextHop = GetNextHop(header.GetSource(), header.GetDestination());

if (!nextHop.IsBroadcast() && !nextHop.IsAny()) {

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

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

route->SetGateway(nextHop);

ucb(route, packet, header);

return true;

}

return false;

}

Step 5: Register the Protocol

Create an available protocol using TypeId system in NS3:

TypeId XYRouting::GetTypeId(void) {

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

.SetParent<Ipv4RoutingProtocol>()

.SetGroupName(“Internet”)

.AddConstructor<XYRouting>();

return tid;

}

Step 6: Integrate into a Simulation

  1. Simulation Script Example:

#include “ns3/internet-stack-helper.h”

#include “ns3/xy-routing.h”

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

NodeContainer nodes;

nodes.Create(9); // 3×3 grid

// Define grid topology (3×3)

int gridWidth = 3;

int gridHeight = 3;

Ptr<XYRouting> xyRouting = CreateObject<XYRouting>();

xyRouting->SetGridSize(gridWidth, gridHeight);

for (int i = 0; i < gridWidth; ++i) {

for (int j = 0; j < gridHeight; ++j) {

int nodeIndex = i * gridHeight + j;

xyRouting->SetNodeCoordinates(nodes.Get(nodeIndex)->GetObject<Ipv4>()->GetAddress(1, 0), {i, j});

}

}

InternetStackHelper stack;

stack.SetRoutingHelper(xyRouting);

stack.Install(nodes);

Simulator::Run();

Simulator::Destroy();

return 0;

}

Step 7: Test and Debug

  1. Enable Logging:

export NS_LOG=”XYRouting=level_all|prefix_time”

./ns3 run my-simulation

  1. Verify Results:
    • Make sure that packets adhere to the XY routing logic.
    • Confirm the performance of outcomes versus a 2D grid topology.

Step 8: Extend and Optimize

  1. Enhancements:
    • For failed links, we can incorporate the failure handling.
    • Enhance for dynamic grids or integrate the adaptive aspects.
  2. Performance Testing:
    • Analyze the performance of XY routing within larger grid networks.
    • Probe packet delivery and effectiveness of route.

We have outlined a step-by-step process along with example coding to execute and examine the XY Routing using NS3 environment. We are prepared to delve deeper into advanced concepts if needed.