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.