INET Framework for OMNeT++/OMNEST
inet::STP Class Reference

Implements the Spanning Tree Protocol. More...

#include <STP.h>

Inheritance diagram for inet::STP:
inet::STPBase inet::ILifecycle

Public Types

enum  BDPUType { CONFIG_BDPU = 0, TCN_BPDU = 1 }
 
typedef Ieee8021dInterfaceData::PortInfo PortInfo
 

Public Member Functions

 STP ()
 
virtual ~STP ()
 
void handleBPDU (BPDU *bpdu)
 
virtual void initInterfacedata (unsigned int portNum)
 
void handleTCN (BPDU *tcn)
 Topology change handling. More...
 
virtual void handleMessage (cMessage *msg) override
 
virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
void generateBPDU (int portNum, const MACAddress &address=MACAddress::STP_MULTICAST_ADDRESS, bool tcFlag=false, bool tcaFlag=false)
 
void generateHelloBDPUs ()
 
void generateTCN ()
 
int comparePorts (Ieee8021dInterfaceData *portA, Ieee8021dInterfaceData *portB)
 
int compareBridgeIDs (unsigned int, MACAddress, unsigned int, MACAddress)
 
int comparePortIDs (unsigned int, unsigned int, unsigned int, unsigned int)
 
bool isSuperiorBPDU (int portNum, BPDU *bpdu)
 
void setSuperiorBPDU (int portNum, BPDU *bpdu)
 
void handleTick ()
 
void checkTimers ()
 
void checkParametersChange ()
 
void initPortTable ()
 
void selectRootPort ()
 
void selectDesignatedPorts ()
 
void setAllDesignated ()
 
void lostRoot ()
 
void lostAlternate (int port)
 
void reset ()
 
bool checkRootEligibility ()
 
void tryRoot ()
 
- Public Member Functions inherited from inet::STPBase
 STPBase ()
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Member Functions

virtual void start () override
 
virtual void stop () override
 
- Protected Member Functions inherited from inet::STPBase
virtual void colorLink (unsigned int i, bool forwarding) const
 Adds effects to be represented by Tkenv. More...
 
virtual void refreshDisplay () const override
 Adds effects to be represented by Tkenv. More...
 
virtual int getRootIndex () const
 Obtains the root gate index. More...
 
Ieee8021dInterfaceDatagetPortInterfaceData (unsigned int portNum)
 Gets Ieee8021dInterfaceData for port number. More...
 
const Ieee8021dInterfaceDatagetPortInterfaceData (unsigned int portNum) const
 
InterfaceEntrygetPortInterfaceEntry (unsigned int portNum)
 Gets InterfaceEntry for port number. More...
 
virtual InterfaceEntrychooseInterface ()
 

Protected Attributes

bool isRoot = false
 
unsigned int rootPort = 0
 
std::vector< unsigned int > desPorts
 
unsigned int rootPathCost = 0
 
unsigned int rootPriority = 0
 
MACAddress rootAddress
 
simtime_t currentMaxAge
 
simtime_t currentFwdDelay
 
simtime_t currentHelloTime
 
simtime_t helloTime
 
unsigned int currentBridgePriority = 0
 
bool topologyChangeNotification = false
 
bool topologyChangeRecvd = false
 
PortInfo defaultPort
 
cMessage * tick = nullptr
 
- Protected Attributes inherited from inet::STPBase
bool visualize = false
 
bool isOperational = false
 
unsigned int numPorts = 0
 
unsigned int bridgePriority = 0
 
MACAddress bridgeAddress
 
simtime_t maxAge
 
simtime_t helloTime
 
simtime_t forwardDelay
 
cModule * switchModule = nullptr
 
IMACAddressTablemacTable = nullptr
 
IInterfaceTableifTable = nullptr
 
InterfaceEntryie = nullptr
 

Static Protected Attributes

static const double tickInterval = 1
 

Friends

std::ostream & operator<< (std::ostream &os, const Ieee8021dInterfaceData::PortRole r)
 
std::ostream & operator<< (std::ostream &os, const Ieee8021dInterfaceData::PortState s)
 
std::ostream & operator<< (std::ostream &os, Ieee8021dInterfaceData *p)
 
std::ostream & operator<< (std::ostream &os, STP i)
 

Detailed Description

Implements the Spanning Tree Protocol.

See the NED file for details.

Member Typedef Documentation

Member Enumeration Documentation

Enumerator
CONFIG_BDPU 
TCN_BPDU 
42 { CONFIG_BDPU = 0, TCN_BPDU = 1 };
Definition: STP.h:42
Definition: STP.h:42

Constructor & Destructor Documentation

inet::STP::STP ( )
33 {
34 }
inet::STP::~STP ( )
virtual
47 {
48  cancelAndDelete(tick);
49 }
cMessage * tick
Definition: STP.h:67

Member Function Documentation

void inet::STP::checkParametersChange ( )

Referenced by handleTick().

387 {
388  if (isRoot) {
392  }
395  reset();
396  }
397 }
unsigned int bridgePriority
Definition: STPBase.h:39
simtime_t helloTime
Definition: STP.h:58
simtime_t currentMaxAge
Definition: STP.h:55
simtime_t maxAge
Definition: STPBase.h:42
bool isRoot
Definition: STP.h:46
simtime_t forwardDelay
Definition: STPBase.h:44
simtime_t currentFwdDelay
Definition: STP.h:56
simtime_t currentHelloTime
Definition: STP.h:57
void reset()
Definition: STP.cc:620
unsigned int currentBridgePriority
Definition: STP.h:61
bool inet::STP::checkRootEligibility ( )

Referenced by tryRoot().

400 {
401  Ieee8021dInterfaceData *port;
402 
403  for (unsigned int i = 0; i < numPorts; i++) {
404  port = getPortInterfaceData(i);
405 
406  if (compareBridgeIDs(port->getRootPriority(), port->getRootAddress(), bridgePriority, bridgeAddress) > 0)
407  return false;
408  }
409 
410  return true;
411 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
unsigned int bridgePriority
Definition: STPBase.h:39
MACAddress bridgeAddress
Definition: STPBase.h:40
int compareBridgeIDs(unsigned int, MACAddress, unsigned int, MACAddress)
Definition: STP.cc:433
unsigned int numPorts
Definition: STPBase.h:37
void inet::STP::checkTimers ( )

Referenced by handleTick().

323 {
324  Ieee8021dInterfaceData *port;
325 
326  // hello timer check
327  if (helloTime >= currentHelloTime) {
328  // only the root switch can generate Hello BPDUs
329  if (isRoot)
331 
332  helloTime = 0;
333  }
334 
335  // information age check
336  for (unsigned int i = 0; i < numPorts; i++) {
337  port = getPortInterfaceData(i);
338 
339  if (port->getAge() >= currentMaxAge) {
340  EV_DETAIL << "Port=" << i << " reached its maximum age. Setting it to the default port info." << endl;
341  if (port->getRole() == Ieee8021dInterfaceData::ROOT) {
343  lostRoot();
344  }
345  else {
347  lostAlternate(i);
348  }
349  }
350  }
351 
352  // fdWhile timer
353  for (unsigned int i = 0; i < numPorts; i++) {
354  port = getPortInterfaceData(i);
355 
356  // ROOT / DESIGNATED, can transition
357  if (port->getRole() == Ieee8021dInterfaceData::ROOT || port->getRole() == Ieee8021dInterfaceData::DESIGNATED) {
358  if (port->getFdWhile() >= currentFwdDelay) {
359  switch (port->getState()) {
361  EV_DETAIL << "Port=" << i << " goes into learning state." << endl;
362  port->setState(Ieee8021dInterfaceData::LEARNING);
363  port->setFdWhile(0);
364  break;
365 
367  EV_DETAIL << "Port=" << i << " goes into forwarding state." << endl;
368  port->setState(Ieee8021dInterfaceData::FORWARDING);
369  port->setFdWhile(0);
370  break;
371 
372  default:
373  port->setFdWhile(0);
374  break;
375  }
376  }
377  }
378  else {
379  EV_DETAIL << "Port=" << i << " goes into discarding state." << endl;
380  port->setFdWhile(0);
381  port->setState(Ieee8021dInterfaceData::DISCARDING);
382  }
383  }
384 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
Definition: Ieee8021dInterfaceData.h:39
void lostRoot()
Definition: STP.cc:608
void lostAlternate(int port)
Definition: STP.cc:614
simtime_t helloTime
Definition: STP.h:58
Definition: Ieee8021dInterfaceData.h:37
Definition: Ieee8021dInterfaceData.h:39
Definition: Ieee8021dInterfaceData.h:37
simtime_t currentMaxAge
Definition: STP.h:55
bool isRoot
Definition: STP.h:46
simtime_t currentFwdDelay
Definition: STP.h:56
simtime_t currentHelloTime
Definition: STP.h:57
virtual void initInterfacedata(unsigned int portNum)
Definition: STP.cc:663
void generateHelloBDPUs()
Definition: STP.cc:283
Definition: Ieee8021dInterfaceData.h:39
unsigned int numPorts
Definition: STPBase.h:37
int inet::STP::compareBridgeIDs ( unsigned int  aPriority,
MACAddress  aAddress,
unsigned int  bPriority,
MACAddress  bAddress 
)

Referenced by checkRootEligibility(), and comparePorts().

434 {
435  if (aPriority < bPriority)
436  return 1; // A is superior
437  else if (aPriority > bPriority)
438  return -1;
439 
440  // APR == BPR
441  if (aAddress.compareTo(bAddress) == -1)
442  return 1; // A is superior
443  else if (aAddress.compareTo(bAddress) == 1)
444  return -1;
445 
446  // A==B
447  // (can happen if bridge have two port connected to one not bridged lan,
448  // "cable loopback"
449  return 0;
450 }
int inet::STP::comparePortIDs ( unsigned int  aPriority,
unsigned int  aNum,
unsigned int  bPriority,
unsigned int  bNum 
)

Referenced by comparePorts().

453 {
454  if (aPriority < bPriority)
455  return 1; // A is superior
456 
457  else if (aPriority > bPriority)
458  return -1;
459 
460  // APR == BPR
461  if (aNum < bNum)
462  return 1; // A is superior
463 
464  else if (aNum > bNum)
465  return -1;
466 
467  // A==B
468  return 0;
469 }
int inet::STP::comparePorts ( Ieee8021dInterfaceData portA,
Ieee8021dInterfaceData portB 
)

Referenced by isSuperiorBPDU(), selectDesignatedPorts(), and selectRootPort().

472 {
473  int result;
474 
475  result = compareBridgeIDs(portA->getRootPriority(), portA->getRootAddress(), portB->getRootPriority(),
476  portB->getRootAddress());
477 
478  // not same, so pass result
479  if (result != 0)
480  return result;
481 
482  if (portA->getRootPathCost() < portB->getRootPathCost())
483  return 1;
484 
485  if (portA->getRootPathCost() > portB->getRootPathCost())
486  return -1;
487 
488  // designated bridge
489  result = compareBridgeIDs(portA->getBridgePriority(), portA->getBridgeAddress(), portB->getBridgePriority(),
490  portB->getBridgeAddress());
491 
492  // not same, so pass result
493  if (result != 0)
494  return result;
495 
496  // designated port of designated Bridge
497  result = comparePortIDs(portA->getPortPriority(), portA->getPortNum(), portB->getPortPriority(), portB->getPortNum());
498 
499  // not same, so pass result
500  if (result != 0)
501  return result;
502 
503  return 0; // same
504 }
int comparePortIDs(unsigned int, unsigned int, unsigned int, unsigned int)
Definition: STP.cc:452
int compareBridgeIDs(unsigned int, MACAddress, unsigned int, MACAddress)
Definition: STP.cc:433
void inet::STP::generateBPDU ( int  portNum,
const MACAddress address = MACAddress::STP_MULTICAST_ADDRESS,
bool  tcFlag = false,
bool  tcaFlag = false 
)

Referenced by generateHelloBDPUs(), handleBPDU(), and handleTCN().

158 {
159  BPDU *bpdu = new BPDU();
160  Ieee802Ctrl *controlInfo = new Ieee802Ctrl();
161  controlInfo->setDest(address);
162  controlInfo->setSwitchPort(port);
163 
164  bpdu->setName("BPDU");
165  bpdu->setProtocolIdentifier(0);
166  bpdu->setProtocolVersionIdentifier(0);
167  bpdu->setBpduType(0); // 0 if configuration BPDU
168 
169  bpdu->setBridgeAddress(bridgeAddress);
170  bpdu->setBridgePriority(bridgePriority);
171  bpdu->setRootPathCost(rootPathCost);
172  bpdu->setRootAddress(rootAddress);
173  bpdu->setRootPriority(rootPriority);
174  bpdu->setPortNum(port);
175  bpdu->setPortPriority(getPortInterfaceData(port)->getPriority());
176  bpdu->setMessageAge(0);
177  bpdu->setMaxAge(currentMaxAge);
178  bpdu->setHelloTime(currentHelloTime);
179  bpdu->setForwardDelay(currentFwdDelay);
180 
182  if (isRoot || tcFlag) {
183  bpdu->setTcFlag(true);
184  bpdu->setTcaFlag(false);
185  }
186  else if (tcaFlag) {
187  bpdu->setTcFlag(false);
188  bpdu->setTcaFlag(true);
189  }
190  }
191 
192  bpdu->setControlInfo(controlInfo);
193 
194  send(bpdu, "relayOut");
195 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
unsigned int bridgePriority
Definition: STPBase.h:39
bool topologyChangeNotification
Definition: STP.h:63
simtime_t currentMaxAge
Definition: STP.h:55
bool isRoot
Definition: STP.h:46
MACAddress rootAddress
Definition: STP.h:53
unsigned int rootPriority
Definition: STP.h:52
simtime_t currentFwdDelay
Definition: STP.h:56
simtime_t currentHelloTime
Definition: STP.h:57
MACAddress bridgeAddress
Definition: STPBase.h:40
unsigned int rootPathCost
Definition: STP.h:51
void inet::STP::generateHelloBDPUs ( )

Referenced by checkTimers().

284 {
285  EV_INFO << "It is hello time. Root switch sending hello BDPUs on all its ports." << endl;
286 
287  // send hello BDPUs on all ports
288  for (unsigned int i = 0; i < numPorts; i++)
289  generateBPDU(i);
290 }
void generateBPDU(int portNum, const MACAddress &address=MACAddress::STP_MULTICAST_ADDRESS, bool tcFlag=false, bool tcaFlag=false)
Definition: STP.cc:157
unsigned int numPorts
Definition: STPBase.h:37
void inet::STP::generateTCN ( )

Referenced by handleTick().

198 {
199  // there is something to notify
202  // exist root port to notifying
204  BPDU *tcn = new BPDU();
205  tcn->setProtocolIdentifier(0);
206  tcn->setProtocolVersionIdentifier(0);
207  tcn->setName("BPDU");
208 
209  // 1 if Topology Change Notification BPDU
210  tcn->setBpduType(1);
211 
212  Ieee802Ctrl *controlInfo = new Ieee802Ctrl();
213  controlInfo->setDest(MACAddress::STP_MULTICAST_ADDRESS);
214  controlInfo->setSwitchPort(rootPort);
215  tcn->setControlInfo(controlInfo);
216 
217  EV_INFO << "The topology has changed. Sending Topology Change Notification BPDU " << tcn << " to the Root Switch." << endl;
218  send(tcn, "relayOut");
219  }
220  }
221 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
Definition: Ieee8021dInterfaceData.h:37
bool topologyChangeNotification
Definition: STP.h:63
bool topologyChangeRecvd
Definition: STP.h:64
unsigned int rootPort
Definition: STP.h:47
static const MACAddress STP_MULTICAST_ADDRESS
The spanning tree protocol bridge&#39;s multicast address, 01:80:C2:00:00:00.
Definition: MACAddress.h:66
void inet::STP::handleBPDU ( BPDU bpdu)

Referenced by handleMessage().

92 {
93  Ieee802Ctrl *controlInfo = check_and_cast<Ieee802Ctrl *>(bpdu->getControlInfo());
94  int arrivalGate = controlInfo->getSwitchPort();
95  Ieee8021dInterfaceData *port = getPortInterfaceData(arrivalGate);
96 
97  if (bpdu->getTcaFlag()) {
98  topologyChangeRecvd = true;
100  }
101 
102  // get inferior BPDU, reply with superior
103  if (!isSuperiorBPDU(arrivalGate, bpdu)) {
104  if (port->getRole() == Ieee8021dInterfaceData::DESIGNATED) {
105  EV_DETAIL << "Inferior Configuration BPDU " << bpdu << " arrived on port=" << arrivalGate << " responding to it with a superior BPDU." << endl;
106  generateBPDU(arrivalGate);
107  }
108  }
109  // BPDU from root
110  else if (port->getRole() == Ieee8021dInterfaceData::ROOT) {
111  EV_INFO << "Configuration BPDU " << bpdu << " arrived from Root Switch." << endl;
112 
113  if (bpdu->getTcFlag()) {
114  EV_DEBUG << "MACAddressTable aging time set to " << currentFwdDelay << "." << endl;
116 
117  // config BPDU with TC flag
118  for (auto & elem : desPorts)
120  }
121  else {
123 
124  EV_INFO << "Sending BPDUs on all designated ports." << endl;
125 
126  // BPDUs are sent on all designated ports
127  for (auto & elem : desPorts)
128  generateBPDU(elem);
129  }
130  }
131 
132  tryRoot();
133  delete bpdu;
134 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
void tryRoot()
Definition: STP.cc:413
Definition: Ieee8021dInterfaceData.h:37
bool topologyChangeNotification
Definition: STP.h:63
bool topologyChangeRecvd
Definition: STP.h:64
Definition: Ieee8021dInterfaceData.h:37
bool isSuperiorBPDU(int portNum, BPDU *bpdu)
Definition: STP.cc:223
IMACAddressTable * macTable
Definition: STPBase.h:47
simtime_t currentFwdDelay
Definition: STP.h:56
static const MACAddress STP_MULTICAST_ADDRESS
The spanning tree protocol bridge&#39;s multicast address, 01:80:C2:00:00:00.
Definition: MACAddress.h:66
void generateBPDU(int portNum, const MACAddress &address=MACAddress::STP_MULTICAST_ADDRESS, bool tcFlag=false, bool tcaFlag=false)
Definition: STP.cc:157
virtual void resetDefaultAging()=0
std::vector< unsigned int > desPorts
Definition: STP.h:48
virtual void setAgingTime(simtime_t agingTime)=0
void inet::STP::handleMessage ( cMessage *  msg)
overridevirtual
60 {
61  if (!isOperational) {
62  EV << "Message '" << msg << "' arrived when module status is down, dropped it\n";
63  delete msg;
64  return;
65  }
66 
67  cMessage *tmp = msg;
68 
69  if (!msg->isSelfMessage()) {
70  if (dynamic_cast<BPDU *>(tmp)) {
71  BPDU *bpdu = (BPDU *)tmp;
72 
73  if (bpdu->getBpduType() == CONFIG_BDPU)
74  handleBPDU(bpdu);
75  else if (bpdu->getBpduType() == TCN_BPDU)
76  handleTCN(bpdu);
77  }
78  else
79  throw cRuntimeError("Non-BPDU packet received");
80  }
81  else {
82  if (msg == tick) {
83  handleTick();
84  scheduleAt(simTime() + 1, tick);
85  }
86  else
87  throw cRuntimeError("Unknown self-message received");
88  }
89 }
void handleTCN(BPDU *tcn)
Topology change handling.
Definition: STP.cc:136
Definition: STP.h:42
void handleBPDU(BPDU *bpdu)
Definition: STP.cc:91
cMessage * tick
Definition: STP.h:67
bool isOperational
Definition: STPBase.h:36
void handleTick()
Definition: STP.cc:292
Definition: STP.h:42
void inet::STP::handleTCN ( BPDU tcn)

Topology change handling.

Referenced by handleMessage().

137 {
138  EV_INFO << "Topology Change Notification BDPU " << tcn << " arrived." << endl;
140 
141  Ieee802Ctrl *controlInfo = check_and_cast<Ieee802Ctrl *>(tcn->getControlInfo());
142  int arrivalGate = controlInfo->getSwitchPort();
143  MACAddress address = controlInfo->getSrc();
144 
145  // send ACK to the sender
146  EV_INFO << "Sending Topology Change Notification ACK." << endl;
147  generateBPDU(arrivalGate, address, false, true);
148 
149  controlInfo->setSwitchPort(rootPort); // send TCN to the Root Switch
150 
151  if (!isRoot)
152  send(tcn, "relayOut");
153  else
154  delete tcn;
155 }
bool topologyChangeNotification
Definition: STP.h:63
bool isRoot
Definition: STP.h:46
unsigned int rootPort
Definition: STP.h:47
void generateBPDU(int portNum, const MACAddress &address=MACAddress::STP_MULTICAST_ADDRESS, bool tcFlag=false, bool tcaFlag=false)
Definition: STP.cc:157
void inet::STP::handleTick ( )

Referenced by handleMessage().

293 {
294  // hello BDPU timer
295  if (isRoot)
296  helloTime = helloTime + 1;
297  else
298  helloTime = 0;
299 
300  for (unsigned int i = 0; i < numPorts; i++) {
301  Ieee8021dInterfaceData *port = getPortInterfaceData(i);
302 
303  // disabled ports don't count
304  if (port->getRole() == Ieee8021dInterfaceData::DISABLED)
305  continue;
306 
307  // increment the MessageAge and FdWhile timers
308  if (port->getRole() != Ieee8021dInterfaceData::DESIGNATED) {
309  EV_DEBUG << "Message Age timer incremented on port=" << i << endl;
310  port->setAge(port->getAge() + tickInterval);
311  }
312  if (port->getRole() == Ieee8021dInterfaceData::ROOT || port->getRole() == Ieee8021dInterfaceData::DESIGNATED) {
313  EV_DEBUG << "Forward While timer incremented on port=" << i << endl;
314  port->setFdWhile(port->getFdWhile() + tickInterval);
315  }
316  }
317  checkTimers();
319  generateTCN();
320 }
void generateTCN()
Definition: STP.cc:197
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
simtime_t helloTime
Definition: STP.h:58
static const double tickInterval
Definition: STP.h:45
Definition: Ieee8021dInterfaceData.h:37
void checkParametersChange()
Definition: STP.cc:386
Definition: Ieee8021dInterfaceData.h:37
bool isRoot
Definition: STP.h:46
void checkTimers()
Definition: STP.cc:322
Definition: Ieee8021dInterfaceData.h:37
unsigned int numPorts
Definition: STPBase.h:37
void inet::STP::initialize ( int  stage)
overridevirtual

Reimplemented from inet::STPBase.

37 {
38  STPBase::initialize(stage);
39 
40  if (stage == INITSTAGE_LOCAL) {
41  tick = new cMessage("STP_TICK", 0);
42  WATCH(bridgeAddress);
43  }
44 }
virtual void initialize(int stage) override
Definition: STPBase.cc:34
cMessage * tick
Definition: STP.h:67
Local initializations.
Definition: InitStages.h:35
MACAddress bridgeAddress
Definition: STPBase.h:40
void inet::STP::initInterfacedata ( unsigned int  portNum)
virtual

Referenced by checkTimers(), and initPortTable().

664 {
665  Ieee8021dInterfaceData *ifd = getPortInterfaceData(portNum);
667  ifd->setState(Ieee8021dInterfaceData::DISCARDING);
668  ifd->setRootPriority(bridgePriority);
669  ifd->setRootAddress(bridgeAddress);
670  ifd->setRootPathCost(0);
671  ifd->setAge(0);
672  ifd->setBridgePriority(bridgePriority);
673  ifd->setBridgeAddress(bridgeAddress);
674  ifd->setPortPriority(-1);
675  ifd->setPortNum(-1);
676  ifd->setLostBPDU(0);
677 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
unsigned int bridgePriority
Definition: STPBase.h:39
Definition: Ieee8021dInterfaceData.h:39
MACAddress bridgeAddress
Definition: STPBase.h:40
Definition: Ieee8021dInterfaceData.h:37
void inet::STP::initPortTable ( )

Referenced by start().

52 {
53  EV_DEBUG << "IEE8021D Interface Data initialization. Setting port infos to the protocol defaults." << endl;
54  for (unsigned int i = 0; i < numPorts; i++) {
56  }
57 }
virtual void initInterfacedata(unsigned int portNum)
Definition: STP.cc:663
unsigned int numPorts
Definition: STPBase.h:37
bool inet::STP::isSuperiorBPDU ( int  portNum,
BPDU bpdu 
)

Referenced by handleBPDU().

224 {
225  Ieee8021dInterfaceData *port = getPortInterfaceData(portNum);
226  Ieee8021dInterfaceData *xBpdu = new Ieee8021dInterfaceData();
227 
228  int result;
229 
230  xBpdu->setRootPriority(bpdu->getRootPriority());
231  xBpdu->setRootAddress(bpdu->getRootAddress());
232  xBpdu->setRootPathCost(bpdu->getRootPathCost() + port->getLinkCost());
233  xBpdu->setBridgePriority(bpdu->getBridgePriority());
234  xBpdu->setBridgeAddress(bpdu->getBridgeAddress());
235  xBpdu->setPortPriority(bpdu->getPortPriority());
236  xBpdu->setPortNum(bpdu->getPortNum());
237 
238  result = comparePorts(port, xBpdu);
239 
240  // port is superior
241  if (result > 0) {
242  delete xBpdu;
243  return false;
244  }
245 
246  if (result < 0) {
247  // BPDU is superior
248  port->setFdWhile(0); // renew info
249  port->setState(Ieee8021dInterfaceData::DISCARDING);
250  setSuperiorBPDU(portNum, bpdu); // renew information
251  delete xBpdu;
252  return true;
253  }
254 
255  setSuperiorBPDU(portNum, bpdu); // renew information
256  delete xBpdu;
257  return true;
258 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
Definition: Ieee8021dInterfaceData.h:39
int comparePorts(Ieee8021dInterfaceData *portA, Ieee8021dInterfaceData *portB)
Definition: STP.cc:471
void setSuperiorBPDU(int portNum, BPDU *bpdu)
Definition: STP.cc:260
void inet::STP::lostAlternate ( int  port)

Referenced by checkTimers().

615 {
618 }
void selectDesignatedPorts()
Definition: STP.cc:550
bool topologyChangeNotification
Definition: STP.h:63
void inet::STP::lostRoot ( )

Referenced by checkTimers().

609 {
611  tryRoot();
612 }
void tryRoot()
Definition: STP.cc:413
bool topologyChangeNotification
Definition: STP.h:63
virtual int inet::STP::numInitStages ( ) const
inlineoverridevirtual

Reimplemented from inet::STPBase.

85 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::STP::reset ( )

Referenced by checkParametersChange().

621 {
622  // upon booting all switches believe themselves to be the root
623  isRoot = true;
626  rootPathCost = 0;
631 }
unsigned int bridgePriority
Definition: STPBase.h:39
simtime_t helloTime
Definition: STP.h:58
simtime_t currentMaxAge
Definition: STP.h:55
simtime_t maxAge
Definition: STPBase.h:42
bool isRoot
Definition: STP.h:46
simtime_t forwardDelay
Definition: STPBase.h:44
void setAllDesignated()
Definition: STP.cc:591
MACAddress rootAddress
Definition: STP.h:53
unsigned int rootPriority
Definition: STP.h:52
simtime_t currentFwdDelay
Definition: STP.h:56
simtime_t currentHelloTime
Definition: STP.h:57
MACAddress bridgeAddress
Definition: STPBase.h:40
unsigned int rootPathCost
Definition: STP.h:51
void inet::STP::selectDesignatedPorts ( )

Referenced by lostAlternate(), and tryRoot().

551 {
552  // select designated ports
553  desPorts.clear();
554  Ieee8021dInterfaceData *port;
555  Ieee8021dInterfaceData *bridgeGlobal = new Ieee8021dInterfaceData();
556  int result;
557 
558  bridgeGlobal->setBridgePriority(bridgePriority);
559  bridgeGlobal->setBridgeAddress(bridgeAddress);
560  bridgeGlobal->setRootAddress(rootAddress);
561  bridgeGlobal->setRootPriority(rootPriority);
562 
563  for (unsigned int i = 0; i < numPorts; i++) {
564  port = getPortInterfaceData(i);
565 
566  if (port->getRole() == Ieee8021dInterfaceData::ROOT || port->getRole() == Ieee8021dInterfaceData::DISABLED)
567  continue;
568 
569  bridgeGlobal->setPortPriority(port->getPriority());
570  bridgeGlobal->setPortNum(i);
571 
572  bridgeGlobal->setRootPathCost(rootPathCost + port->getLinkCost());
573 
574  result = comparePorts(bridgeGlobal, port);
575 
576  if (result > 0) {
577  EV_DETAIL << "Port=" << i << " is elected as designated port." << endl;
578  desPorts.push_back(i);
579  port->setRole(Ieee8021dInterfaceData::DESIGNATED);
580  continue;
581  }
582  if (result < 0) {
583  EV_DETAIL << "Port=" << i << " goes into alternate role." << endl;
584  port->setRole(Ieee8021dInterfaceData::ALTERNATE);
585  continue;
586  }
587  }
588  delete bridgeGlobal;
589 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
unsigned int bridgePriority
Definition: STPBase.h:39
int comparePorts(Ieee8021dInterfaceData *portA, Ieee8021dInterfaceData *portB)
Definition: STP.cc:471
Definition: Ieee8021dInterfaceData.h:37
Definition: Ieee8021dInterfaceData.h:37
MACAddress rootAddress
Definition: STP.h:53
unsigned int rootPriority
Definition: STP.h:52
MACAddress bridgeAddress
Definition: STPBase.h:40
std::vector< unsigned int > desPorts
Definition: STP.h:48
Definition: Ieee8021dInterfaceData.h:37
Definition: Ieee8021dInterfaceData.h:37
unsigned int rootPathCost
Definition: STP.h:51
unsigned int numPorts
Definition: STPBase.h:37
void inet::STP::selectRootPort ( )

Referenced by tryRoot().

507 {
508  desPorts.clear();
509  unsigned int xRootPort = 0;
510  int result;
511  Ieee8021dInterfaceData *best = getPortInterfaceData(0);
512  Ieee8021dInterfaceData *currentPort;
513 
514  for (unsigned int i = 0; i < numPorts; i++) {
515  currentPort = getPortInterfaceData(i);
516  currentPort->setRole(Ieee8021dInterfaceData::NOTASSIGNED);
517  result = comparePorts(currentPort, best);
518  if (result > 0) {
519  xRootPort = i;
520  best = currentPort;
521  continue;
522  }
523  if (result < 0) {
524  continue;
525  }
526  if (currentPort->getPriority() < best->getPriority()) {
527  xRootPort = i;
528  best = currentPort;
529  continue;
530  }
531  if (currentPort->getPriority() > best->getPriority())
532  continue;
533  }
534 
535  if (rootPort != xRootPort) {
536  EV_DETAIL << "Port=" << xRootPort << " selected as root port." << endl;
538  }
539  rootPort = xRootPort;
541  rootPathCost = best->getRootPathCost();
542  rootAddress = best->getRootAddress();
543  rootPriority = best->getRootPriority();
544 
545  currentMaxAge = best->getMaxAge();
546  currentFwdDelay = best->getFwdDelay();
547  currentHelloTime = best->getHelloTime();
548 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
void setRole(PortRole role)
Definition: Ieee8021dInterfaceData.h:140
int comparePorts(Ieee8021dInterfaceData *portA, Ieee8021dInterfaceData *portB)
Definition: STP.cc:471
Definition: Ieee8021dInterfaceData.h:37
bool topologyChangeNotification
Definition: STP.h:63
simtime_t currentMaxAge
Definition: STP.h:55
unsigned int rootPort
Definition: STP.h:47
MACAddress rootAddress
Definition: STP.h:53
unsigned int rootPriority
Definition: STP.h:52
simtime_t currentFwdDelay
Definition: STP.h:56
simtime_t currentHelloTime
Definition: STP.h:57
std::vector< unsigned int > desPorts
Definition: STP.h:48
Definition: Ieee8021dInterfaceData.h:37
unsigned int rootPathCost
Definition: STP.h:51
unsigned int numPorts
Definition: STPBase.h:37
void inet::STP::setAllDesignated ( )

Referenced by reset(), start(), and tryRoot().

592 {
593  // all ports of the root switch are designated ports
594  EV_DETAIL << "All ports become designated." << endl; // todo
595 
596  Ieee8021dInterfaceData *port;
597  desPorts.clear();
598  for (unsigned int i = 0; i < numPorts; i++) {
599  port = getPortInterfaceData(i);
600  if (port->getRole() == Ieee8021dInterfaceData::DISABLED)
601  continue;
602 
603  port->setRole(Ieee8021dInterfaceData::DESIGNATED);
604  desPorts.push_back(i);
605  }
606 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
Definition: Ieee8021dInterfaceData.h:37
std::vector< unsigned int > desPorts
Definition: STP.h:48
Definition: Ieee8021dInterfaceData.h:37
unsigned int numPorts
Definition: STPBase.h:37
void inet::STP::setSuperiorBPDU ( int  portNum,
BPDU bpdu 
)

Referenced by isSuperiorBPDU().

261 {
262  // BDPU is out-of-date
263  if (bpdu->getMessageAge() >= bpdu->getMaxAge())
264  return;
265 
266  Ieee8021dInterfaceData *portData = getPortInterfaceData(portNum);
267 
268  portData->setRootPriority(bpdu->getRootPriority());
269  portData->setRootAddress(bpdu->getRootAddress());
270  portData->setRootPathCost(bpdu->getRootPathCost() + portData->getLinkCost());
271  portData->setBridgePriority(bpdu->getBridgePriority());
272  portData->setBridgeAddress(bpdu->getBridgeAddress());
273  portData->setPortPriority(bpdu->getPortPriority());
274  portData->setPortNum(bpdu->getPortNum());
275  portData->setMaxAge(bpdu->getMaxAge());
276  portData->setFwdDelay(bpdu->getForwardDelay());
277  portData->setHelloTime(bpdu->getHelloTime());
278 
279  // we just set new port info so reset the age timer
280  portData->setAge(0);
281 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Gets Ieee8021dInterfaceData for port number.
Definition: STPBase.cc:140
void inet::STP::start ( )
overrideprotectedvirtual

Reimplemented from inet::STPBase.

634 {
635  STPBase::start();
636 
637  initPortTable();
639  isRoot = true;
641  topologyChangeRecvd = true;
644  rootPathCost = 0;
645  rootPort = 0;
649  helloTime = 0;
651 
652  scheduleAt(simTime() + tickInterval, tick);
653 }
unsigned int bridgePriority
Definition: STPBase.h:39
simtime_t helloTime
Definition: STP.h:58
static const double tickInterval
Definition: STP.h:45
bool topologyChangeNotification
Definition: STP.h:63
bool topologyChangeRecvd
Definition: STP.h:64
simtime_t currentMaxAge
Definition: STP.h:55
simtime_t maxAge
Definition: STPBase.h:42
bool isRoot
Definition: STP.h:46
simtime_t forwardDelay
Definition: STPBase.h:44
void setAllDesignated()
Definition: STP.cc:591
unsigned int rootPort
Definition: STP.h:47
MACAddress rootAddress
Definition: STP.h:53
void initPortTable()
Definition: STP.cc:51
unsigned int rootPriority
Definition: STP.h:52
simtime_t currentFwdDelay
Definition: STP.h:56
virtual void start()
Definition: STPBase.cc:65
cMessage * tick
Definition: STP.h:67
simtime_t currentHelloTime
Definition: STP.h:57
MACAddress bridgeAddress
Definition: STPBase.h:40
unsigned int currentBridgePriority
Definition: STP.h:61
unsigned int rootPathCost
Definition: STP.h:51
void inet::STP::stop ( )
overrideprotectedvirtual

Reimplemented from inet::STPBase.

656 {
657  STPBase::stop();
658  isRoot = false;
660  cancelEvent(tick);
661 }
bool topologyChangeNotification
Definition: STP.h:63
bool isRoot
Definition: STP.h:46
cMessage * tick
Definition: STP.h:67
virtual void stop()
Definition: STPBase.cc:76
void inet::STP::tryRoot ( )

Referenced by handleBPDU(), and lostRoot().

414 {
415  if (checkRootEligibility()) {
416  EV_DETAIL << "Switch is elected as root switch." << endl;
417  isRoot = true;
421  rootPathCost = 0;
425  }
426  else {
427  isRoot = false;
428  selectRootPort();
430  }
431 }
void selectDesignatedPorts()
Definition: STP.cc:550
unsigned int bridgePriority
Definition: STPBase.h:39
bool checkRootEligibility()
Definition: STP.cc:399
simtime_t helloTime
Definition: STP.h:58
void selectRootPort()
Definition: STP.cc:506
simtime_t currentMaxAge
Definition: STP.h:55
simtime_t maxAge
Definition: STPBase.h:42
bool isRoot
Definition: STP.h:46
simtime_t forwardDelay
Definition: STPBase.h:44
void setAllDesignated()
Definition: STP.cc:591
MACAddress rootAddress
Definition: STP.h:53
unsigned int rootPriority
Definition: STP.h:52
simtime_t currentFwdDelay
Definition: STP.h:56
simtime_t currentHelloTime
Definition: STP.h:57
MACAddress bridgeAddress
Definition: STPBase.h:40
unsigned int rootPathCost
Definition: STP.h:51

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  os,
const Ieee8021dInterfaceData::PortRole  r 
)
friend
164 {
165  switch (r) {
167  os << "Unkn";
168  break;
169 
171  os << "Altr";
172  break;
173 
175  os << "Desg";
176  break;
177 
179  os << "Root";
180  break;
181 
182  default:
183  os << "<?>";
184  break;
185  }
186 
187  return os;
188 }
Definition: Ieee8021dInterfaceData.h:37
Definition: Ieee8021dInterfaceData.h:37
Definition: Ieee8021dInterfaceData.h:37
Definition: Ieee8021dInterfaceData.h:37
std::ostream& operator<< ( std::ostream &  os,
const Ieee8021dInterfaceData::PortState  s 
)
friend
191 {
192  switch (s) {
194  os << "DIS";
195  break;
196 
198  os << "LRN";
199  break;
200 
202  os << "FWD";
203  break;
204 
205  default:
206  os << "<?>";
207  break;
208  }
209 
210  return os;
211 }
Definition: Ieee8021dInterfaceData.h:39
Definition: Ieee8021dInterfaceData.h:39
value< double, units::s > s
Definition: Units.h:1049
Definition: Ieee8021dInterfaceData.h:39
std::ostream& operator<< ( std::ostream &  os,
Ieee8021dInterfaceData p 
)
friend
214 {
215  os << "[";
216  if (p->isLearning())
217  os << "L";
218  else
219  os << "_";
220  if (p->isForwarding())
221  os << "F";
222  else
223  os << "_";
224  os << "]";
225 
226  os << " " << p->getRole() << " " << p->getState() << " ";
227  os << p->getLinkCost() << " ";
228  os << p->getPriority() << " ";
229 
230  return os;
231 }
std::ostream& operator<< ( std::ostream &  os,
STP  i 
)
friend
234 {
235  os << "RootID Priority: " << i.rootPriority << " \n";
236  os << " Address: " << i.rootAddress << " \n";
237  if (i.isRoot)
238  os << " This bridge is the Root. \n";
239  else {
240  os << " Cost: " << i.rootPathCost << " \n";
241  os << " Port: " << i.rootPort << " \n";
242  }
243  os << " Hello Time: " << i.currentHelloTime << " \n";
244  os << " Max Age: " << i.currentMaxAge << " \n";
245  os << " Forward Delay: " << i.currentFwdDelay << " \n";
246  os << "BridgeID Priority: " << i.bridgePriority << "\n";
247  os << " Address: " << i.bridgeAddress << " \n";
248  os << " Hello Time: " << i.helloTime << " \n";
249  os << " Max Age: " << i.maxAge << " \n";
250  os << " Forward Delay: " << i.forwardDelay << " \n";
251  os << "Port Flag Role State Cost Priority \n";
252  os << "-----------------------------------------\n";
253 
254  for (unsigned int x = 0; x < i.numPorts; x++)
255  os << x << " " << i.getPortInterfaceData(x) << " \n";
256 
257  return os;
258 }

Member Data Documentation

unsigned int inet::STP::currentBridgePriority = 0
protected

Referenced by checkParametersChange(), and start().

simtime_t inet::STP::currentFwdDelay
protected
simtime_t inet::STP::currentHelloTime
protected
simtime_t inet::STP::currentMaxAge
protected
PortInfo inet::STP::defaultPort
protected
std::vector<unsigned int> inet::STP::desPorts
protected
simtime_t inet::STP::helloTime
protected
bool inet::STP::isRoot = false
protected
unsigned int inet::STP::rootPathCost = 0
protected
unsigned int inet::STP::rootPort = 0
protected
unsigned int inet::STP::rootPriority = 0
protected
cMessage* inet::STP::tick = nullptr
protected
const double inet::STP::tickInterval = 1
staticprotected

Referenced by handleTick(), and start().

bool inet::STP::topologyChangeNotification = false
protected
bool inet::STP::topologyChangeRecvd = false
protected

Referenced by generateTCN(), handleBPDU(), and start().


The documentation for this class was generated from the following files: