#include <LinkStateRouting.h>
Inheritance diagram for LinkStateRouting:
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.
Public Member Functions | |
LinkStateRouting () | |
virtual | ~LinkStateRouting () |
Protected Member Functions | |
virtual void | initialize (int stage) |
virtual int | numInitStages () const |
virtual void | handleMessage (cMessage *msg) |
void | processLINK_STATE_MESSAGE (LinkStateMsg *msg, IPAddress sender) |
virtual void | receiveChangeNotification (int category, cPolymorphic *details) |
void | sendToPeers (const std::vector< TELinkStateInfo > &list, bool req, IPAddress exceptPeer) |
void | sendToPeer (IPAddress peer, const std::vector< TELinkStateInfo > &list, bool req) |
void | sendToIP (LinkStateMsg *msg, IPAddress destAddr) |
Protected Attributes | |
TED * | tedmod |
cMessage * | announceMsg |
IPAddress | routerId |
IPAddressVector | peerIfAddrs |
LinkStateRouting::LinkStateRouting | ( | ) |
LinkStateRouting::~LinkStateRouting | ( | ) | [virtual] |
void LinkStateRouting::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
00072 { 00073 if (msg == announceMsg) 00074 { 00075 delete announceMsg; 00076 announceMsg = NULL; 00077 sendToPeers(tedmod->ted, true, IPAddress()); 00078 } 00079 else if (!strcmp(msg->arrivalGate()->name(), "from_ip")) 00080 { 00081 EV << "Processing message from IP: " << msg << endl; 00082 IPControlInfo *controlInfo = check_and_cast<IPControlInfo *>(msg->controlInfo()); 00083 IPAddress sender = controlInfo->srcAddr(); 00084 processLINK_STATE_MESSAGE(check_and_cast<LinkStateMsg*>(msg), sender); 00085 } 00086 else 00087 ASSERT(false); 00088 }
void LinkStateRouting::initialize | ( | int | stage | ) | [protected, virtual] |
00041 { 00042 // we have to wait until routerId gets assigned in stage 3 00043 if (stage==4) 00044 { 00045 tedmod = TEDAccess().get(); 00046 00047 RoutingTable *rt = RoutingTableAccess().get(); 00048 routerId = rt->routerId(); 00049 00050 // listen for TED modifications 00051 NotificationBoard *nb = NotificationBoardAccess().get(); 00052 nb->subscribe(this, NF_TED_CHANGED); 00053 00054 // peers are given as interface names in the "peers" module parameter; 00055 // store corresponding interface addresses in peerIfAddrs[] 00056 cStringTokenizer tokenizer(par("peers")); 00057 InterfaceTable *ift = InterfaceTableAccess().get(); 00058 const char *token; 00059 while ((token = tokenizer.nextToken())!=NULL) 00060 { 00061 ASSERT(ift->interfaceByName(token)); 00062 peerIfAddrs.push_back(ift->interfaceByName(token)->ipv4()->inetAddress()); 00063 } 00064 00065 // schedule start of flooding link state info 00066 announceMsg = new cMessage("announce"); 00067 scheduleAt(simTime() + exponential(0.01), announceMsg); 00068 } 00069 }
virtual int LinkStateRouting::numInitStages | ( | ) | const [inline, protected, virtual] |
void LinkStateRouting::processLINK_STATE_MESSAGE | ( | LinkStateMsg * | msg, | |
IPAddress | sender | |||
) | [protected] |
00119 { 00120 EV << "received LINK_STATE message from " << sender << endl; 00121 00122 TELinkStateInfoVector forward; 00123 00124 unsigned int n = msg->getLinkInfoArraySize(); 00125 00126 bool change = false; // in topology 00127 00128 // loop through every link in the message 00129 for (unsigned int i = 0; i < n; i++) 00130 { 00131 const TELinkStateInfo& link = msg->getLinkInfo(i); 00132 00133 TELinkStateInfo *match; 00134 00135 // process link if we haven't seen this already and timestamp is newer 00136 if(tedmod->checkLinkValidity(link, match)) 00137 { 00138 ASSERT(link.sourceId == link.advrouter.getInt()); 00139 00140 EV << "new information found" << endl; 00141 00142 if(!match) 00143 { 00144 // and we have no info on this link so far, store it as it is 00145 tedmod->ted.push_back(link); 00146 change = true; 00147 } 00148 else 00149 { 00150 // copy over the information from it 00151 if(match->state != link.state) 00152 { 00153 match->state = link.state; 00154 change = true; 00155 } 00156 match->messageId = link.messageId; 00157 match->sourceId = link.sourceId; 00158 match->timestamp = link.timestamp; 00159 for(int i = 0; i < 8; i++) 00160 match->UnResvBandwidth[i] = link.UnResvBandwidth[i]; 00161 match->MaxBandwidth = link.MaxBandwidth; 00162 match->metric = link.metric; 00163 } 00164 00165 forward.push_back(link); 00166 } 00167 } 00168 00169 if(change) 00170 tedmod->rebuildRoutingTable(); 00171 00172 if(msg->getRequest()) 00173 { 00174 sendToPeer(sender, tedmod->ted, false); 00175 } 00176 00177 if(forward.size() > 0) 00178 { 00179 sendToPeers(forward, false, sender); 00180 } 00181 00182 delete msg; 00183 }
void LinkStateRouting::receiveChangeNotification | ( | int | category, | |
cPolymorphic * | details | |||
) | [protected, virtual] |
Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed.
Implements INotifiable.
00091 { 00092 Enter_Method_Silent(); 00093 printNotificationBanner(category, details); 00094 00095 ASSERT(category == NF_TED_CHANGED); 00096 00097 EV << "TED changed\n"; 00098 00099 TEDChangeInfo *d = check_and_cast<TEDChangeInfo *>(details); 00100 00101 unsigned int k = d->getTedLinkIndicesArraySize(); 00102 00103 ASSERT(k > 0); 00104 00105 // build linkinfo list 00106 std::vector<TELinkStateInfo> links; 00107 for (unsigned int i = 0; i < k; i++) 00108 { 00109 unsigned int index = d->getTedLinkIndices(i); 00110 00111 tedmod->updateTimestamp(&tedmod->ted[index]); 00112 links.push_back(tedmod->ted[index]); 00113 } 00114 00115 sendToPeers(links, false, IPAddress()); 00116 }
void LinkStateRouting::sendToIP | ( | LinkStateMsg * | msg, | |
IPAddress | destAddr | |||
) | [protected] |
00225 { 00226 // attach control info to packet 00227 IPControlInfo *controlInfo = new IPControlInfo(); 00228 controlInfo->setDestAddr(destAddr); 00229 controlInfo->setSrcAddr(routerId); 00230 controlInfo->setProtocol(IP_PROT_OSPF); 00231 msg->setControlInfo(controlInfo); 00232 00233 int length = msg->getLinkInfoArraySize() * 72; 00234 msg->setByteLength(length); 00235 00236 msg->addPar("color") = TED_TRAFFIC; 00237 00238 send(msg, "to_ip"); 00239 }
void LinkStateRouting::sendToPeer | ( | IPAddress | peer, | |
const std::vector< TELinkStateInfo > & | list, | |||
bool | req | |||
) | [protected] |
00210 { 00211 EV << "sending LINK_STATE message to " << peer << endl; 00212 00213 LinkStateMsg *out = new LinkStateMsg("link state"); 00214 00215 out->setLinkInfoArraySize(list.size()); 00216 for (unsigned int j = 0; j < list.size(); j++) 00217 out->setLinkInfo(j, list[j]); 00218 00219 out->setRequest(req); 00220 00221 sendToIP(out, peer); 00222 }
void LinkStateRouting::sendToPeers | ( | const std::vector< TELinkStateInfo > & | list, | |
bool | req, | |||
IPAddress | exceptPeer | |||
) | [protected] |
00186 { 00187 EV << "sending LINK_STATE message to peers" << endl; 00188 00189 // send "list" to every peer (linkid in our ted[] entries???) in a LinkStateMsg 00190 for (unsigned int i = 0; i < tedmod->ted.size(); i++) 00191 { 00192 if(tedmod->ted[i].advrouter != routerId) 00193 continue; 00194 00195 if(tedmod->ted[i].linkid == exceptPeer) 00196 continue; 00197 00198 if(!tedmod->ted[i].state) 00199 continue; 00200 00201 if(find(peerIfAddrs.begin(), peerIfAddrs.end(), tedmod->ted[i].local) == peerIfAddrs.end()) 00202 continue; 00203 00204 // send a copy 00205 sendToPeer(tedmod->ted[i].linkid, list, req); 00206 } 00207 }
cMessage* LinkStateRouting::announceMsg [protected] |
IPAddressVector LinkStateRouting::peerIfAddrs [protected] |
IPAddress LinkStateRouting::routerId [protected] |
TED* LinkStateRouting::tedmod [protected] |