TED.cc

Go to the documentation of this file.
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