Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TED Class Reference

#include <TED.h>

List of all members.


Detailed Description

Contains the Traffic Engineering Database and provides public methods to access it from MPLS signalling protocols (LDP, RSVP-TE).

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_tcalculateShortestPaths (const TELinkStateInfoVector &topology, double req_bandwidth, int priority)

Private Attributes

RoutingTablert
InterfaceTableift
IPAddress routerId
NotificationBoardnb
IPAddressVector interfaceAddrs
int maxMessageId

Classes

struct  edge_t
struct  vertex_t


Constructor & Destructor Documentation

TED::TED  ) 
 

00031 {
00032 }

TED::~TED  )  [virtual]
 

00035 {
00036 }


Member Function Documentation

int TED::assignIndex std::vector< vertex_t > &  vertices,
IPAddress  nodeAddr
[private]
 

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 }

IPAddressVector TED::calculateShortestPath IPAddressVector  dest,
const TELinkStateInfoVector topology,
double  req_bandwidth,
int  priority
[protected]
 

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 }

std::vector< TED::vertex_t > TED::calculateShortestPaths const TELinkStateInfoVector topology,
double  req_bandwidth,
int  priority
[private]
 

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 }

bool TED::checkLinkValidity TELinkStateInfo  link,
TELinkStateInfo *&  match
 

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 }

IPAddressVector TED::getLocalAddress  ) 
 

00469 {
00470     return interfaceAddrs;
00471 }

void TED::handleMessage cMessage *  msg  )  [protected, virtual]
 

00135 {
00136     ASSERT(false);
00137 }

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->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 }

IPAddress TED::interfaceAddrByPeerAddress IPAddress  peerIP  ) 
 

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 }

bool TED::isLocalAddress IPAddress  addr  ) 
 

00453 {
00454     for (unsigned int i = 0; i < interfaceAddrs.size(); i++)
00455         if(interfaceAddrs[i] == addr)
00456             return true;
00457     return false;
00458 }

bool TED::isLocalPeer IPAddress  inetAddr  ) 
 

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 }

unsigned int TED::linkIndex IPAddress  advrouter,
IPAddress  linkid
 

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 }

unsigned int TED::linkIndex IPAddress  localInf  ) 
 

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 }

virtual int TED::numInitStages  )  const [inline, protected, virtual]
 

00070 {return 5;}

IPAddress TED::peerByLocalAddress IPAddress  localInf  ) 
 

00487 {
00488     unsigned int index = linkIndex(localInf);
00489     return ted[index].linkid;
00490 }

IPAddress TED::peerRemoteInterface IPAddress  peerIP  ) 
 

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 }

IPAddress TED::primaryAddress IPAddress  localInf  ) 
 

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 }

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->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 }

void TED::updateTimestamp TELinkStateInfo link  ) 
 

00461 {
00462     ASSERT(link->advrouter == routerId);
00463 
00464     link->timestamp = simTime();
00465     link->messageId = ++maxMessageId;
00466 }


Member Data Documentation

InterfaceTable* TED::ift [private]
 

IPAddressVector TED::interfaceAddrs [private]
 

int TED::maxMessageId [private]
 

NotificationBoard* TED::nb [private]
 

IPAddress TED::routerId [private]
 

RoutingTable* TED::rt [private]
 

TELinkStateInfoVector TED::ted
 

The link state database. (TELinkStateInfoVector is defined in TED.msg)


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:32 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0