|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // (C) 2005 Vojtech Janota, Andras Varga 00003 // 00004 // This library is free software, you can redistribute it 00005 // and/or modify 00006 // it under the terms of the GNU Lesser General Public License 00007 // as published by the Free Software Foundation; 00008 // either version 2 of the License, or any later version. 00009 // The library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 // See the GNU Lesser General Public License for more details. 00013 // 00014 00015 #include <omnetpp.h> 00016 #include <algorithm> 00017 00018 #include "LinkStateRouting.h" 00019 #include "IPControlInfo.h" 00020 #include "IPv4InterfaceData.h" 00021 #include "NotifierConsts.h" 00022 #include "RoutingTableAccess.h" 00023 #include "InterfaceTableAccess.h" 00024 #include "NotificationBoard.h" 00025 #include "TED.h" 00026 #include "TEDAccess.h" 00027 00028 Define_Module(LinkStateRouting); 00029 00030 LinkStateRouting::LinkStateRouting() 00031 { 00032 announceMsg = NULL; 00033 } 00034 00035 LinkStateRouting::~LinkStateRouting() 00036 { 00037 cancelAndDelete(announceMsg); 00038 } 00039 00040 void LinkStateRouting::initialize(int stage) 00041 { 00042 // we have to wait until routerId gets assigned in stage 3 00043 if (stage==4) 00044 { 00045 tedmod = TEDAccess().get(); 00046 00047 IRoutingTable *rt = RoutingTableAccess().get(); 00048 routerId = rt->getRouterId(); 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 IInterfaceTable *ift = InterfaceTableAccess().get(); 00058 const char *token; 00059 while ((token = tokenizer.nextToken())!=NULL) 00060 { 00061 ASSERT(ift->getInterfaceByName(token)); 00062 peerIfAddrs.push_back(ift->getInterfaceByName(token)->ipv4Data()->getIPAddress()); 00063 } 00064 00065 // schedule start of flooding link state info 00066 announceMsg = new cMessage("announce"); 00067 scheduleAt(simTime() + exponential(0.01), announceMsg); 00068 } 00069 } 00070 00071 void LinkStateRouting::handleMessage(cMessage * msg) 00072 { 00073 if (msg == announceMsg) 00074 { 00075 delete announceMsg; 00076 announceMsg = NULL; 00077 sendToPeers(tedmod->ted, true, IPAddress()); 00078 } 00079 else if (!strcmp(msg->getArrivalGate()->getName(), "ipIn")) 00080 { 00081 EV << "Processing message from IP: " << msg << endl; 00082 IPControlInfo *controlInfo = check_and_cast<IPControlInfo *>(msg->getControlInfo()); 00083 IPAddress sender = controlInfo->getSrcAddr(); 00084 processLINK_STATE_MESSAGE(check_and_cast<LinkStateMsg*>(msg), sender); 00085 } 00086 else 00087 ASSERT(false); 00088 } 00089 00090 void LinkStateRouting::receiveChangeNotification(int category, const cPolymorphic *details) 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 } 00117 00118 void LinkStateRouting::processLINK_STATE_MESSAGE(LinkStateMsg* msg, IPAddress sender) 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 } 00184 00185 void LinkStateRouting::sendToPeers(const std::vector<TELinkStateInfo>& list, bool req, IPAddress exceptPeer) 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 } 00208 00209 void LinkStateRouting::sendToPeer(IPAddress peer, const std::vector<TELinkStateInfo> & list, bool req) 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 } 00223 00224 void LinkStateRouting::sendToIP(LinkStateMsg *msg, IPAddress destAddr) 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, "ipOut"); 00239 } 00240