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

How to Implement Data Center networking in ns3

To implement the Data center Networking (DCN) in ns-3 consists to simulate a network that links to servers, switches and routers that usually found in data centers. This can include numerous topologies such as fat-tree, leaf-spine, or others. Here is the detailed procedure on how to set up a general data center network in ns-3 environment using a fat-tree topology.

Step-by-Step Implementation

  1. Install ns-3

Make sure the ns3 installed on the system. You can download and installed in from official website.

  1. Define the Fat-Tree Topology

A fat-tree topology consists of three layers:

  • Core layer
  • Aggregation layer
  • Edge layer
  1. Create Network Nodes

To generate network nodes using NodeContainer for servers, edge switches, aggregation switches, and core switches.

#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”

using namespace ns3;

NodeContainer coreSwitches, aggSwitches, edgeSwitches, servers;

// Parameters

uint32_t k = 4; // Number of ports per switch (k must be even for fat-tree topology)

uint32_t numPods = k; // Number of pods

uint32_t numCoreSwitches = (k / 2) * (k / 2);

uint32_t numAggSwitches = k * (k / 2);

uint32_t numEdgeSwitches = k * (k / 2);

uint32_t numServers = k * numEdgeSwitches / 2;

// Create nodes

coreSwitches.Create(numCoreSwitches);

aggSwitches.Create(numAggSwitches);

edgeSwitches.Create(numEdgeSwitches);

servers.Create(numServers);

  1. Set Up Point-to-Point Links

Create point-to-point links between the switches and servers.

PointToPointHelper p2p;

p2p.SetDeviceAttribute(“DataRate”, StringValue(“1Gbps”));

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

// Install network devices on core switches

NetDeviceContainer coreDevices;

for (uint32_t i = 0; i < coreSwitches.GetN(); ++i) {

    for (uint32_t j = 0; j < aggSwitches.GetN() / numPods; ++j) {

        NetDeviceContainer link = p2p.Install(NodeContainer(coreSwitches.Get(i), aggSwitches.Get(j + (i / (k / 2)) * (k / 2))));

        coreDevices.Add(link);

    }

}

// Install network devices on aggregation switches

NetDeviceContainer aggDevices;

for (uint32_t i = 0; i < aggSwitches.GetN(); ++i) {

    for (uint32_t j = 0; j < edgeSwitches.GetN() / numPods; ++j) {

        NetDeviceContainer link = p2p.Install(NodeContainer(aggSwitches.Get(i), edgeSwitches.Get(j + (i / (k / 2)) * (k / 2))));

        aggDevices.Add(link);

    }

}

// Install network devices on edge switches

NetDeviceContainer edgeDevices;

for (uint32_t i = 0; i < edgeSwitches.GetN(); ++i) {

    for (uint32_t j = 0; j < numServers / numEdgeSwitches; ++j) {

        NetDeviceContainer link = p2p.Install(NodeContainer(edgeSwitches.Get(i), servers.Get(j + i * (numServers / numEdgeSwitches))));

        edgeDevices.Add(link);

    }

}

  1. Configure Mobility Model

Set up the mobility model for the nodes if necessary. For data center networking, nodes typically do not move.

  1. Set Up Routing Protocols

Configure routing protocols for the network. OSPF or other dynamic routing protocols can be configured, but for simplicity, static routing is demonstrated here.

InternetStackHelper internet;

internet.Install(coreSwitches);

internet.Install(aggSwitches);

internet.Install(edgeSwitches);

internet.Install(servers);

Ipv4AddressHelper address;

Ipv4InterfaceContainer coreInterfaces, aggInterfaces, edgeInterfaces, serverInterfaces;

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

coreInterfaces = address.Assign(coreDevices);

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

aggInterfaces = address.Assign(aggDevices);

 

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

edgeInterfaces = address.Assign(edgeDevices);

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

serverInterfaces = address.Assign(servers);

  1. Implement Data Center Applications

Create applications that simulate data center traffic. Below is an example of a simple application that simulates data transfer between servers.

Server Application

class ServerApplication : public Application {

public:

    void StartApplication() override {

        recvSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());

        recvSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 9));

        recvSocket->Listen();

        recvSocket->SetAcceptCallback(MakeNullCallback<bool, Ptr<Socket>, const Address &>(),

                                      MakeCallback(&ServerApplication::HandleAccept, this));

        recvSocket->SetRecvCallback(MakeCallback(&ServerApplication::HandleRead, this));

    }

    void HandleAccept(Ptr<Socket> socket, const Address& from) {

        socket->SetRecvCallback(MakeCallback(&ServerApplication::HandleRead, this));

    }

 

    void HandleRead(Ptr<Socket> socket) {

        Ptr<Packet> packet;

        while ((packet = socket->Recv())) {

            std::cout << “Server received packet of size ” << packet->GetSize() << ” bytes” << std::endl;

        }

    }

private:

    Ptr<Socket> recvSocket;

};

Client Application

class ClientApplication : public Application {

public:

    void StartApplication() override {

        sendSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());

        InetSocketAddress remote = InetSocketAddress(serverAddress, 9);

        sendSocket->Connect(remote);

        // Schedule the first packet send

        Simulator::Schedule(Seconds(1.0), &ClientApplication::SendPacket, this);

    }

 

    void SetServerAddress(Ipv4Address address) {

        serverAddress = address;

    }

    void SendPacket() {

        Ptr<Packet> packet = Create<Packet>(100); // Create a 100-byte packet

        sendSocket->Send(packet);

        // Schedule the next packet send

        Simulator::Schedule(Seconds(1.0), &ClientApplication::SendPacket, this);

    }

private:

    Ptr<Socket> sendSocket;

    Ipv4Address serverAddress;

};

  1. Install Applications

Install the applications on the nodes.

ApplicationContainer serverApps, clientApps;

// Install server applications on all servers

for (uint32_t i = 0; i < servers.GetN(); ++i) {

    Ptr<ServerApplication> serverApp = CreateObject<ServerApplication>();

    servers.Get(i)->AddApplication(serverApp);

    serverApp->SetStartTime(Seconds(0.0));

    serverApp->SetStopTime(Seconds(20.0));

    serverApps.Add(serverApp);

}

// Install client applications on a subset of servers

for (uint32_t i = 0; i < 5; ++i) {

    Ptr<ClientApplication> clientApp = CreateObject<ClientApplication>();

    clientApp->SetServerAddress(servers.Get((i + 1) % servers.GetN())->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal());

    servers.Get(i)->AddApplication(clientApp);

    clientApp->SetStartTime(Seconds(1.0));

    clientApp->SetStopTime(Seconds(20.0));

    clientApps.Add(clientApp);

}

  1. Run the Simulation

Configure the simulation runtime and execute it.

Simulator::Stop(Seconds(20.0));

Simulator::Run();

Simulator::Destroy();

Complete Example of a Simple Data Center Network Script

Here is the sample script to complete the data centre networks in ns-3 environment that are given below:

#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”

using namespace ns3;

class ServerApplication : public Application {

public:

    void StartApplication() override {

        recvSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());

        recvSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 9));

        recvSocket->Listen();

        recvSocket->SetAcceptCallback(MakeNullCallback<bool, Ptr<Socket>, const Address &>(),

                                      MakeCallback(&ServerApplication::HandleAccept, this));

        recvSocket->SetRecvCallback(MakeCallback(&ServerApplication::HandleRead, this));

    }

 

    void HandleAccept(Ptr<Socket> socket, const Address& from) {

        socket->SetRecvCallback(MakeCallback(&ServerApplication::HandleRead, this));

    }

    void HandleRead(Ptr<Socket> socket) {

        Ptr<Packet> packet;

        while ((packet = socket->Recv())) {

            std::cout << “Server received packet of size ” << packet->GetSize() << ” bytes” << std::endl;

        }

    }

private:

    Ptr<Socket> recvSocket;

};

class ClientApplication : public Application {

public:

    void StartApplication() override {

        sendSocket = Socket::CreateSocket(GetNode(), TcpSocketFactory::GetTypeId());

        InetSocketAddress remote = InetSocketAddress(serverAddress, 9);

        sendSocket->Connect(remote);

        // Schedule the first packet send

        Simulator::Schedule(Seconds(1.0), &ClientApplication::SendPacket, this);

    }

    void SetServerAddress(Ipv4Address address) {

        serverAddress = address;

    }

    void SendPacket() {

        Ptr<Packet> packet = Create<Packet>(100); // Create a 100-byte packet

        sendSocket->Send(packet);

        // Schedule the next packet send

        Simulator::Schedule(Seconds(1.0), &ClientApplication::SendPacket, this);

    }

private:

    Ptr<Socket> sendSocket;

    Ipv4Address serverAddress;

};

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

    NodeContainer coreSwitches, aggSwitches, edgeSwitches, servers;

    uint32_t k = 4; // Number of ports per switch (k must be even for fat-tree topology)

    uint32_t numPods = k; // Number of pods

    uint32_t numCoreSwitches = (k / 2) * (k / 2);

    uint32_t numAggSwitches = k * (k / 2);

    uint32_t numEdgeSwitches = k * (k / 2);

    uint32_t numServers = k * numEdgeSwitches / 2;

    coreSwitches.Create(numCoreSwitches);

    aggSwitches.Create(numAggSwitches);

    edgeSwitches.Create(numEdgeSwitches);

    servers.Create(numServers);

    PointToPointHelper p2p;

    p2p.SetDeviceAttribute(“DataRate”, StringValue(“1Gbps”));

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

    NetDeviceContainer coreDevices, aggDevices, edgeDevices;

    for (uint32_t i = 0; i < coreSwitches.GetN(); ++i) {

        for (uint32_t j = 0; j < aggSwitches.GetN() / numPods; ++j) {

            NetDeviceContainer link = p2p.Install(NodeContainer(coreSwitches.Get(i), aggSwitches.Get(j + (i / (k / 2)) * (k / 2))));

            coreDevices.Add(link);

        }

    }

    for (uint32_t i = 0; i < aggSwitches.GetN(); ++i) {

        for (uint32_t j = 0; j < edgeSwitches.GetN() / numPods; ++j) {

            NetDeviceContainer link = p2p.Install(NodeContainer(aggSwitches.Get(i), edgeSwitches.Get(j + (i / (k / 2)) * (k / 2))));

            aggDevices.Add(link);

        }

    }

    for (uint32_t i = 0; i < edgeSwitches.GetN(); ++i) {

        for (uint32_t j = 0; j < numServers / numEdgeSwitches; ++j) {

            NetDeviceContainer link = p2p.Install(NodeContainer(edgeSwitches.Get(i), servers.Get(j + i * (numServers / numEdgeSwitches))));

            edgeDevices.Add(link);

        }

    }

    InternetStackHelper internet;

    internet.Install(coreSwitches);

    internet.Install(aggSwitches);

    internet.Install(edgeSwitches);

    internet.Install(servers);

    Ipv4AddressHelper address;

    Ipv4InterfaceContainer coreInterfaces, aggInterfaces, edgeInterfaces, serverInterfaces;

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

    coreInterfaces = address.Assign(coreDevices);

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

    aggInterfaces = address.Assign(aggDevices);

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

    edgeInterfaces = address.Assign(edgeDevices);

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

    serverInterfaces = address.Assign(servers);

    ApplicationContainer serverApps, clientApps;

    for (uint32_t i = 0; i < servers.GetN(); ++i) {

        Ptr<ServerApplication> serverApp = CreateObject<ServerApplication>();

        servers.Get(i)->AddApplication(serverApp);

        serverApp->SetStartTime(Seconds(0.0));

        serverApp->SetStopTime(Seconds(20.0));

        serverApps.Add(serverApp);

    }

    for (uint32_t i = 0; i < 5; ++i) {

        Ptr<ClientApplication> clientApp = CreateObject<ClientApplication>();

        clientApp->SetServerAddress(servers.Get((i + 1) % servers.GetN())->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal());

        servers.Get(i)->AddApplication(clientApp);

        clientApp->SetStartTime(Seconds(1.0));

        clientApp->SetStopTime(Seconds(20.0));

        clientApps.Add(clientApp);

    }

    Simulator::Stop(Seconds(20.0));

    Simulator::Run();

    Simulator::Destroy();

    return 0;

}

 

As a final point, we discussed about how to implement and process the Data Center network in ns-3 environment clearly. We also provide all kinds of Data Center network that adjust in various environments. Even after reading the above ideas if you find difficulty in Implementing Data Center networking in ns3 then you can contact us.