#include <TED.h>
See NED file for more info.
Public Member Functions | |
TED () | |
virtual | ~TED () |
virtual bool | checkLinkValidity (TELinkStateInfo link, TELinkStateInfo *&match) |
virtual void | updateTimestamp (TELinkStateInfo *link) |
Public interface to the Traffic Engineering Database | |
virtual IPAddress | getInterfaceAddrByPeerAddress (IPAddress peerIP) |
virtual IPAddress | peerRemoteInterface (IPAddress peerIP) |
virtual IPAddress | getPeerByLocalAddress (IPAddress localInf) |
virtual IPAddress | primaryAddress (IPAddress localInf) |
virtual bool | isLocalPeer (IPAddress inetAddr) |
virtual bool | isLocalAddress (IPAddress addr) |
virtual unsigned int | linkIndex (IPAddress localInf) |
virtual unsigned int | linkIndex (IPAddress advrouter, IPAddress linkid) |
virtual IPAddressVector | getLocalAddress () |
virtual void | rebuildRoutingTable () |
Public Attributes | |
TELinkStateInfoVector | ted |
Protected Member Functions | |
virtual void | initialize (int stage) |
virtual int | numInitStages () const |
virtual void | handleMessage (cMessage *msg) |
virtual IPAddressVector | calculateShortestPath (IPAddressVector dest, const TELinkStateInfoVector &topology, double req_bandwidth, int priority) |
virtual int | assignIndex (std::vector< vertex_t > &vertices, IPAddress nodeAddr) |
std::vector< vertex_t > | calculateShortestPaths (const TELinkStateInfoVector &topology, double req_bandwidth, int priority) |
Protected Attributes | |
IRoutingTable * | rt |
IInterfaceTable * | ift |
IPAddress | routerId |
NotificationBoard * | nb |
IPAddressVector | interfaceAddrs |
int | maxMessageId |
Classes | |
struct | edge_t |
struct | vertex_t |
void TED::initialize | ( | int | stage | ) | [protected, virtual] |
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 }
void TED::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
IPAddressVector TED::calculateShortestPath | ( | IPAddressVector | dest, | |
const TELinkStateInfoVector & | topology, | |||
double | req_bandwidth, | |||
int | priority | |||
) | [protected, virtual] |
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 }
Referenced by RSVP::commitResv(), RSVP::delSession(), RSVP::evalNextHopInterface(), RSVP::pathProblem(), RSVP::processPathTearMsg(), RSVP::processPSB_TIMEOUT(), and rebuildRoutingTable().
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 }
Referenced by RSVP::refreshResv().
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 }
Referenced by RSVP::evalNextHopInterface(), RSVP::pathProblem(), rebuildRoutingTable(), RSVP::refreshPath(), and RSVP::setupHello().
Referenced by 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 }
bool TED::isLocalPeer | ( | IPAddress | inetAddr | ) | [virtual] |
Referenced by peerRemoteInterface(), and rebuildRoutingTable().
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 }
bool TED::isLocalAddress | ( | IPAddress | addr | ) | [virtual] |
Referenced by RSVP::allocateResource(), RSVP::commitResv(), RSVP::createPSB(), RSVP::doCACCheck(), RSVP::evalNextHopInterface(), RSVP::preempt(), RSVP::processPathMsg(), RSVP::processPSB_TIMEOUT(), RSVP::processRSB_TIMEOUT(), RSVP::refreshPath(), RSVP::refreshResv(), and RSVP::scheduleRefreshTimer().
00450 { 00451 for (unsigned int i = 0; i < interfaceAddrs.size(); i++) 00452 if (interfaceAddrs[i] == addr) 00453 return true; 00454 return false; 00455 }
unsigned int TED::linkIndex | ( | IPAddress | localInf | ) | [virtual] |
Referenced by RSVP::allocateResource(), RSVP::doCACCheck(), getPeerByLocalAddress(), RSVP::preempt(), RSVP::processHELLO_TIMEOUT(), LDP::processHelloTimeout(), LDP::processLDPHello(), RSVP::processPathMsg(), and RSVP::recoveryEvent().
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 }
IPAddressVector TED::getLocalAddress | ( | ) | [virtual] |
void TED::rebuildRoutingTable | ( | ) | [virtual] |
Referenced by initialize(), RSVP::processHELLO_TIMEOUT(), LDP::processHelloTimeout(), LDP::processLDPHello(), LinkStateRouting::processLINK_STATE_MESSAGE(), and RSVP::recoveryEvent().
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 }
int TED::assignIndex | ( | std::vector< vertex_t > & | vertices, | |
IPAddress | nodeAddr | |||
) | [protected, virtual] |
Referenced by calculateShortestPaths().
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 }
std::vector< TED::vertex_t > TED::calculateShortestPaths | ( | const TELinkStateInfoVector & | topology, | |
double | req_bandwidth, | |||
int | priority | |||
) | [protected] |
Referenced by calculateShortestPath(), and rebuildRoutingTable().
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 }
bool TED::checkLinkValidity | ( | TELinkStateInfo | link, | |
TELinkStateInfo *& | match | |||
) | [virtual] |
Referenced by LinkStateRouting::processLINK_STATE_MESSAGE().
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 }
void TED::updateTimestamp | ( | TELinkStateInfo * | link | ) | [virtual] |
Referenced by LinkStateRouting::receiveChangeNotification().
00458 { 00459 ASSERT(link->advrouter == routerId); 00460 00461 link->timestamp = simTime(); 00462 link->messageId = ++maxMessageId; 00463 }
TELinkStateInfoVector TED::ted |
The link state database. (TELinkStateInfoVector is defined in TED.msg)
Referenced by RSVP::allocateResource(), checkLinkValidity(), RSVP::doCACCheck(), getInterfaceAddrByPeerAddress(), getPeerByLocalAddress(), LinkStateRouting::handleMessage(), initialize(), isLocalPeer(), linkIndex(), peerRemoteInterface(), RSVP::preempt(), primaryAddress(), RSVP::processHELLO_TIMEOUT(), LDP::processHelloTimeout(), LDP::processLDPHello(), LinkStateRouting::processLINK_STATE_MESSAGE(), RSVP::processPathMsg(), rebuildRoutingTable(), LinkStateRouting::receiveChangeNotification(), RSVP::recoveryEvent(), and LinkStateRouting::sendToPeers().
IRoutingTable* TED::rt [protected] |
Referenced by initialize(), and rebuildRoutingTable().
IInterfaceTable* TED::ift [protected] |
Referenced by initialize().
IPAddress TED::routerId [protected] |
NotificationBoard* TED::nb [protected] |
Referenced by initialize().
IPAddressVector TED::interfaceAddrs [protected] |
Referenced by getLocalAddress(), initialize(), isLocalAddress(), and rebuildRoutingTable().
int TED::maxMessageId [protected] |
Referenced by initialize(), and updateTimestamp().