#include <TED.h>
See NED file for more info.
Public Member Functions | |
| TED () | |
| virtual | ~TED () |
| bool | checkLinkValidity (TELinkStateInfo link, TELinkStateInfo *&match) |
| void | updateTimestamp (TELinkStateInfo *link) |
Public interface to the Traffic Engineering Database | |
| IPAddress | interfaceAddrByPeerAddress (IPAddress peerIP) |
| IPAddress | peerRemoteInterface (IPAddress peerIP) |
| IPAddress | peerByLocalAddress (IPAddress localInf) |
| IPAddress | primaryAddress (IPAddress localInf) |
| bool | isLocalPeer (IPAddress inetAddr) |
| bool | isLocalAddress (IPAddress addr) |
| unsigned int | linkIndex (IPAddress localInf) |
| unsigned int | linkIndex (IPAddress advrouter, IPAddress linkid) |
| IPAddressVector | getLocalAddress () |
| void | rebuildRoutingTable () |
Public Attributes | |
| TELinkStateInfoVector | ted |
Protected Member Functions | |
| virtual void | initialize (int stage) |
| virtual int | numInitStages () const |
| virtual void | handleMessage (cMessage *msg) |
| IPAddressVector | calculateShortestPath (IPAddressVector dest, const TELinkStateInfoVector &topology, double req_bandwidth, int priority) |
Private Member Functions | |
| int | assignIndex (std::vector< vertex_t > &vertices, IPAddress nodeAddr) |
| std::vector< vertex_t > | calculateShortestPaths (const TELinkStateInfoVector &topology, double req_bandwidth, int priority) |
Private Attributes | |
| RoutingTable * | rt |
| InterfaceTable * | ift |
| IPAddress | routerId |
| NotificationBoard * | nb |
| IPAddressVector | interfaceAddrs |
| int | maxMessageId |
Classes | |
| struct | edge_t |
| struct | vertex_t |
|
|
00031 {
00032 }
|
|
|
00035 {
00036 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
00342 {
00343 std::vector<vertex_t> vertices;
00344 std::vector<edge_t> edges;
00345
00346 // select edges that have enough bandwidth left, and store them into edges[].
00347 // meanwhile, collect vertices in vectices[].
00348 for (unsigned int i = 0; i < topology.size(); i++)
00349 {
00350 if(!topology[i].state)
00351 continue;
00352
00353 if(topology[i].UnResvBandwidth[priority] < req_bandwidth)
00354 continue;
00355
00356 edge_t edge;
00357 edge.src = assignIndex(vertices, topology[i].advrouter);
00358 edge.dest = assignIndex(vertices, topology[i].linkid);
00359 edge.metric = topology[i].metric;
00360 edges.push_back(edge);
00361 }
00362
00363 IPAddress srcAddr = routerId;
00364
00365 int srcIndex = assignIndex(vertices, srcAddr);
00366 vertices[srcIndex].dist = 0.0;
00367
00368 // FIXME comment: Dijkstra? just guessing...
00369 for (unsigned int i = 1; i < vertices.size(); i++)
00370 {
00371 bool mod = false;
00372
00373 for (unsigned int j = 0; j < edges.size(); j++)
00374 {
00375 int src = edges[j].src;
00376 int dest = edges[j].dest;
00377
00378 ASSERT(src >= 0);
00379 ASSERT(dest >= 0);
00380 ASSERT(src < vertices.size());
00381 ASSERT(dest < vertices.size());
00382 ASSERT(src != dest);
00383
00384 if(vertices[src].dist + edges[j].metric >= vertices[dest].dist)
00385 continue;
00386
00387 vertices[dest].dist = vertices[src].dist + edges[j].metric;
00388 vertices[dest].parent = src;
00389
00390 mod = true;
00391 }
00392
00393 if(!mod)
00394 break;
00395 }
00396
00397 return vertices;
00398 }
|
|
||||||||||||
|
00401 {
00402 std::vector<TELinkStateInfo>::iterator it;
00403
00404 match = NULL;
00405
00406 for(it = ted.begin(); it != ted.end(); it++)
00407 {
00408 if(it->sourceId == link.sourceId && it->messageId == link.messageId && it->timestamp == link.timestamp)
00409 {
00410 // we've already seen this message, ignore it
00411 return false;
00412 }
00413
00414 if(it->advrouter == link.advrouter && it->linkid == link.linkid)
00415 {
00416 // we've have info about this link
00417
00418 if(it->timestamp < link.timestamp || (it->timestamp == link.timestamp && it->messageId < link.messageId))
00419 {
00420 // but it's older, use this new
00421 match = &(*it);
00422 break;
00423 }
00424 else
00425 {
00426 // and it's newer, forget this message
00427 return false;
00428 }
00429 }
00430 }
00431
00432 // no or not up2date info, link is interesting
00433 return true;
00434 }
|
|
|
00469 {
00470 return interfaceAddrs;
00471 }
|
|
|
00135 {
00136 ASSERT(false);
00137 }
|
|
|
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->routerId();
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->numInterfaces(); i++)
00062 {
00063 InterfaceEntry *ie = ift->interfaceAt(i);
00064
00065 if (ie->nodeOutputGateId() == -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 RoutingEntry *rentry = NULL;
00076 for (int j = 0; j < rt->numRoutingEntries(); j++)
00077 {
00078 rentry = rt->routingEntry(j);
00079 if (rentry->interfacePtr == ie && rentry->type == RoutingEntry::DIRECT)
00080 break;
00081 }
00082 ASSERT(rentry);
00083 IPAddress linkid = rentry->host;
00084 IPAddress remote = rentry->gateway;
00085 ASSERT(!remote.isUnspecified());
00086
00087 // find bandwidth of the link
00088 cGate *g = parentModule()->gate(ie->nodeOutputGateId());
00089 ASSERT(g);
00090 double linkBandwidth = g->datarate()->doubleValue();
00091
00092 //
00093 // fill in and insert TED entry
00094 //
00095 TELinkStateInfo entry;
00096 entry.advrouter = routerId;
00097 entry.local = ie->ipv4()->inetAddress();
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->delay()->doubleValue() for shortest delay calculation
00106 entry.metric = rentry->interfacePtr->ipv4()->metric();
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->numInterfaces(); i++)
00119 {
00120 InterfaceEntry *ie = ift->interfaceAt(i);
00121 if (rt->interfaceByAddress(ie->ipv4()->inetAddress()) != ie)
00122 error("MPLS models assume interfaces to have unique addresses, "
00123 "but address of '%s' (%s) is not unique",
00124 ie->name(), ie->ipv4()->inetAddress().str().c_str());
00125 if (!ie->isLoopback())
00126 interfaceAddrs.push_back(ie->ipv4()->inetAddress());
00127 }
00128
00129 rebuildRoutingTable();
00130
00131 WATCH_VECTOR(ted);
00132 }
|
|
|
00311 {
00312 std::vector<TELinkStateInfo>::iterator it;
00313 for (it = ted.begin(); it != ted.end(); it++)
00314 if (it->linkid == peerIP && it->advrouter == routerId)
00315 return it->local;
00316 error("not a local peer: %s", peerIP.str().c_str());
00317 return IPAddress(); // prevent warning
00318 }
|
|
|
00453 {
00454 for (unsigned int i = 0; i < interfaceAddrs.size(); i++)
00455 if(interfaceAddrs[i] == addr)
00456 return true;
00457 return false;
00458 }
|
|
|
00332 {
00333 std::vector<TELinkStateInfo>::iterator it;
00334 for (it = ted.begin(); it != ted.end(); it++)
00335 if (it->linkid == inetAddr && it->advrouter == routerId)
00336 break;
00337 return it != ted.end();
00338 }
|
|
||||||||||||
|
00445 {
00446 for (unsigned int i = 0; i < ted.size(); i++)
00447 if(ted[i].advrouter == advrouter && ted[i].linkid == linkid)
00448 return i;
00449 ASSERT(false);
00450 }
|
|
|
00437 {
00438 for (unsigned int i = 0; i < ted.size(); i++)
00439 if (ted[i].advrouter == routerId && ted[i].local == localInf)
00440 return i;
00441 ASSERT(false);
00442 }
|
|
|
00070 {return 5;}
|
|
|
|
|
|
00321 {
00322 ASSERT(isLocalPeer(peerIP));
00323 std::vector<TELinkStateInfo>::iterator it;
00324 for (it = ted.begin(); it != ted.end(); it++)
00325 if (it->linkid == peerIP && it->advrouter == routerId)
00326 return it->remote;
00327 error("not a local peer: %s", peerIP.str().c_str());
00328 return IPAddress(); // prevent warning
00329 }
|
|
|
00474 {
00475 for (unsigned int i = 0; i < ted.size(); i++)
00476 {
00477 if(ted[i].local == localInf)
00478 return ted[i].advrouter;
00479
00480 if(ted[i].remote == localInf)
00481 return ted[i].linkid;
00482 }
00483 ASSERT(false);
00484 }
|
|
|
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->numRoutingEntries();
00217 int j = 0;
00218 for (int i = 0; i < n; i++)
00219 {
00220 RoutingEntry *entry = rt->routingEntry(j);
00221 if (entry->host.isMulticast())
00222 {
00223 ++j;
00224 }
00225 else
00226 {
00227 rt->deleteRoutingEntry(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 RoutingEntry *entry = new RoutingEntry;
00261 entry->host = V[i].node;
00262
00263 if (V[i].node == V[nHop].node)
00264 {
00265 entry->gateway = IPAddress();
00266 entry->type = entry->DIRECT;
00267 }
00268 else
00269 {
00270 entry->gateway = V[nHop].node;
00271 entry->type = entry->REMOTE;
00272 }
00273 entry->interfacePtr = rt->interfaceByAddress(interfaceAddrByPeerAddress(V[nHop].node));
00274 entry->interfaceName = opp_string(entry->interfacePtr->name());
00275 entry->source = RoutingEntry::OSPF;
00276
00277 entry->netmask = 0xffffffff;
00278 entry->metric = 0;
00279
00280 EV << " inserting route: host=" << entry->host << " interface=" << entry->interfaceName << " nexthop=" << entry->gateway << "\n";
00281
00282 rt->addRoutingEntry(entry);
00283 }
00284
00285 // insert local peers
00286
00287 for (unsigned int i = 0; i < interfaceAddrs.size(); i++)
00288 {
00289 RoutingEntry *entry = new RoutingEntry;
00290
00291 entry->host = peerByLocalAddress(interfaceAddrs[i]);
00292 entry->gateway = IPAddress();
00293 entry->type = entry->DIRECT;
00294 entry->interfacePtr = rt->interfaceByAddress(interfaceAddrs[i]);
00295 entry->interfaceName = opp_string(entry->interfacePtr->name());
00296 entry->source = RoutingEntry::OSPF;
00297
00298 entry->netmask = 0xffffffff;
00299 entry->metric = 0; // XXX FIXME what's that?
00300
00301 EV << " inserting route: local=" << interfaceAddrs[i] << " peer=" << entry->host << " interface=" << entry->interfaceName << "\n";
00302
00303 rt->addRoutingEntry(entry);
00304 }
00305
00306 nb->fireChangeNotification(NF_IPv4_ROUTINGTABLE_CHANGED);
00307
00308 }
|
|
|
00461 {
00462 ASSERT(link->advrouter == routerId);
00463
00464 link->timestamp = simTime();
00465 link->messageId = ++maxMessageId;
00466 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The link state database. (TELinkStateInfoVector is defined in TED.msg) |
1.4.1