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

How to Implement Spanning Tree Protocol in ns3

To implement the Spanning Tree Protocol (STP) in ns3, we have to incorporate several steps by creating a simulation which builds a loop-free logical topology for a network. STP is a link layer protocol that check for a loop-free topology for any bridged Ethernet local area network. Below is a complete guide on implementing STP in ns3.

Step-by-step guide on implementing STP in ns3

  1. Set up your ns3 :
  • Make sure that ns3 is installed in the computer. If not, install it.

 

  1. Create a New Module for STP:
  • Go to the src directory in ns3 and create a new directory named stp. Create subdirectories named model, helper, and examples, inside the src directory.

 

  1. Define the STP protocol:
  • create .cc and .h files for the STP protocol in the model directory. Define the StpProtocol class that simulates the behavior of STP.

 

  1. Implement the STP class:
  • Implement the key components of STP such as Bridge Protocol Data Units (BPDU), Root Bridge election, Port Roles (Root Port, Designated Port, and Blocked Port), and the STP state machine. For the BPDU messages and the logic to process these messages, create classes.

 

  1. Integrate the STP with ns3 ethernet system:
  • Create a custom bridge device or modify the NetDevice class to handle STP logic.

 

  1. Create simulation script:
  • Set up a network topology.
  • Install the Internet stack.
  • Use the STP helper to enable STP.
  • Set up applications and run the simulation.

Example Code Structure

Below is the example code structure for the implementation of STP in ns3.

Define STP Protocol

// src/stp/model/stp-protocol.h

#ifndef STP_PROTOCOL_H

#define STP_PROTOCOL_H

#include “ns3/packet.h”

#include “ns3/net-device.h”

#include “ns3/timer.h”

#include <vector>

#include <map>

namespace ns3 {

class StpProtocol : public Object

{

public:

static TypeId GetTypeId (void);

StpProtocol ();

virtual ~StpProtocol ();

void Install (Ptr<NetDevice> device);

void ReceiveBpdu (Ptr<Packet> packet, Ptr<NetDevice> device);

private:

void Start ();

void Stop ();

void SendBpdu ();

void HandleBpdu (Ptr<Packet> packet, Ptr<NetDevice> device);

void ElectRootBridge ();

void UpdatePortRoles ();

Ptr<NetDevice> m_device;

Timer m_timer;

bool m_isRootBridge;

uint32_t m_rootBridgeId;

uint32_t m_bridgeId;

std::map<Ptr<NetDevice>, uint32_t> m_portRoles; // Root, Designated, Blocked

};

} // namespace ns3

#endif // STP_PROTOCOL_H

Implement STP Protocol

// src/stp/model/stp-protocol.cc

#include “stp-protocol.h”

#include “ns3/log.h”

#include “ns3/simulator.h”

#include “ns3/packet.h”

namespace ns3 {

NS_LOG_COMPONENT_DEFINE (“StpProtocol”);

NS_OBJECT_ENSURE_REGISTERED (StpProtocol);

TypeId

StpProtocol::GetTypeId (void)

{

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

.SetParent<Object> ()

.SetGroupName (“Network”)

.AddConstructor<StpProtocol> ();

return tid;

}

StpProtocol::StpProtocol ()

{

NS_LOG_FUNCTION (this);

}

StpProtocol::~StpProtocol ()

{

NS_LOG_FUNCTION (this);

}

void

StpProtocol::Install (Ptr<NetDevice> device)

{

NS_LOG_FUNCTION (this << device);

m_device = device;

m_bridgeId = device->GetNode ()->GetId ();

Start ();

}

void

StpProtocol::Start ()

{

NS_LOG_FUNCTION (this);

m_isRootBridge = true;

m_rootBridgeId = m_bridgeId;

m_timer.SetFunction (&StpProtocol::SendBpdu, this);

m_timer.Schedule (Seconds (2.0));

}

void

StpProtocol::Stop ()

{

NS_LOG_FUNCTION (this);

m_timer.Cancel ();

}

void

StpProtocol::SendBpdu ()

{

NS_LOG_FUNCTION (this);

// Create BPDU packet

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

// Add BPDU header information

// …

// Send BPDU on all ports

for (auto it = m_portRoles.begin (); it != m_portRoles.end (); ++it)

{

Ptr<NetDevice> device = it->first;

device->Send (packet, device->GetBroadcast (), 0x0001); // Example protocol number for BPDU

}

m_timer.Schedule (Seconds (2.0));

}

void

StpProtocol::ReceiveBpdu (Ptr<Packet> packet, Ptr<NetDevice> device)

{

NS_LOG_FUNCTION (this << packet << device);

HandleBpdu (packet, device);

}

void

StpProtocol::HandleBpdu (Ptr<Packet> packet, Ptr<NetDevice> device)

{

NS_LOG_FUNCTION (this << packet << device);

// Process BPDU packet

// …

ElectRootBridge ();

UpdatePortRoles ();

}

void

StpProtocol::ElectRootBridge ()

{

NS_LOG_FUNCTION (this);

// Elect root bridge based on received BPDU packets

// …

}

void

StpProtocol::UpdatePortRoles ()

{

NS_LOG_FUNCTION (this);

// Update port roles (Root, Designated, Blocked) based on root bridge election

// …

}

} // namespace ns3

Helper Class

// src/stp/helper/stp-helper.h

#ifndef STP_HELPER_H

#define STP_HELPER_H

#include “ns3/net-device-container.h”

#include “ns3/object-factory.h”

#include “ns3/stp-protocol.h”

namespace ns3 {

class StpHelper

{

public:

StpHelper ();

void Install (NodeContainer c) const;

void Install (Ptr<Node> node) const;

void Install (Ptr<NetDevice> device) const;

private:

ObjectFactory m_factory;

};

} // namespace ns3

#endif // STP_HELPER_H

Implement Helper Class

// src/stp/helper/stp-helper.cc

#include “stp-helper.h”

#include “ns3/stp-protocol.h”

#include “ns3/node.h”

#include “ns3/ipv4.h”

namespace ns3 {

StpHelper::StpHelper ()

{

m_factory.SetTypeId (StpProtocol::GetTypeId ());

}

void

StpHelper::Install (NodeContainer c) const

{

for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)

{

Install (*i);

}

}

void

StpHelper::Install (Ptr<Node> node) const

{

for (uint32_t i = 0; i < node->GetNDevices (); ++i)

{

Ptr<NetDevice> device = node->GetDevice (i);

Install (device);

}

}

void

StpHelper::Install (Ptr<NetDevice> device) const

{

Ptr<StpProtocol> protocol = m_factory.Create<StpProtocol> ();

protocol->Install (device);

}

} // namespace ns3

Example Simulation Script

// examples/stp-simulation.cc

#include “ns3/core-module.h”

#include “ns3/network-module.h”

#include “ns3/internet-module.h”

#include “ns3/bridge-module.h”

#include “ns3/point-to-point-module.h”

#include “ns3/applications-module.h”

#include “ns3/stp-helper.h”

using namespace ns3;

NS_LOG_COMPONENT_DEFINE (“StpSimulation”);

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

{

CommandLine cmd;

cmd.Parse (argc, argv);

// Create nodes

NodeContainer nodes;

nodes.Create (6);

// Create point-to-point links

PointToPointHelper p2p;

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

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

NetDeviceContainer devices[6][6];

for (int i = 0; i < 6; ++i)

{

for (int j = i + 1; j < 6; ++j)

{

devices[i][j] = p2p.Install (nodes.Get (i), nodes.Get (j));

}

}

// Install STP on all nodes

StpHelper stp;

stp.Install (nodes);

// Install Internet stack

InternetStackHelper internet;

internet.Install (nodes);

// Assign IP addresses

Ipv4AddressHelper address;

for (int i = 0; i < 6; ++i)

{

for (int j = i + 1; j < 6; ++j)

{

std::ostringstream subnet;

subnet << “10.” << i << “.” << j << “.0”;

address.SetBase (subnet.str ().c_str (), “255.255.255.0”);

address.Assign (devices[i][j]);

}

}

// Create a packet sink to receive packets

uint16_t sinkPort = 8080;

Address sinkAddress (InetSocketAddress (Ipv4Address (“10.0.0.1”), sinkPort));

PacketSinkHelper packetSinkHelper (“ns3::TcpSocketFactory”, sinkAddress);

ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (0));

sinkApps.Start (Seconds (1.0));

sinkApps.Stop (Seconds (10.0));

// Create a TCP client to send packets

OnOffHelper clientHelper (“ns3::TcpSocketFactory”, sinkAddress);

clientHelper.SetAttribute (“OnTime”, StringValue (“ns3::ConstantRandomVariable[Constant=1]”));

clientHelper.SetAttribute (“OffTime”, StringValue (“ns3::ConstantRandomVariable[Constant=0]”));

clientHelper.SetAttribute (“DataRate”, DataRateValue (DataRate (“1Mbps”)));

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

ApplicationContainer clientApps = clientHelper.Install (nodes.Get (1));

clientApps.Start (Seconds (2.0));

clientApps.Stop (Seconds (10.0));

// Enable tracing

AsciiTraceHelper ascii;

p2p.EnableAsciiAll (ascii.CreateFileStream (“stp-routing.tr”));

p2p.EnablePcapAll (“stp-routing”);

// Run the simulation

Simulator::Run ();

Simulator::Destroy ();

return 0;

}

Running the Simulation

To run the simulation, compile the script and execute it:

./waf configure –enable-examples

./waf build

./waf –run stp-simulation

Overall, we had a performance analysis on the Spanning Tree Protocol (STP) by implementing it in ns3 by creating a simulation that builds a loop-free logical topology for a network. Also, we provide more detailed information on Spanning Tree Protocol (STP) so we assure for best system development.