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
- 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.
- Advantages:
- This approach is very simple for executing and determining the route.
- Prevents deadlock once it utilized within mesh-based networks.
- 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
- Install NS3:
git clone https://gitlab.com/nsnam/ns-3-dev.git
cd ns-3-dev
./ns3 configure –enable-examples –enable-tests
./ns3 build
- Verify Installation: Confirm the installation by executing a simple example script:
./ns3 run examples/tutorial/first
Step 3: Plan the XY Routing Protocol
- 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.
- 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
- 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
- Enable Logging:
export NS_LOG=”XYRouting=level_all|prefix_time”
./ns3 run my-simulation
- 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
- Enhancements:
- For failed links, we can incorporate the failure handling.
- Enhance for dynamic grids or integrate the adaptive aspects.
- 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.
Click Here to watch our latest output video using NS3 simulator
Click Here to watch our latest projects screenshots using NS3 simulator