|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // (C) 2005 Vojtech Janota 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 "TED.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 00026 #define LS_INFINITY 1e16 00027 00028 Define_Module(TED); 00029 00030 TED::TED() 00031 { 00032 } 00033 00034 TED::~TED() 00035 { 00036 } 00037 00038 void TED::initialize(int stage) 00039 { 00040 // we have to wait for stage 2 until interfaces get registered (stage 0) 00041 // and get their auto-assigned IP addresses (stage 2); routerId gets 00042 // assigned in stage 3 00043 if (stage!=4) 00044 return; 00045 00046 rt = RoutingTableAccess().get(); 00047 ift = InterfaceTableAccess().get(); 00048 routerId = rt->getRouterId(); 00049 nb = NotificationBoardAccess().get(); 00050 00051 maxMessageId = 0; 00052 00053 ASSERT(!routerId.isUnspecified()); 00054 00055 // 00056 // Extract initial TED contents from the routing table. 00057 // 00058 // We need to create one TED entry (TELinkStateInfo) for each link, 00059 // i.e. for each physical interface. 00060 // 00061 for (int i = 0; i < ift->getNumInterfaces(); i++) 00062 { 00063 InterfaceEntry *ie = ift->getInterface(i); 00064 00065 if (ie->getNodeOutputGateId() == -1) // ignore if it's not a physical interface 00066 continue; 00067 00068 // 00069 // We'll need to fill in "linkid" and "remote" (ie. peer addr). 00070 // 00071 // Real link state protocols find the peer address by exchanging HELLO messages; 00072 // in this model we haven't implemented HELLO but provide peer addresses via 00073 // preconfigured static host routes in routing table. 00074 // 00075 const IPRoute *rentry = NULL; 00076 for (int j = 0; j < rt->getNumRoutes(); j++) 00077 { 00078 rentry = rt->getRoute(j); 00079 if (rentry->getInterface()==ie && rentry->getType()==IPRoute::DIRECT) 00080 break; 00081 } 00082 ASSERT(rentry); 00083 IPAddress linkid = rentry->getHost(); 00084 IPAddress remote = rentry->getGateway(); 00085 ASSERT(!remote.isUnspecified()); 00086 00087 // find bandwidth of the link 00088 cGate *g = getParentModule()->gate(ie->getNodeOutputGateId()); 00089 ASSERT(g); 00090 double linkBandwidth = g->getChannel()->par("datarate"); 00091 00092 // 00093 // fill in and insert TED entry 00094 // 00095 TELinkStateInfo entry; 00096 entry.advrouter = routerId; 00097 entry.local = ie->ipv4Data()->getIPAddress(); 00098 entry.linkid = linkid; 00099 entry.remote = remote; 00100 entry.MaxBandwidth = linkBandwidth; 00101 for (int j = 0; j < 8; j++) 00102 entry.UnResvBandwidth[j] = entry.MaxBandwidth; 00103 entry.state = true; 00104 00105 // use g->getChannel()->par("delay").doubleValue() for shortest delay calculation 00106 entry.metric = rentry->getInterface()->ipv4Data()->getMetric(); 00107 00108 EV << "metric set to=" << entry.metric << endl; 00109 00110 entry.sourceId = routerId.getInt(); 00111 entry.messageId = ++maxMessageId; 00112 entry.timestamp = simTime(); 00113 00114 ted.push_back(entry); 00115 } 00116 00117 // extract list of local interface addresses into interfaceAddrs[] 00118 for (int i = 0; i < ift->getNumInterfaces(); i++) 00119 { 00120 InterfaceEntry *ie = ift->getInterface(i); 00121 if (rt->getInterfaceByAddress(ie->ipv4Data()->getIPAddress()) != ie) 00122 error("MPLS models assume interfaces to have unique addresses, " 00123 "but address of '%s' (%s) is not unique", 00124 ie->getName(), ie->ipv4Data()->getIPAddress().str().c_str()); 00125 if (!ie->isLoopback()) 00126 interfaceAddrs.push_back(ie->ipv4Data()->getIPAddress()); 00127 } 00128 00129 rebuildRoutingTable(); 00130 00131 WATCH_VECTOR(ted); 00132 } 00133 00134 void TED::handleMessage(cMessage * msg) 00135 { 00136 ASSERT(false); 00137 } 00138 00139 std::ostream & operator<<(std::ostream & os, const TELinkStateInfo& info) 00140 { 00141 os << "advrouter:" << info.advrouter; 00142 os << " linkid:" << info.linkid; 00143 os << " local:" << info.local; 00144 os << " remote:" << info.remote; 00145 os << " state:" << info.state; 00146 os << " metric:" << info.metric; 00147 os << " maxBW:" << info.MaxBandwidth; 00148 os << " unResvBW[7]:" << info.UnResvBandwidth[7]; // FIXME comment: what is 7 ? 00149 os << " unResvBW[4]:" << info.UnResvBandwidth[4]; // FIXME comment: what is 4 ? 00150 00151 return os; 00152 } 00153 00154 // FIXME should this be called findOrCreateVertex() or something like that? 00155 int TED::assignIndex(std::vector<vertex_t>& vertices, IPAddress nodeAddr) 00156 { 00157 // find node in vertices[] whose IP address is nodeAddr 00158 for (unsigned int i = 0 ; i < vertices.size(); i++) 00159 if (vertices[i].node == nodeAddr) 00160 return i; 00161 00162 // if not found, create 00163 vertex_t newVertex; 00164 newVertex.node = nodeAddr; 00165 newVertex.dist = LS_INFINITY; 00166 newVertex.parent = -1; 00167 00168 vertices.push_back(newVertex); 00169 return vertices.size() - 1; 00170 } 00171 00172 IPAddressVector TED::calculateShortestPath(IPAddressVector dest, 00173 const TELinkStateInfoVector& topology, double req_bandwidth, int priority) 00174 { 00175 // FIXME comment: what do we do here? 00176 std::vector<vertex_t> V = calculateShortestPaths(topology, req_bandwidth, priority); 00177 00178 double minDist = LS_INFINITY; 00179 int minIndex = -1; 00180 00181 // FIXME comment: what do we do in this block? 00182 for (unsigned int i = 0; i < V.size(); i++) 00183 { 00184 if (V[i].dist >= minDist) 00185 continue; 00186 00187 if (find(dest.begin(), dest.end(), V[i].node) == dest.end()) 00188 continue; 00189 00190 minDist = V[i].dist; 00191 minIndex = i; 00192 } 00193 00194 IPAddressVector result; 00195 00196 if (minIndex < 0) 00197 return result; 00198 00199 result.push_back(V[minIndex].node); 00200 while (V[minIndex].parent != -1) 00201 { 00202 minIndex = V[minIndex].parent; 00203 result.insert(result.begin(), V[minIndex].node); 00204 } 00205 00206 return result; 00207 } 00208 00209 void TED::rebuildRoutingTable() 00210 { 00211 EV << "rebuilding routing table at " << routerId << endl; 00212 00213 std::vector<vertex_t> V = calculateShortestPaths(ted, 0.0, 7); 00214 00215 // remove all routing entries, except multicast ones (we don't care about them) 00216 int n = rt->getNumRoutes(); 00217 int j = 0; 00218 for (int i = 0; i < n; i++) 00219 { 00220 const IPRoute *entry = rt->getRoute(j); 00221 if (entry->getHost().isMulticast()) 00222 { 00223 ++j; 00224 } 00225 else 00226 { 00227 rt->deleteRoute(entry); 00228 } 00229 } 00230 00231 // for (unsigned int i = 0; i < V.size(); i++) 00232 // { 00233 // EV << "V[" << i << "].node=" << V[i].node << endl; 00234 // EV << "V[" << i << "].parent=" << V[i].parent << endl; 00235 // EV << "V[" << i << "].dist=" << V[i].dist << endl; 00236 // } 00237 00238 // insert remote destinations 00239 00240 for (unsigned int i = 0; i < V.size(); i++) 00241 { 00242 if (V[i].node == routerId) // us 00243 continue; 00244 00245 if (V[i].parent == -1) // unreachable 00246 continue; 00247 00248 if (isLocalPeer(V[i].node)) // local peer 00249 continue; 00250 00251 int nHop = i; 00252 00253 while (!isLocalPeer(V[nHop].node)) 00254 { 00255 nHop = V[nHop].parent; 00256 } 00257 00258 ASSERT(isLocalPeer(V[nHop].node)); 00259 00260 IPRoute *entry = new IPRoute; 00261 entry->setHost(V[i].node); 00262 00263 if (V[i].node == V[nHop].node) 00264 { 00265 entry->setGateway(IPAddress()); 00266 entry->setType(entry->DIRECT); 00267 } 00268 else 00269 { 00270 entry->setGateway(V[nHop].node); 00271 entry->setType(entry->REMOTE); 00272 } 00273 entry->setInterface(rt->getInterfaceByAddress(getInterfaceAddrByPeerAddress(V[nHop].node))); 00274 entry->setSource(IPRoute::OSPF); 00275 00276 entry->setNetmask(0xffffffff); 00277 entry->setMetric(0); 00278 00279 EV << " inserting route: host=" << entry->getHost() << " interface=" << entry->getInterfaceName() << " nexthop=" << entry->getGateway() << "\n"; 00280 00281 rt->addRoute(entry); 00282 } 00283 00284 // insert local peers 00285 00286 for (unsigned int i = 0; i < interfaceAddrs.size(); i++) 00287 { 00288 IPRoute *entry = new IPRoute; 00289 00290 entry->setHost(getPeerByLocalAddress(interfaceAddrs[i])); 00291 entry->setGateway(IPAddress()); 00292 entry->setType(entry->DIRECT); 00293 entry->setInterface(rt->getInterfaceByAddress(interfaceAddrs[i])); 00294 entry->setSource(IPRoute::OSPF); 00295 00296 entry->setNetmask(0xffffffff); 00297 entry->setMetric(0); // XXX FIXME what's that? 00298 00299 EV << " inserting route: local=" << interfaceAddrs[i] << " peer=" << entry->getHost() << " interface=" << entry->getInterfaceName() << "\n"; 00300 00301 rt->addRoute(entry); 00302 } 00303 } 00304 00305 IPAddress TED::getInterfaceAddrByPeerAddress(IPAddress peerIP) 00306 { 00307 std::vector<TELinkStateInfo>::iterator it; 00308 for (it = ted.begin(); it != ted.end(); it++) 00309 if (it->linkid == peerIP && it->advrouter == routerId) 00310 return it->local; 00311 error("not a local peer: %s", peerIP.str().c_str()); 00312 return IPAddress(); // prevent warning 00313 } 00314 00315 IPAddress TED::peerRemoteInterface(IPAddress peerIP) 00316 { 00317 ASSERT(isLocalPeer(peerIP)); 00318 std::vector<TELinkStateInfo>::iterator it; 00319 for (it = ted.begin(); it != ted.end(); it++) 00320 if (it->linkid == peerIP && it->advrouter == routerId) 00321 return it->remote; 00322 error("not a local peer: %s", peerIP.str().c_str()); 00323 return IPAddress(); // prevent warning 00324 } 00325 00326 bool TED::isLocalPeer(IPAddress inetAddr) 00327 { 00328 std::vector<TELinkStateInfo>::iterator it; 00329 for (it = ted.begin(); it != ted.end(); it++) 00330 if (it->linkid == inetAddr && it->advrouter == routerId) 00331 break; 00332 return it != ted.end(); 00333 } 00334 00335 std::vector<TED::vertex_t> TED::calculateShortestPaths(const TELinkStateInfoVector& topology, 00336 double req_bandwidth, int priority) 00337 { 00338 std::vector<vertex_t> vertices; 00339 std::vector<edge_t> edges; 00340 00341 // select edges that have enough bandwidth left, and store them into edges[]. 00342 // meanwhile, collect vertices in vectices[]. 00343 for (unsigned int i = 0; i < topology.size(); i++) 00344 { 00345 if (!topology[i].state) 00346 continue; 00347 00348 if (topology[i].UnResvBandwidth[priority] < req_bandwidth) 00349 continue; 00350 00351 edge_t edge; 00352 edge.src = assignIndex(vertices, topology[i].advrouter); 00353 edge.dest = assignIndex(vertices, topology[i].linkid); 00354 edge.metric = topology[i].metric; 00355 edges.push_back(edge); 00356 } 00357 00358 IPAddress srcAddr = routerId; 00359 00360 int srcIndex = assignIndex(vertices, srcAddr); 00361 vertices[srcIndex].dist = 0.0; 00362 00363 // FIXME comment: Dijkstra? just guessing... 00364 for (unsigned int i = 1; i < vertices.size(); i++) 00365 { 00366 bool mod = false; 00367 00368 for (unsigned int j = 0; j < edges.size(); j++) 00369 { 00370 int src = edges[j].src; 00371 int dest = edges[j].dest; 00372 00373 ASSERT(src >= 0); 00374 ASSERT(dest >= 0); 00375 ASSERT(src < (int)vertices.size()); 00376 ASSERT(dest < (int)vertices.size()); 00377 ASSERT(src != dest); 00378 00379 if (vertices[src].dist + edges[j].metric >= vertices[dest].dist) 00380 continue; 00381 00382 vertices[dest].dist = vertices[src].dist + edges[j].metric; 00383 vertices[dest].parent = src; 00384 00385 mod = true; 00386 } 00387 00388 if (!mod) 00389 break; 00390 } 00391 00392 return vertices; 00393 } 00394 00395 bool TED::checkLinkValidity(TELinkStateInfo link, TELinkStateInfo *&match) 00396 { 00397 std::vector<TELinkStateInfo>::iterator it; 00398 00399 match = NULL; 00400 00401 for (it = ted.begin(); it != ted.end(); it++) 00402 { 00403 if (it->sourceId == link.sourceId && it->messageId == link.messageId && it->timestamp == link.timestamp) 00404 { 00405 // we've already seen this message, ignore it 00406 return false; 00407 } 00408 00409 if (it->advrouter == link.advrouter && it->linkid == link.linkid) 00410 { 00411 // we've have info about this link 00412 00413 if (it->timestamp < link.timestamp || (it->timestamp == link.timestamp && it->messageId < link.messageId)) 00414 { 00415 // but it's older, use this new 00416 match = &(*it); 00417 break; 00418 } 00419 else 00420 { 00421 // and it's newer, forget this message 00422 return false; 00423 } 00424 } 00425 } 00426 00427 // no or not up2date info, link is interesting 00428 return true; 00429 } 00430 00431 unsigned int TED::linkIndex(IPAddress localInf) 00432 { 00433 for (unsigned int i = 0; i < ted.size(); i++) 00434 if (ted[i].advrouter == routerId && ted[i].local == localInf) 00435 return i; 00436 ASSERT(false); 00437 return -1; // to eliminate warning 00438 } 00439 00440 unsigned int TED::linkIndex(IPAddress advrouter, IPAddress linkid) 00441 { 00442 for (unsigned int i = 0; i < ted.size(); i++) 00443 if (ted[i].advrouter == advrouter && ted[i].linkid == linkid) 00444 return i; 00445 ASSERT(false); 00446 return -1; // to eliminate warning 00447 } 00448 00449 bool TED::isLocalAddress(IPAddress addr) 00450 { 00451 for (unsigned int i = 0; i < interfaceAddrs.size(); i++) 00452 if (interfaceAddrs[i] == addr) 00453 return true; 00454 return false; 00455 } 00456 00457 void TED::updateTimestamp(TELinkStateInfo *link) 00458 { 00459 ASSERT(link->advrouter == routerId); 00460 00461 link->timestamp = simTime(); 00462 link->messageId = ++maxMessageId; 00463 } 00464 00465 IPAddressVector TED::getLocalAddress() 00466 { 00467 return interfaceAddrs; 00468 } 00469 00470 IPAddress TED::primaryAddress(IPAddress localInf) // only used in RSVP::processHelloMsg 00471 { 00472 for (unsigned int i = 0; i < ted.size(); i++) 00473 { 00474 if (ted[i].local == localInf) 00475 return ted[i].advrouter; 00476 00477 if (ted[i].remote == localInf) 00478 return ted[i].linkid; 00479 } 00480 ASSERT(false); 00481 return IPAddress(); // to eliminate warning 00482 } 00483 00484 IPAddress TED::getPeerByLocalAddress(IPAddress localInf) 00485 { 00486 unsigned int index = linkIndex(localInf); 00487 return ted[index].linkid; 00488 } 00489 00490 00491