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

Implements a minimalistic link state routing protocol that employs flooding. More...

#include <LinkStateRouting.h>

Inheritance diagram for inet::LinkStateRouting:

Public Member Functions

 LinkStateRouting ()
 
virtual ~LinkStateRouting ()
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void processLINK_STATE_MESSAGE (Packet *msg, Ipv4Address sender)
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
virtual void sendToPeers (const std::vector< TeLinkStateInfo > &list, bool req, Ipv4Address exceptPeer)
 
virtual void sendToPeer (Ipv4Address peer, const std::vector< TeLinkStateInfo > &list, bool req)
 
virtual void sendToIP (Packet *msg, Ipv4Address destAddr)
 

Protected Attributes

ModuleRefByPar< Tedtedmod
 
cMessage * announceMsg = nullptr
 
Ipv4Address routerId
 
Ipv4AddressVector peerIfAddrs
 

Detailed Description

Implements a minimalistic link state routing protocol that employs flooding.

Flooding works like this:

When a router receives a link state packet, it merges the packet contents into its own link state database (ted). If the packet contained new information (ted got updated), the router broadcasts the ted contents to all its other neighbours; otherwise (when the packet didn't contain any new info), nothing happens.

Also: when the announceMsg timer expires, LinkStateRouting sends out an initial link state message. (Currently this happens only once, at the beginning of the simulation). The "request" bit in the message is set then, asking neighbours to send back their link state databases. (FIXME why's this? redundant messaging: same msg is often sent twice: both as reply and as voluntary "announce").

TODO discover peers by "hello". Peers are those from which the router has received a Hello in the last X seconds. Link info to all peers are maintained; links to ex-peers (those haven't heard of for more than X seconds) are assumed to be down.

See NED file for more info.

Constructor & Destructor Documentation

◆ LinkStateRouting()

inet::LinkStateRouting::LinkStateRouting ( )
27 {
28 }

◆ ~LinkStateRouting()

inet::LinkStateRouting::~LinkStateRouting ( )
virtual
31 {
32  cancelAndDelete(announceMsg);
33 }

Member Function Documentation

◆ handleMessage()

void inet::LinkStateRouting::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
66 {
67  if (msg == announceMsg) {
68  delete announceMsg;
69  announceMsg = nullptr;
70  sendToPeers(tedmod->ted, true, Ipv4Address());
71  }
72  else if (!strcmp(msg->getArrivalGate()->getName(), "ipIn")) {
73  EV_INFO << "Processing message from Ipv4: " << msg << endl;
74  Ipv4Address sender = check_and_cast<Packet *>(msg)->getTag<L3AddressInd>()->getSrcAddress().toIpv4();
75  processLINK_STATE_MESSAGE(check_and_cast<Packet *>(msg), sender);
76  }
77  else
78  ASSERT(false);
79 }

◆ initialize()

void inet::LinkStateRouting::initialize ( int  stage)
overrideprotectedvirtual
36 {
37  cSimpleModule::initialize(stage);
38  // TODO INITSTAGE
39  if (stage == INITSTAGE_ROUTING_PROTOCOLS) {
40  tedmod.reference(this, "tedModule", true);
41 
42  IIpv4RoutingTable *rt = getModuleFromPar<IIpv4RoutingTable>(par("routingTableModule"), this);
43  routerId = rt->getRouterId();
44 
45  // listen for TED modifications
46  cModule *host = getContainingNode(this);
47  host->subscribe(tedChangedSignal, this);
48 
49  // peers are given as interface names in the "peers" module parameter;
50  // store corresponding interface addresses in peerIfAddrs[]
51  cStringTokenizer tokenizer(par("peers"));
52  IInterfaceTable *ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
53  const char *token;
54  while ((token = tokenizer.nextToken()) != nullptr) {
55  peerIfAddrs.push_back(CHK(ift->findInterfaceByName(token))->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
56  }
57 
58  // schedule start of flooding link state info
59  announceMsg = new cMessage("announce");
60  scheduleAt(simTime() + exponential(0.01), announceMsg);
61  registerProtocol(Protocol::linkStateRouting, gate("ipOut"), gate("ipIn"));
62  }
63 }

◆ numInitStages()

virtual int inet::LinkStateRouting::numInitStages ( ) const
inlineoverrideprotectedvirtual
62 { return NUM_INIT_STAGES; }

◆ processLINK_STATE_MESSAGE()

void inet::LinkStateRouting::processLINK_STATE_MESSAGE ( Packet msg,
Ipv4Address  sender 
)
protectedvirtual
110 {
111  EV_INFO << "received LINK_STATE message from " << sender << endl;
112 
113  const auto& msg = pk->peekAtFront<LinkStateMsg>();
114  TeLinkStateInfoVector forward;
115 
116  unsigned int n = msg->getLinkInfoArraySize();
117 
118  bool change = false; // in topology
119 
120  // loop through every link in the message
121  for (unsigned int i = 0; i < n; i++) {
122  const TeLinkStateInfo& link = msg->getLinkInfo(i);
123 
124  TeLinkStateInfo *match;
125 
126  // process link if we haven't seen this already and timestamp is newer
127  if (tedmod->checkLinkValidity(link, match)) {
128  ASSERT(link.sourceId == link.advrouter.getInt());
129 
130  EV_INFO << "new information found" << endl;
131 
132  if (!match) {
133  // and we have no info on this link so far, store it as it is
134  tedmod->ted.push_back(link);
135  change = true;
136  }
137  else {
138  // copy over the information from it
139  if (match->state != link.state) {
140  match->state = link.state;
141  change = true;
142  }
143  match->messageId = link.messageId;
144  match->sourceId = link.sourceId;
145  match->timestamp = link.timestamp;
146  for (int i = 0; i < 8; i++)
147  match->UnResvBandwidth[i] = link.UnResvBandwidth[i];
148  match->MaxBandwidth = link.MaxBandwidth;
149  match->metric = link.metric;
150  }
151 
152  forward.push_back(link);
153  }
154  }
155 
156  if (change)
157  tedmod->rebuildRoutingTable();
158 
159  if (msg->getRequest()) {
160  sendToPeer(sender, tedmod->ted, false);
161  }
162 
163  if (forward.size() > 0) {
164  sendToPeers(forward, false, sender);
165  }
166 
167  delete pk;
168 }

Referenced by handleMessage().

◆ receiveSignal()

void inet::LinkStateRouting::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprotectedvirtual
82 {
83  Enter_Method("%s", cComponent::getSignalName(signalID));
84 
85  printSignalBanner(signalID, obj, details);
86 
87  ASSERT(signalID == tedChangedSignal);
88 
89  EV_INFO << "TED changed\n";
90 
91  const TedChangeInfo *d = check_and_cast<const TedChangeInfo *>(obj);
92 
93  unsigned int k = d->getTedLinkIndicesArraySize();
94 
95  ASSERT(k > 0);
96 
97  // build linkinfo list
98  std::vector<TeLinkStateInfo> links;
99  for (unsigned int i = 0; i < k; i++) {
100  unsigned int index = d->getTedLinkIndices(i);
101 
102  tedmod->updateTimestamp(&tedmod->ted[index]);
103  links.push_back(tedmod->ted[index]);
104  }
105 
106  sendToPeers(links, false, Ipv4Address());
107 }

◆ sendToIP()

void inet::LinkStateRouting::sendToIP ( Packet msg,
Ipv4Address  destAddr 
)
protectedvirtual
213 {
214  msg->addPar("color") = TED_TRAFFIC;
215 
216  msg->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::linkStateRouting);
217  msg->addTagIfAbsent<DispatchProtocolInd>()->setProtocol(&Protocol::linkStateRouting);
218  msg->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(&Protocol::ipv4);
219  msg->addTagIfAbsent<L3AddressReq>()->setDestAddress(destAddr);
220  msg->addTagIfAbsent<L3AddressReq>()->setSrcAddress(routerId);
221  send(msg, "ipOut");
222 }

Referenced by sendToPeer().

◆ sendToPeer()

void inet::LinkStateRouting::sendToPeer ( Ipv4Address  peer,
const std::vector< TeLinkStateInfo > &  list,
bool  req 
)
protectedvirtual
194 {
195  EV_INFO << "sending LINK_STATE message to " << peer << endl;
196 
197  Packet *pk = new Packet("link state");
198  const auto& out = makeShared<LinkStateMsg>();
199 
200  out->setLinkInfoArraySize(list.size());
201  for (unsigned int j = 0; j < list.size(); j++)
202  out->setLinkInfo(j, list[j]);
203 
204  out->setRequest(req);
205  B length = B(72) * out->getLinkInfoArraySize();
206  out->setChunkLength(length);
207  pk->insertAtBack(out);
208 
209  sendToIP(pk, peer);
210 }

Referenced by processLINK_STATE_MESSAGE(), and sendToPeers().

◆ sendToPeers()

void inet::LinkStateRouting::sendToPeers ( const std::vector< TeLinkStateInfo > &  list,
bool  req,
Ipv4Address  exceptPeer 
)
protectedvirtual
171 {
172  EV_INFO << "sending LINK_STATE message to peers" << endl;
173 
174  // send "list" to every peer (linkid in our ted[] entries???) in a LinkStateMsg
175  for (auto& elem : tedmod->ted) {
176  if (elem.advrouter != routerId)
177  continue;
178 
179  if (elem.linkid == exceptPeer)
180  continue;
181 
182  if (!elem.state)
183  continue;
184 
185  if (!contains(peerIfAddrs, elem.local))
186  continue;
187 
188  // send a copy
189  sendToPeer(elem.linkid, list, req);
190  }
191 }

Referenced by handleMessage(), processLINK_STATE_MESSAGE(), and receiveSignal().

Member Data Documentation

◆ announceMsg

cMessage* inet::LinkStateRouting::announceMsg = nullptr
protected

◆ peerIfAddrs

Ipv4AddressVector inet::LinkStateRouting::peerIfAddrs
protected

Referenced by initialize(), and sendToPeers().

◆ routerId

Ipv4Address inet::LinkStateRouting::routerId
protected

Referenced by initialize(), sendToIP(), and sendToPeers().

◆ tedmod

ModuleRefByPar<Ted> inet::LinkStateRouting::tedmod
protected

The documentation for this class was generated from the following files:
CHK
#define CHK(x)
Definition: INETDefs.h:87
inet::TeLinkStateInfoVector
std::vector< struct TeLinkStateInfo > TeLinkStateInfoVector
Definition: Ted_m.h:46
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::getContainingNode
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
DispatchProtocolReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
inet::printSignalBanner
void printSignalBanner(simsignal_t signalID, const cObject *obj, const cObject *details)
Utility function.
Definition: Simsignals.cc:126
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::Protocol::linkStateRouting
static const Protocol linkStateRouting
Definition: Protocol.h:127
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::tedChangedSignal
simsignal_t tedChangedSignal
Definition: Simsignals.cc:38
inet::contains
bool contains(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:65
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::physicallayer::k
const double k
Definition: Qam1024Modulation.cc:14
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::registerProtocol
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
inet::INITSTAGE_ROUTING_PROTOCOLS
INET_API InitStage INITSTAGE_ROUTING_PROTOCOLS
Initialization of routing protocols.