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

#include <Ieee8021dRelay.h>

Inheritance diagram for inet::Ieee8021dRelay:
inet::ILifecycle

Public Member Functions

 Ieee8021dRelay ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
void handleAndDispatchFrame (EtherFrame *frame)
 Updates address table (if the port is in learning state) with source address, determines output port and sends out (or broadcasts) frame on ports (if the ports are in forwarding state). More...
 
void dispatch (EtherFrame *frame, unsigned int portNum)
 
void learn (EtherFrame *frame)
 
void broadcast (EtherFrame *frame)
 
void dispatchBPDU (BPDU *bpdu)
 Receives BPDU from the STP/RSTP module and dispatch it to network. More...
 
void deliverBPDU (EtherFrame *frame)
 Deliver BPDU to the STP/RSTP module. More...
 
virtual void start ()
 
virtual void stop ()
 
bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
Ieee8021dInterfaceDatagetPortInterfaceData (unsigned int portNum)
 
virtual InterfaceEntrychooseInterface ()
 
virtual void finish () override
 

Protected Attributes

MACAddress bridgeAddress
 
IInterfaceTableifTable = nullptr
 
IMACAddressTablemacTable = nullptr
 
InterfaceEntryie = nullptr
 
bool isOperational = false
 
bool isStpAware = false
 
unsigned int portCount = 0
 
int numReceivedNetworkFrames = 0
 
int numDroppedFrames = 0
 
int numReceivedBPDUsFromSTP = 0
 
int numDeliveredBDPUsToSTP = 0
 
int numDispatchedNonBPDUFrames = 0
 
int numDispatchedBDPUFrames = 0
 

Constructor & Destructor Documentation

inet::Ieee8021dRelay::Ieee8021dRelay ( )
30 {
31 }

Member Function Documentation

void inet::Ieee8021dRelay::broadcast ( EtherFrame frame)
protected

Referenced by handleAndDispatchFrame().

102 {
103  EV_DETAIL << "Broadcast frame " << frame << endl;
104 
105  unsigned int arrivalGate = frame->getArrivalGate()->getIndex();
106 
107  for (unsigned int i = 0; i < portCount; i++)
108  if (i != arrivalGate && (!isStpAware || getPortInterfaceData(i)->isForwarding()))
109  dispatch(frame->dup(), i);
110 
111 
112  delete frame;
113 }
unsigned int portCount
Definition: Ieee8021dRelay.h:47
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Definition: Ieee8021dRelay.cc:232
bool isStpAware
Definition: Ieee8021dRelay.h:46
void dispatch(EtherFrame *frame, unsigned int portNum)
Definition: Ieee8021dRelay.cc:162
InterfaceEntry * inet::Ieee8021dRelay::chooseInterface ( )
protectedvirtual

Referenced by initialize(), and start().

269 {
270  // TODO: Currently, we assume that the first non-loopback interface is an Ethernet interface
271  // since relays work on EtherSwitches.
272  // NOTE that, we don't check if the returning interface is an Ethernet interface!
273  IInterfaceTable *ift = check_and_cast<IInterfaceTable *>(getModuleByPath(par("interfaceTablePath")));
274 
275  for (int i = 0; i < ift->getNumInterfaces(); i++) {
276  InterfaceEntry *current = ift->getInterface(i);
277  if (!current->isLoopback())
278  return current;
279  }
280 
281  return nullptr;
282 }
void inet::Ieee8021dRelay::deliverBPDU ( EtherFrame frame)
protected

Deliver BPDU to the STP/RSTP module.

Sets the BPDU's Ieee802Ctrl info according to the arriving EtherFrame.

Referenced by handleAndDispatchFrame().

215 {
216  BPDU *bpdu = check_and_cast<BPDU *>(frame->decapsulate());
217 
218  Ieee802Ctrl *controlInfo = new Ieee802Ctrl();
219  controlInfo->setSrc(frame->getSrc());
220  controlInfo->setSwitchPort(frame->getArrivalGate()->getIndex());
221  controlInfo->setDest(frame->getDest());
222 
223  bpdu->setControlInfo(controlInfo);
224 
225  delete frame; // we have the BPDU packet, so delete the frame
226 
227  EV_INFO << "Sending BPDU frame " << bpdu << " to the STP/RSTP module" << endl;
229  send(bpdu, "stpOut");
230 }
int numDeliveredBDPUsToSTP
Definition: Ieee8021dRelay.h:53
void inet::Ieee8021dRelay::dispatch ( EtherFrame frame,
unsigned int  portNum 
)
protected

Referenced by broadcast(), and handleAndDispatchFrame().

163 {
164  EV_INFO << "Sending frame " << frame << " on output port " << portNum << "." << endl;
165 
166  if (portNum >= portCount)
167  throw cRuntimeError("Output port %d doesn't exist!", portNum);
168 
169  EV_INFO << "Sending " << frame << " with destination = " << frame->getDest() << ", port = " << portNum << endl;
170 
173  send(frame, "ifOut", portNum);
174 }
int numDispatchedNonBPDUFrames
Definition: Ieee8021dRelay.h:54
unsigned int portCount
Definition: Ieee8021dRelay.h:47
static simsignal_t packetSentToLowerSignal
Definition: LayeredProtocolBase.h:32
void inet::Ieee8021dRelay::dispatchBPDU ( BPDU bpdu)
protected

Receives BPDU from the STP/RSTP module and dispatch it to network.

Sets EherFrame destination, source, etc. according to the BPDU's Ieee802Ctrl info.

Referenced by handleMessage().

186 {
187  Ieee802Ctrl *controlInfo = check_and_cast<Ieee802Ctrl *>(bpdu->removeControlInfo());
188  unsigned int portNum = controlInfo->getSwitchPort();
189  MACAddress address = controlInfo->getDest();
190  delete controlInfo;
191 
192  if (portNum >= portCount)
193  throw cRuntimeError("Output port %d doesn't exist!", portNum);
194 
195  // TODO: use LLCFrame
196  EthernetIIFrame *frame = new EthernetIIFrame(bpdu->getName());
197 
198  frame->setKind(bpdu->getKind());
199  frame->setSrc(bridgeAddress);
200  frame->setDest(address);
201  frame->setByteLength(ETHER_MAC_FRAME_BYTES);
202  frame->setEtherType(-1);
203  frame->encapsulate(bpdu);
204 
205  if (frame->getByteLength() < MIN_ETHERNET_FRAME_BYTES)
206  frame->setByteLength(MIN_ETHERNET_FRAME_BYTES);
207 
208  EV_INFO << "Sending BPDU frame " << frame << " with destination = " << frame->getDest() << ", port = " << portNum << endl;
211  send(frame, "ifOut", portNum);
212 }
#define ETHER_MAC_FRAME_BYTES
Definition: Ethernet.h:49
unsigned int portCount
Definition: Ieee8021dRelay.h:47
static simsignal_t packetSentToLowerSignal
Definition: LayeredProtocolBase.h:32
int numDispatchedBDPUFrames
Definition: Ieee8021dRelay.h:55
#define MIN_ETHERNET_FRAME_BYTES
Definition: Ethernet.h:31
MACAddress bridgeAddress
Definition: Ieee8021dRelay.h:41
void inet::Ieee8021dRelay::finish ( )
overrideprotectedvirtual
285 {
286  recordScalar("number of received BPDUs from STP module", numReceivedBPDUsFromSTP);
287  recordScalar("number of received frames from network (including BPDUs)", numReceivedNetworkFrames);
288  recordScalar("number of dropped frames (including BPDUs)", numDroppedFrames);
289  recordScalar("number of delivered BPDUs to the STP module", numDeliveredBDPUsToSTP);
290  recordScalar("number of dispatched BPDU frames to the network", numDispatchedBDPUFrames);
291  recordScalar("number of dispatched non-BDPU frames to the network", numDispatchedNonBPDUFrames);
292 }
int numDispatchedNonBPDUFrames
Definition: Ieee8021dRelay.h:54
int numReceivedBPDUsFromSTP
Definition: Ieee8021dRelay.h:52
int numDroppedFrames
Definition: Ieee8021dRelay.h:51
int numDispatchedBDPUFrames
Definition: Ieee8021dRelay.h:55
int numDeliveredBDPUsToSTP
Definition: Ieee8021dRelay.h:53
int numReceivedNetworkFrames
Definition: Ieee8021dRelay.h:50
Ieee8021dInterfaceData * inet::Ieee8021dRelay::getPortInterfaceData ( unsigned int  portNum)
protected

Referenced by broadcast(), handleAndDispatchFrame(), and learn().

233 {
234  if (isStpAware) {
235  cGate *gate = getContainingNode(this)->gate("ethg$o", portNum);
236  InterfaceEntry *gateIfEntry = ifTable->getInterfaceByNodeOutputGateId(gate->getId());
237  Ieee8021dInterfaceData *portData = gateIfEntry ? gateIfEntry->ieee8021dData() : nullptr;
238 
239  if (!portData)
240  throw cRuntimeError("Ieee8021dInterfaceData not found for port = %d", portNum);
241 
242  return portData;
243  }
244  return nullptr;
245 }
virtual InterfaceEntry * getInterfaceByNodeOutputGateId(int id) const =0
Returns an interface given by its getNodeOutputGateId().
Ieee8021dInterfaceData * ieee8021dData() const
Definition: InterfaceEntry.h:227
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:65
bool isStpAware
Definition: Ieee8021dRelay.h:46
IInterfaceTable * ifTable
Definition: Ieee8021dRelay.h:42
void inet::Ieee8021dRelay::handleAndDispatchFrame ( EtherFrame frame)
protected

Updates address table (if the port is in learning state) with source address, determines output port and sends out (or broadcasts) frame on ports (if the ports are in forwarding state).

Includes calls to updateTableWithAddress() and getPortForAddress().

Referenced by handleMessage().

116 {
117  int arrivalGate = frame->getArrivalGate()->getIndex();
118  Ieee8021dInterfaceData *arrivalPortData = getPortInterfaceData(arrivalGate);
119  learn(frame);
120 
121  // BPDU Handling
122  if (isStpAware && (frame->getDest() == MACAddress::STP_MULTICAST_ADDRESS || frame->getDest() == bridgeAddress) && arrivalPortData->getRole() != Ieee8021dInterfaceData::DISABLED) {
123  EV_DETAIL << "Deliver BPDU to the STP/RSTP module" << endl;
124  deliverBPDU(frame); // deliver to the STP/RSTP module
125  }
126  else if (isStpAware && !arrivalPortData->isForwarding()) {
127  EV_INFO << "The arrival port is not forwarding! Discarding it!" << endl;
129  delete frame;
130  }
131  else if (frame->getDest().isBroadcast()) { // broadcast address
132  broadcast(frame);
133  }
134  else {
135  int outGate = macTable->getPortForAddress(frame->getDest());
136  // Not known -> broadcast
137  if (outGate == -1) {
138  EV_DETAIL << "Destination address = " << frame->getDest() << " unknown, broadcasting frame " << frame << endl;
139  broadcast(frame);
140  }
141  else {
142  if (outGate != arrivalGate) {
143  Ieee8021dInterfaceData *outPortData = getPortInterfaceData(outGate);
144 
145  if (!isStpAware || outPortData->isForwarding())
146  dispatch(frame, outGate);
147  else {
148  EV_INFO << "Output port " << outGate << " is not forwarding. Discarding!" << endl;
150  delete frame;
151  }
152  }
153  else {
154  EV_DETAIL << "Output port is same as input port, " << frame->getFullName() << " destination = " << frame->getDest() << ", discarding frame " << frame << endl;
156  delete frame;
157  }
158  }
159  }
160 }
void deliverBPDU(EtherFrame *frame)
Deliver BPDU to the STP/RSTP module.
Definition: Ieee8021dRelay.cc:214
void learn(EtherFrame *frame)
Definition: Ieee8021dRelay.cc:176
int numDroppedFrames
Definition: Ieee8021dRelay.h:51
MACAddress bridgeAddress
Definition: Ieee8021dRelay.h:41
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
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Definition: Ieee8021dRelay.cc:232
virtual int getPortForAddress(MACAddress &address, unsigned int vid=0)=0
For a known arriving port, V-TAG and destination MAC.
void broadcast(EtherFrame *frame)
Definition: Ieee8021dRelay.cc:101
bool isStpAware
Definition: Ieee8021dRelay.h:46
Definition: Ieee8021dInterfaceData.h:37
void dispatch(EtherFrame *frame, unsigned int portNum)
Definition: Ieee8021dRelay.cc:162
IMACAddressTable * macTable
Definition: Ieee8021dRelay.h:43
void inet::Ieee8021dRelay::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
73 {
74  if (!isOperational) {
75  EV_ERROR << "Message '" << msg << "' arrived when module status is down, dropped it." << endl;
76  delete msg;
77  return;
78  }
79 
80  if (!msg->isSelfMessage()) {
81  // messages from STP process
82  if (strcmp(msg->getArrivalGate()->getName(), "stpIn") == 0) {
84  EV_INFO << "Received " << msg << " from STP/RSTP module." << endl;
85  BPDU *bpdu = check_and_cast<BPDU *>(msg);
86  dispatchBPDU(bpdu);
87  }
88  // messages from network
89  else if (strcmp(msg->getArrivalGate()->getName(), "ifIn") == 0) {
91  EV_INFO << "Received " << msg << " from network." << endl;
92  EtherFrame *frame = check_and_cast<EtherFrame *>(msg);
95  }
96  }
97  else
98  throw cRuntimeError("This module doesn't handle self-messages!");
99 }
int numReceivedBPDUsFromSTP
Definition: Ieee8021dRelay.h:52
void dispatchBPDU(BPDU *bpdu)
Receives BPDU from the STP/RSTP module and dispatch it to network.
Definition: Ieee8021dRelay.cc:185
bool isOperational
Definition: Ieee8021dRelay.h:45
void handleAndDispatchFrame(EtherFrame *frame)
Updates address table (if the port is in learning state) with source address, determines output port ...
Definition: Ieee8021dRelay.cc:115
int numReceivedNetworkFrames
Definition: Ieee8021dRelay.h:50
static simsignal_t packetReceivedFromLowerSignal
Definition: LayeredProtocolBase.h:33
bool inet::Ieee8021dRelay::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

295 {
296  Enter_Method_Silent();
297 
298  if (dynamic_cast<NodeStartOperation *>(operation)) {
300  start();
301  }
302  }
303  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
305  stop();
306  }
307  }
308  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
310  stop();
311  }
312  }
313  else {
314  throw cRuntimeError("Unsupported operation '%s'", operation->getClassName());
315  }
316 
317  return true;
318 }
virtual void start()
Definition: Ieee8021dRelay.cc:247
Definition: NodeOperations.h:49
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
virtual void stop()
Definition: Ieee8021dRelay.cc:260
Stage
Definition: NodeOperations.h:46
Definition: NodeOperations.h:127
Definition: NodeOperations.h:77
void inet::Ieee8021dRelay::initialize ( int  stage)
overrideprotectedvirtual
34 {
35  if (stage == INITSTAGE_LOCAL) {
36  // statistics
39 
40  // number of ports
41  portCount = gate("ifOut", 0)->size();
42  if (gate("ifIn", 0)->size() != (int)portCount)
43  throw cRuntimeError("the sizes of the ifIn[] and ifOut[] gate vectors must be the same");
44  }
45  else if (stage == INITSTAGE_LINK_LAYER_2) {
46  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
47  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
48 
49  macTable = check_and_cast<IMACAddressTable *>(getModuleByPath(par("macTablePath")));
50  ifTable = check_and_cast<IInterfaceTable *>(getModuleByPath(par("interfaceTablePath")));
51 
52  if (isOperational) {
53  ie = chooseInterface();
54 
55  if (ie)
56  bridgeAddress = ie->getMacAddress(); // get the bridge's MAC address
57  else
58  throw cRuntimeError("No non-loopback interface found!");
59  }
60 
61  isStpAware = gate("stpIn")->isConnected(); // if the stpIn is not connected then the switch is STP/RSTP unaware
62 
63  WATCH(bridgeAddress);
65  WATCH(numDroppedFrames);
69  }
70 }
int numDispatchedNonBPDUFrames
Definition: Ieee8021dRelay.h:54
unsigned int portCount
Definition: Ieee8021dRelay.h:47
int numReceivedBPDUsFromSTP
Definition: Ieee8021dRelay.h:52
int numDroppedFrames
Definition: Ieee8021dRelay.h:51
int numDispatchedBDPUFrames
Definition: Ieee8021dRelay.h:55
int numDeliveredBDPUsToSTP
Definition: Ieee8021dRelay.h:53
bool isOperational
Definition: Ieee8021dRelay.h:45
int numReceivedNetworkFrames
Definition: Ieee8021dRelay.h:50
MACAddress bridgeAddress
Definition: Ieee8021dRelay.h:41
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
InterfaceEntry * ie
Definition: Ieee8021dRelay.h:44
const MACAddress & getMacAddress() const
Definition: InterfaceEntry.h:197
bool isStpAware
Definition: Ieee8021dRelay.h:46
Additional link-layer initializations that depend on the previous stage.
Definition: InitStages.h:64
IMACAddressTable * macTable
Definition: Ieee8021dRelay.h:43
IInterfaceTable * ifTable
Definition: Ieee8021dRelay.h:42
Definition: NodeStatus.h:40
virtual InterfaceEntry * chooseInterface()
Definition: Ieee8021dRelay.cc:268
void inet::Ieee8021dRelay::learn ( EtherFrame frame)
protected

Referenced by handleAndDispatchFrame().

177 {
178  int arrivalGate = frame->getArrivalGate()->getIndex();
179  Ieee8021dInterfaceData *port = getPortInterfaceData(arrivalGate);
180 
181  if (!isStpAware || port->isLearning())
182  macTable->updateTableWithAddress(arrivalGate, frame->getSrc());
183 }
Ieee8021dInterfaceData * getPortInterfaceData(unsigned int portNum)
Definition: Ieee8021dRelay.cc:232
bool isStpAware
Definition: Ieee8021dRelay.h:46
virtual bool updateTableWithAddress(int portno, MACAddress &address, unsigned int vid=0)=0
Register a new MAC address at AddressTable.
IMACAddressTable * macTable
Definition: Ieee8021dRelay.h:43
virtual int inet::Ieee8021dRelay::numInitStages ( ) const
inlineoverrideprotectedvirtual
59 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::Ieee8021dRelay::start ( )
protectedvirtual

Referenced by handleOperationStage().

248 {
249  isOperational = true;
250 
251  ie = chooseInterface();
252  if (ie)
253  bridgeAddress = ie->getMacAddress(); // get the bridge's MAC address
254  else
255  throw cRuntimeError("No non-loopback interface found!");
256 
257  macTable->clearTable();
258 }
virtual void clearTable()=0
For lifecycle: clears all entries from the vlanAddressTable.
bool isOperational
Definition: Ieee8021dRelay.h:45
MACAddress bridgeAddress
Definition: Ieee8021dRelay.h:41
InterfaceEntry * ie
Definition: Ieee8021dRelay.h:44
const MACAddress & getMacAddress() const
Definition: InterfaceEntry.h:197
IMACAddressTable * macTable
Definition: Ieee8021dRelay.h:43
virtual InterfaceEntry * chooseInterface()
Definition: Ieee8021dRelay.cc:268
void inet::Ieee8021dRelay::stop ( )
protectedvirtual

Referenced by handleOperationStage().

261 {
262  isOperational = false;
263 
264  macTable->clearTable();
265  ie = nullptr;
266 }
virtual void clearTable()=0
For lifecycle: clears all entries from the vlanAddressTable.
bool isOperational
Definition: Ieee8021dRelay.h:45
InterfaceEntry * ie
Definition: Ieee8021dRelay.h:44
IMACAddressTable * macTable
Definition: Ieee8021dRelay.h:43

Member Data Documentation

MACAddress inet::Ieee8021dRelay::bridgeAddress
protected
InterfaceEntry* inet::Ieee8021dRelay::ie = nullptr
protected

Referenced by initialize(), start(), and stop().

IInterfaceTable* inet::Ieee8021dRelay::ifTable = nullptr
protected

Referenced by getPortInterfaceData(), and initialize().

bool inet::Ieee8021dRelay::isOperational = false
protected

Referenced by handleMessage(), initialize(), start(), and stop().

bool inet::Ieee8021dRelay::isStpAware = false
protected
IMACAddressTable* inet::Ieee8021dRelay::macTable = nullptr
protected
int inet::Ieee8021dRelay::numDeliveredBDPUsToSTP = 0
protected

Referenced by deliverBPDU(), finish(), and initialize().

int inet::Ieee8021dRelay::numDispatchedBDPUFrames = 0
protected

Referenced by dispatchBPDU(), finish(), and initialize().

int inet::Ieee8021dRelay::numDispatchedNonBPDUFrames = 0
protected

Referenced by dispatch(), finish(), and initialize().

int inet::Ieee8021dRelay::numDroppedFrames = 0
protected
int inet::Ieee8021dRelay::numReceivedBPDUsFromSTP = 0
protected

Referenced by finish(), handleMessage(), and initialize().

int inet::Ieee8021dRelay::numReceivedNetworkFrames = 0
protected

Referenced by finish(), handleMessage(), and initialize().

unsigned int inet::Ieee8021dRelay::portCount = 0
protected

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