LDP Class Reference

#include <LDP.h>

Inheritance diagram for LDP:

TCPSocket::CallbackInterface IClassifier INotifiable

List of all members.


Detailed Description

LDP (rfc 3036) protocol implementation.

Public Types

typedef std::vector< fec_tFecVector
typedef std::vector< fec_bind_tFecBindVector
typedef std::vector
< pending_req_t
PendingVector
typedef std::vector< peer_infoPeerVector

Public Member Functions

 LDP ()
virtual ~LDP ()

Protected Member Functions

virtual IPAddress locateNextHop (IPAddress dest)
virtual IPAddress findPeerAddrFromInterface (std::string interfaceName)
std::string findInterfaceFromPeerAddr (IPAddress peerIP)
virtual int findPeer (IPAddress peerAddr)
virtual TCPSocketgetPeerSocket (IPAddress peerAddr)
virtual TCPSocketfindPeerSocket (IPAddress peerAddr)
virtual void sendToPeer (IPAddress dest, cMessage *msg)
FecVector::iterator findFecEntry (FecVector &fecs, IPAddress addr, int length)
FecBindVector::iterator findFecEntry (FecBindVector &fecs, int fecid, IPAddress peer)
virtual void sendMappingRequest (IPAddress dest, IPAddress addr, int length)
virtual void sendMapping (int type, IPAddress dest, int label, IPAddress addr, int length)
virtual void sendNotify (int status, IPAddress dest, IPAddress addr, int length)
virtual void rebuildFecList ()
virtual void updateFecList (IPAddress nextHop)
virtual void updateFecListEntry (fec_t oldItem)
virtual void announceLinkChange (int tedlinkindex)
virtual int numInitStages () const
virtual void initialize (int stage)
virtual void handleMessage (cMessage *msg)
virtual void sendHelloTo (IPAddress dest)
virtual void openTCPConnectionToPeer (int peerIndex)
virtual void processLDPHello (LDPHello *msg)
virtual void processHelloTimeout (cMessage *msg)
virtual void processMessageFromTCP (cMessage *msg)
virtual void processLDPPacketFromTCP (LDPPacket *ldpPacket)
virtual void processLABEL_MAPPING (LDPLabelMapping *packet)
virtual void processLABEL_REQUEST (LDPLabelRequest *packet)
virtual void processLABEL_RELEASE (LDPLabelMapping *packet)
virtual void processLABEL_WITHDRAW (LDPLabelMapping *packet)
virtual void processNOTIFICATION (LDPNotify *packet)
virtual bool lookupLabel (IPDatagram *ipdatagram, LabelOpVector &outLabel, std::string &outInterface, int &color)
virtual void receiveChangeNotification (int category, const cPolymorphic *details)
TCPSocket::CallbackInterface callback methods


virtual void socketEstablished (int connId, void *yourPtr)
virtual void socketDataArrived (int connId, void *yourPtr, cPacket *msg, bool urgent)
virtual void socketPeerClosed (int connId, void *yourPtr)
virtual void socketClosed (int connId, void *yourPtr)
virtual void socketFailure (int connId, void *yourPtr, int code)
virtual void socketStatusArrived (int connId, void *yourPtr, TCPStatusInfo *status)

Protected Attributes

simtime_t holdTime
simtime_t helloInterval
FecVector fecList
FecBindVector fecUp
FecBindVector fecDown
PendingVector pending
PeerVector myPeers
IInterfaceTableift
IRoutingTablert
LIBTablelt
TEDtedmod
NotificationBoardnb
UDPSocket udpSocket
TCPSocket serverSocket
TCPSocketMap socketMap
cMessage * sendHelloMsg
int maxFecid

Classes

struct  fec_bind_t
struct  fec_t
struct  peer_info
struct  pending_req_t

Member Typedef Documentation

typedef std::vector<fec_t> LDP::FecVector

typedef std::vector<fec_bind_t> LDP::FecBindVector

typedef std::vector<pending_req_t> LDP::PendingVector

typedef std::vector<peer_info> LDP::PeerVector


Constructor & Destructor Documentation

LDP::LDP (  ) 

00085 {
00086     sendHelloMsg = NULL;
00087 }

LDP::~LDP (  )  [virtual]

00090 {
00091     for (unsigned int i=0; i<myPeers.size(); i++)
00092         cancelAndDelete(myPeers[i].timeout);
00093 
00094     cancelAndDelete(sendHelloMsg);
00095     //this causes segfault at the end of simulation       -- Vojta
00096     //socketMap.deleteSockets();
00097 }


Member Function Documentation

IPAddress LDP::locateNextHop ( IPAddress  dest  )  [protected, virtual]

This method finds next peer in upstream direction

00690 {
00691     // Mapping L3 IP-host of next hop to L2 peer address.
00692 
00693     // Lookup the routing table, rfc3036
00694     // "When the FEC for which a label is requested is a Prefix FEC Element or
00695     //  a Host Address FEC Element, the receiving LSR uses its routing table to determine
00696     //  its response. Unless its routing table includes an entry that exactly matches
00697     //  the requested Prefix or Host Address, the LSR must respond with a
00698     //  No Route Notification message."
00699     //
00700     // FIXME the code below (though seems like that's what the RFC refers to) doesn't work
00701     // -- we can't reasonably expect the destination host to be exaplicitly in an
00702     // LSR's routing table!!! Use simple IP routing instead. --Andras
00703     //
00704     // Wrong code:
00705     //int i;
00706     //for (i=0; i < rt->getNumRoutes(); i++)
00707     //    if (rt->getRoute(i)->host == dest)
00708     //        break;
00709     //
00710     //if (i == rt->getNumRoutes())
00711     //    return IPAddress();  // Signal an NOTIFICATION of NO ROUTE
00712     //
00713     InterfaceEntry *ie = rt->getInterfaceForDestAddr(dest);
00714     if (!ie)
00715         return IPAddress();  // no route
00716 
00717     std::string iName = ie->getName(); // FIXME why use name for lookup?
00718     return findPeerAddrFromInterface(iName);
00719 }

IPAddress LDP::findPeerAddrFromInterface ( std::string  interfaceName  )  [protected, virtual]

This method maps the peerIP with the interface name in routing table. It is expected that for MPLS host, entries linked to MPLS peers are available. In case no corresponding peerIP found, a peerIP (not deterministic) will be returned.

Referenced by locateNextHop().

00724 {
00725     int i = 0;
00726     int k = 0;
00727     InterfaceEntry *ie = ift->getInterfaceByName(interfaceName.c_str());
00728 
00729     const IPRoute *anEntry;
00730 
00731     for (i = 0; i < rt->getNumRoutes(); i++)
00732     {
00733         for (k = 0; k < (int)myPeers.size(); k++)
00734         {
00735             anEntry = rt->getRoute(i);
00736             if (anEntry->getHost()==myPeers[k].peerIP && anEntry->getInterface()==ie)
00737             {
00738                 return myPeers[k].peerIP;
00739             }
00740             // addresses->push_back(peerIP[k]);
00741         }
00742     }
00743 
00744     // Return any IP which has default route - not in routing table entries
00745     for (i = 0; i < (int)myPeers.size(); i++)
00746     {
00747         for (k = 0; k < rt->getNumRoutes(); k++)
00748         {
00749             anEntry = rt->getRoute(i);
00750             if (anEntry->getHost() == myPeers[i].peerIP)
00751                 break;
00752         }
00753         if (k == rt->getNumRoutes())
00754             break;
00755     }
00756 
00757     // return the peer's address if found, unspecified address otherwise
00758     return i==(int)myPeers.size() ? IPAddress() : myPeers[i].peerIP;
00759 }

std::string LDP::findInterfaceFromPeerAddr ( IPAddress  peerIP  )  [protected]

Referenced by lookupLabel(), processLABEL_MAPPING(), processLABEL_REQUEST(), and updateFecListEntry().

00763 {
00764 /*
00765     int i;
00766     for (unsigned int i=0;i<myPeers.size();i++)
00767     {
00768         if (myPeers[i].peerIP == peerIP)
00769             return string(myPeers[i].linkInterface);
00770     }
00771     return string("X");
00772 */
00773 //    Rely on port index to find the interface name
00774 
00775     // this function is a misnomer, we must recognize our own address too
00776     if (rt->isLocalAddress(peerIP))
00777         return "lo0";
00778 
00779     InterfaceEntry *ie = rt->getInterfaceForDestAddr(peerIP);
00780     if (!ie)
00781         error("findInterfaceFromPeerAddr(): %s is not routable", peerIP.str().c_str());
00782     return ie->getName();
00783 }

int LDP::findPeer ( IPAddress  peerAddr  )  [protected, virtual]

Utility: return peer's index in myPeers table, or -1 if not found

Referenced by findPeerSocket(), processLDPHello(), and processMessageFromTCP().

01161 {
01162     for (PeerVector::iterator i=myPeers.begin(); i!=myPeers.end(); ++i)
01163         if (i->peerIP==peerAddr)
01164             return i-myPeers.begin();
01165     return -1;
01166 }

TCPSocket * LDP::getPeerSocket ( IPAddress  peerAddr  )  [protected, virtual]

Utility: return socket for given peer. Throws error if there's no TCP connection

Referenced by sendToPeer().

01178 {
01179     TCPSocket *sock = findPeerSocket(peerAddr);
01180     ASSERT(sock);
01181     if (!sock)
01182         error("No LDP session to peer %s yet", peerAddr.str().c_str());
01183     return sock;
01184 }

TCPSocket * LDP::findPeerSocket ( IPAddress  peerAddr  )  [protected, virtual]

Utility: return socket for given peer, and NULL if session doesn't exist

Referenced by getPeerSocket(), processLABEL_REQUEST(), and updateFecListEntry().

01169 {
01170     // find peer in table and return its socket
01171     int i = findPeer(peerAddr);
01172     if (i==-1 || !(myPeers[i].socket) || myPeers[i].socket->getState()!=TCPSocket::CONNECTED)
01173         return NULL; // we don't have an LDP session to this peer
01174     return myPeers[i].socket;
01175 }

void LDP::sendToPeer ( IPAddress  dest,
cMessage *  msg 
) [protected, virtual]

Referenced by processLABEL_WITHDRAW(), sendMapping(), sendMappingRequest(), and sendNotify().

00180 {
00181     getPeerSocket(dest)->send(msg);
00182 }

LDP::FecVector::iterator LDP::findFecEntry ( FecVector fecs,
IPAddress  addr,
int  length 
) [protected]

Referenced by lookupLabel(), processLABEL_MAPPING(), processLABEL_RELEASE(), processLABEL_REQUEST(), processLABEL_WITHDRAW(), processNOTIFICATION(), rebuildFecList(), and updateFecListEntry().

00807 {
00808     FecVector::iterator it;
00809     for (it = fecs.begin(); it != fecs.end(); it++)
00810     {
00811         if (it->length != length)
00812             continue;
00813 
00814         if (it->addr != addr) // XXX compare only relevant part (?)
00815             continue;
00816 
00817         break;
00818     }
00819     return it;
00820 }

LDP::FecBindVector::iterator LDP::findFecEntry ( FecBindVector fecs,
int  fecid,
IPAddress  peer 
) [protected]

00791 {
00792     FecBindVector::iterator it;
00793     for (it = fecs.begin(); it != fecs.end(); it++)
00794     {
00795         if (it->fecid != fecid)
00796             continue;
00797 
00798         if (it->peer != peer)
00799             continue;
00800 
00801         break;
00802     }
00803     return it;
00804 }

void LDP::sendMappingRequest ( IPAddress  dest,
IPAddress  addr,
int  length 
) [protected, virtual]

Referenced by processNOTIFICATION(), and updateFecListEntry().

00185 {
00186     LDPLabelRequest *requestMsg = new LDPLabelRequest("Lb-Req");
00187     requestMsg->setByteLength(LDP_HEADER_BYTES); // FIXME find out actual length
00188     requestMsg->setType(LABEL_REQUEST);
00189 
00190     FEC_TLV fec;
00191     fec.addr = addr;
00192     fec.length = length;
00193     requestMsg->setFec(fec);
00194 
00195     requestMsg->setReceiverAddress(dest);
00196     requestMsg->setSenderAddress(rt->getRouterId());
00197 
00198     sendToPeer(dest, requestMsg);
00199 }

void LDP::sendMapping ( int  type,
IPAddress  dest,
int  label,
IPAddress  addr,
int  length 
) [protected, virtual]

Referenced by processLABEL_MAPPING(), processLABEL_REQUEST(), rebuildFecList(), and updateFecListEntry().

00842 {
00843     // Send LABEL MAPPING downstream
00844     LDPLabelMapping *lmMessage = new LDPLabelMapping("Lb-Mapping");
00845     lmMessage->setByteLength(LDP_HEADER_BYTES); // FIXME find out actual length
00846     lmMessage->setType(type);
00847     lmMessage->setReceiverAddress(dest);
00848     lmMessage->setSenderAddress(rt->getRouterId());
00849     lmMessage->setLabel(label);
00850 
00851     FEC_TLV fec;
00852     fec.addr = addr;
00853     fec.length = length;
00854 
00855     lmMessage->setFec(fec);
00856 
00857     sendToPeer(dest, lmMessage);
00858 }

void LDP::sendNotify ( int  status,
IPAddress  dest,
IPAddress  addr,
int  length 
) [protected, virtual]

Referenced by processLABEL_REQUEST().

00823 {
00824     // Send NOTIFY message
00825     LDPNotify *lnMessage = new LDPNotify("Lb-Notify");
00826     lnMessage->setByteLength(LDP_HEADER_BYTES); // FIXME find out actual length
00827     lnMessage->setType(NOTIFICATION);
00828     lnMessage->setStatus(NO_ROUTE);
00829     lnMessage->setReceiverAddress(dest);
00830     lnMessage->setSenderAddress(rt->getRouterId());
00831 
00832     FEC_TLV fec;
00833     fec.addr = addr;
00834     fec.length = length;
00835 
00836     lnMessage->setFec(fec);
00837 
00838     sendToPeer(dest, lnMessage);
00839 }

void LDP::rebuildFecList (  )  [protected, virtual]

Referenced by initialize(), and receiveChangeNotification().

00263 {
00264     EV << "make list of recognized FECs" << endl;
00265 
00266     FecVector oldList = fecList;
00267     fecList.clear();
00268 
00269     for (int i = 0; i < rt->getNumRoutes(); i++)
00270     {
00271         // every entry in the routing table
00272 
00273         const IPRoute *re = rt->getRoute(i);
00274 
00275         // ignore multicast routes
00276         if (re->getHost().isMulticast())
00277             continue;
00278 
00279         // find out current next hop according to routing table
00280         IPAddress nextHop = (re->getType() == IPRoute::DIRECT) ? re->getHost() : re->getGateway();
00281         ASSERT(!nextHop.isUnspecified());
00282 
00283         EV << "nextHop <-- " << nextHop << endl;
00284 
00285         FecVector::iterator it = findFecEntry(oldList, re->getHost(), re->getNetmask().getNetmaskLength());
00286 
00287         if (it == oldList.end())
00288         {
00289             // fec didn't exist, it was just created
00290             fec_t newItem;
00291             newItem.fecid = ++maxFecid;
00292             newItem.addr = re->getHost();
00293             newItem.length = re->getNetmask().getNetmaskLength();
00294             newItem.nextHop = nextHop;
00295             updateFecListEntry(newItem);
00296             fecList.push_back(newItem);
00297         }
00298         else if (it->nextHop != nextHop)
00299         {
00300             // next hop for this FEC changed,
00301             it->nextHop = nextHop;
00302             updateFecListEntry(*it);
00303             fecList.push_back(*it);
00304             oldList.erase(it);
00305         }
00306         else
00307         {
00308             // FEC didn't change, reusing old values
00309             fecList.push_back(*it);
00310             oldList.erase(it);
00311             continue;
00312         }
00313     }
00314 
00315 
00316     // our own addresses (XXX is it needed?)
00317 
00318     for (int i = 0; i< ift->getNumInterfaces(); ++i)
00319     {
00320         InterfaceEntry *ie = ift->getInterface(i);
00321         if (ie->getNetworkLayerGateIndex() < 0)
00322             continue;
00323 
00324         FecVector::iterator it = findFecEntry(oldList, ie->ipv4Data()->getIPAddress(), 32);
00325         if (it == oldList.end())
00326         {
00327             fec_t newItem;
00328             newItem.fecid = ++maxFecid;
00329             newItem.addr = ie->ipv4Data()->getIPAddress();
00330             newItem.length = 32;
00331             newItem.nextHop = ie->ipv4Data()->getIPAddress();
00332             fecList.push_back(newItem);
00333         }
00334         else
00335         {
00336             fecList.push_back(*it);
00337             oldList.erase(it);
00338         }
00339     }
00340 
00341     if (oldList.size() > 0)
00342     {
00343         EV << "there are " << oldList.size() << " deprecated FECs, removing them" << endl;
00344 
00345         FecVector::iterator it;
00346         for (it = oldList.begin(); it != oldList.end(); it++)
00347         {
00348             EV << "removing FEC= " << *it << endl;
00349 
00350             FecBindVector::iterator dit;
00351             for (dit = fecDown.begin(); dit != fecDown.end(); dit++)
00352             {
00353                 if (dit->fecid != it->fecid)
00354                     continue;
00355 
00356                 EV << "sending release label=" << dit->label << " downstream to " << dit->peer << endl;
00357 
00358                 sendMapping(LABEL_RELEASE, dit->peer, dit->label, it->addr, it->length);
00359             }
00360 
00361             FecBindVector::iterator uit;
00362             for (uit = fecUp.begin(); uit != fecUp.end(); uit++)
00363             {
00364                 if (uit->fecid != it->fecid)
00365                     continue;
00366 
00367                 EV << "sending withdraw label=" << uit->label << " upstream to " << uit->peer << endl;
00368 
00369                 sendMapping(LABEL_WITHDRAW, uit->peer, uit->label, it->addr, it->length);
00370 
00371                 EV << "removing entry inLabel=" << uit->label << " from LIB" << endl;
00372 
00373                 lt->removeLibEntry(uit->label);
00374             }
00375 
00376         }
00377     }
00378 
00379     // we must keep this list sorted for matching to work correctly
00380     // this is probably slower than it must be
00381     std::sort(fecList.begin(), fecList.end(), fecPrefixCompare);
00382 }

void LDP::updateFecList ( IPAddress  nextHop  )  [protected, virtual]

Referenced by processHelloTimeout(), and socketEstablished().

00385 {
00386     FecVector::iterator it;
00387     for (it = fecList.begin(); it != fecList.end(); it++)
00388     {
00389         if (it->nextHop != nextHop)
00390             continue;
00391 
00392         updateFecListEntry(*it);
00393     }
00394 }

void LDP::updateFecListEntry ( LDP::fec_t  oldItem  )  [protected, virtual]

Referenced by processLABEL_WITHDRAW(), rebuildFecList(), and updateFecList().

00202 {
00203     // do we have mapping from downstream?
00204     FecBindVector::iterator dit = findFecEntry(fecDown, oldItem.fecid, oldItem.nextHop);
00205 
00206     // is next hop our LDP peer?
00207     bool ER = findPeerSocket(oldItem.nextHop)==NULL;
00208 
00209     ASSERT(!(ER && dit != fecDown.end())); // can't be egress and have mapping at the same time
00210 
00211     // adjust upstream mappings
00212     FecBindVector::iterator uit;
00213     for (uit = fecUp.begin(); uit != fecUp.end();)
00214     {
00215         if (uit->fecid != oldItem.fecid)
00216         {
00217                 uit++;
00218             continue;
00219         }
00220 
00221         std::string inInterface = findInterfaceFromPeerAddr(uit->peer);
00222         std::string outInterface = findInterfaceFromPeerAddr(oldItem.nextHop);
00223         if (ER)
00224         {
00225             // we are egress, that's easy:
00226             LabelOpVector outLabel = LIBTable::popLabel();
00227             uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
00228 
00229             EV << "installed (egress) LIB entry inLabel=" << uit->label << " inInterface=" << inInterface <<
00230                     " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
00231             uit++;
00232         }
00233         else if (dit != fecDown.end())
00234         {
00235             // we have mapping from DS, that's easy
00236             LabelOpVector outLabel = LIBTable::swapLabel(dit->label);
00237             uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
00238 
00239             EV << "installed LIB entry inLabel=" << uit->label << " inInterface=" << inInterface <<
00240                     " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
00241             uit++;
00242         }
00243         else
00244         {
00245             // no mapping from DS, withdraw mapping US
00246             EV << "sending withdraw message upstream" << endl;
00247             sendMapping(LABEL_WITHDRAW, uit->peer, uit->label, oldItem.addr, oldItem.length);
00248 
00249             // remove from US mappings
00250             uit = fecUp.erase(uit);
00251         }
00252     }
00253 
00254     if (!ER && dit == fecDown.end())
00255     {
00256         // and ask DS for mapping
00257         EV << "sending request message downstream" << endl;
00258         sendMappingRequest(oldItem.nextHop, oldItem.addr, oldItem.length);
00259     }
00260 }

void LDP::announceLinkChange ( int  tedlinkindex  )  [protected, virtual]

Referenced by processHelloTimeout(), and processLDPHello().

01248 {
01249     TEDChangeInfo d;
01250     d.setTedLinkIndicesArraySize(1);
01251     d.setTedLinkIndices(0, tedlinkindex);
01252     nb->fireChangeNotification(NF_TED_CHANGED, &d);
01253 }

virtual int LDP::numInitStages (  )  const [inline, protected, virtual]

00180 {return 4;}

void LDP::initialize ( int  stage  )  [protected, virtual]

00100 {
00101     if (stage != 3)
00102         return; // wait for routing table to initialize first
00103 
00104     holdTime = par("holdTime").doubleValue();
00105     helloInterval = par("helloInterval").doubleValue();
00106 
00107     ift = InterfaceTableAccess().get();
00108     rt = RoutingTableAccess().get();
00109     lt = LIBTableAccess().get();
00110     tedmod = TEDAccess().get();
00111     nb = NotificationBoardAccess().get();
00112 
00113     WATCH_VECTOR(myPeers);
00114     WATCH_VECTOR(fecUp);
00115     WATCH_VECTOR(fecDown);
00116     WATCH_VECTOR(fecList);
00117     WATCH_VECTOR(pending);
00118 
00119     maxFecid = 0;
00120 
00121     // schedule first hello
00122     sendHelloMsg = new cMessage("LDPSendHello");
00123     scheduleAt(simTime() + exponential(0.1), sendHelloMsg);
00124 
00125     // bind UDP socket
00126     udpSocket.setOutputGate(gate("udpOut"));
00127     udpSocket.bind(LDP_PORT);
00128 
00129     // start listening for incoming TCP conns
00130     EV << "Starting to listen on port " << LDP_PORT << " for incoming LDP sessions\n";
00131     serverSocket.setOutputGate(gate("tcpOut"));
00132     serverSocket.bind(LDP_PORT);
00133     serverSocket.listen();
00134 
00135     // build list of recognized FECs
00136     rebuildFecList();
00137 
00138     // listen for routing table modifications
00139     nb->subscribe(this, NF_IPv4_ROUTE_ADDED);
00140     nb->subscribe(this, NF_IPv4_ROUTE_DELETED);
00141 }

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

00144 {
00145     EV << "Received: (" << msg->getClassName() << ")" << msg->getName() << "\n";
00146     if (msg==sendHelloMsg)
00147     {
00148         // every LDP capable router periodically sends HELLO messages to the
00149         // "all routers in the sub-network" multicast address
00150         EV << "Multicasting LDP Hello to neighboring routers\n";
00151         sendHelloTo(IPAddress::ALL_ROUTERS_MCAST);
00152 
00153         // schedule next hello
00154         scheduleAt(simTime() + helloInterval, sendHelloMsg);
00155     }
00156     else if (msg->isSelfMessage())
00157     {
00158         EV << "Timer " << msg->getName() << " expired\n";
00159         if (!strcmp(msg->getName(), "HelloTimeout"))
00160         {
00161             processHelloTimeout(msg);
00162         }
00163         else
00164         {
00165             processNOTIFICATION(check_and_cast<LDPNotify*>(msg));
00166         }
00167     }
00168     else if (!strcmp(msg->getArrivalGate()->getName(), "udpIn"))
00169     {
00170         // we can only receive LDP Hello from UDP (everything else goes over TCP)
00171         processLDPHello(check_and_cast<LDPHello *>(msg));
00172     }
00173     else if (!strcmp(msg->getArrivalGate()->getName(), "tcpIn"))
00174     {
00175         processMessageFromTCP(msg);
00176     }
00177 }

void LDP::sendHelloTo ( IPAddress  dest  )  [protected, virtual]

Referenced by handleMessage(), and processLDPHello().

00397 {
00398     LDPHello *hello = new LDPHello("LDP-Hello");
00399     hello->setByteLength(LDP_HEADER_BYTES);
00400     hello->setType(HELLO);
00401     hello->setSenderAddress(rt->getRouterId());
00402     //hello->setReceiverAddress(...);
00403     hello->setHoldTime(SIMTIME_DBL(holdTime));
00404     //hello->setRbit(...);
00405     //hello->setTbit(...);
00406     hello->addPar("color") = LDP_HELLO_TRAFFIC;
00407 
00408     udpSocket.sendTo(hello, dest, LDP_PORT);
00409 }

void LDP::openTCPConnectionToPeer ( int  peerIndex  )  [protected, virtual]

Referenced by processLDPHello().

00545 {
00546     TCPSocket *socket = new TCPSocket();
00547     socket->setOutputGate(gate("tcpOut"));
00548     socket->setCallbackObject(this, (void*)peerIndex);
00549     socket->bind(rt->getRouterId(), 0);
00550     socketMap.addSocket(socket);
00551     myPeers[peerIndex].socket = socket;
00552 
00553     socket->connect(myPeers[peerIndex].peerIP, LDP_PORT);
00554 }

void LDP::processLDPHello ( LDPHello *  msg  )  [protected, virtual]

Referenced by handleMessage().

00485 {
00486     UDPControlInfo *controlInfo = check_and_cast<UDPControlInfo *>(msg->getControlInfo());
00487     //IPAddress peerAddr = controlInfo->getSrcAddr().get4();
00488     IPAddress peerAddr = msg->getSenderAddress();
00489     int interfaceId = controlInfo->getInterfaceId();
00490     delete msg;
00491 
00492     EV << "Received LDP Hello from " << peerAddr << ", ";
00493 
00494     if (peerAddr.isUnspecified() || peerAddr==rt->getRouterId())
00495     {
00496         // must be ourselves (we're also in the all-routers multicast group), ignore
00497         EV << "that's myself, ignore\n";
00498         return;
00499     }
00500 
00501     // mark link as working if it was failed, and rebuild table
00502     unsigned int index = tedmod->linkIndex(rt->getRouterId(), peerAddr);
00503     if (!tedmod->ted[index].state)
00504     {
00505         tedmod->ted[index].state = true;
00506         tedmod->rebuildRoutingTable();
00507         announceLinkChange(index);
00508     }
00509 
00510     // peer already in table?
00511     int i = findPeer(peerAddr);
00512     if (i!=-1)
00513     {
00514         EV << "already in my peer table, rescheduling timeout" << endl;
00515         ASSERT(myPeers[i].timeout);
00516         cancelEvent(myPeers[i].timeout);
00517         scheduleAt(simTime() + holdTime, myPeers[i].timeout);
00518         return;
00519     }
00520 
00521     // not in table, add it
00522     peer_info info;
00523     info.peerIP = peerAddr;
00524     info.linkInterface = ift->getInterfaceById(interfaceId)->getName();
00525     info.activeRole = peerAddr.getInt() > rt->getRouterId().getInt();
00526     info.socket = NULL;
00527     info.timeout = new cMessage("HelloTimeout");
00528     scheduleAt(simTime() + holdTime, info.timeout);
00529     myPeers.push_back(info);
00530     int peerIndex = myPeers.size()-1;
00531 
00532     EV << "added to peer table\n";
00533     EV << "We'll be " << (info.activeRole ? "ACTIVE" : "PASSIVE") << " in this session\n";
00534 
00535     // introduce ourselves with a Hello, then connect if we're in ACTIVE role
00536     sendHelloTo(peerAddr);
00537     if (info.activeRole)
00538     {
00539         EV << "Establishing session with it\n";
00540         openTCPConnectionToPeer(peerIndex);
00541     }
00542 }

void LDP::processHelloTimeout ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00412 {
00413     // peer is gone
00414 
00415     unsigned int i;
00416     for (i = 0; i < myPeers.size(); i++)
00417         if (myPeers[i].timeout == msg)
00418             break;
00419     ASSERT(i < myPeers.size());
00420 
00421     IPAddress peerIP = myPeers[i].peerIP;
00422 
00423     EV << "peer=" << peerIP << " is gone, removing adjacency" << endl;
00424 
00425     ASSERT(!myPeers[i].timeout->isScheduled());
00426     delete myPeers[i].timeout;
00427     ASSERT(myPeers[i].socket);
00428     myPeers[i].socket->abort(); // should we only close?
00429     delete myPeers[i].socket;
00430     myPeers.erase(myPeers.begin() + i);
00431 
00432     EV << "removing (stale) bindings from fecDown for peer=" << peerIP << endl;
00433 
00434     FecBindVector::iterator dit;
00435     for (dit = fecDown.begin(); dit != fecDown.end();)
00436     {
00437         if (dit->peer != peerIP)
00438         {
00439                 dit++;
00440             continue;
00441         }
00442 
00443         EV << "label=" << dit->label << endl;
00444 
00445         // send release message just in case (?)
00446         // what happens if peer is not really down and
00447         // hello messages just disappeared?
00448         // does the protocol recover on its own (XXX check this)
00449 
00450         dit = fecDown.erase(dit);
00451     }
00452 
00453     EV << "removing bindings from sent to peer=" << peerIP << " from fecUp" << endl;
00454 
00455     FecBindVector::iterator uit;
00456     for (uit = fecUp.begin(); uit != fecUp.end();)
00457     {
00458         if (uit->peer != peerIP)
00459         {
00460                 uit++;
00461             continue;
00462         }
00463 
00464         EV << "label=" << uit->label << endl;
00465 
00466         // send withdraw message just in case (?)
00467         // see comment above...
00468 
00469         uit = fecUp.erase(uit);
00470     }
00471 
00472     EV << "updating fecList" << endl;
00473 
00474     updateFecList(peerIP);
00475 
00476     // update TED and routing table
00477 
00478     unsigned int index = tedmod->linkIndex(rt->getRouterId(), peerIP);
00479     tedmod->ted[index].state = false;
00480     announceLinkChange(index);
00481     tedmod->rebuildRoutingTable();
00482 }

void LDP::processMessageFromTCP ( cMessage *  msg  )  [protected, virtual]

Referenced by handleMessage().

00557 {
00558     TCPSocket *socket = socketMap.findSocketFor(msg);
00559     if (!socket)
00560     {
00561         // not yet in socketMap, must be new incoming connection.
00562         // find which peer it is and register connection
00563         socket = new TCPSocket(msg);
00564         socket->setOutputGate(gate("tcpOut"));
00565 
00566         // FIXME there seems to be some confusion here. Is it sure that
00567         // routerIds we use as peerAddrs are the same as IP addresses
00568         // the routing is based on? --Andras
00569         IPAddress peerAddr = socket->getRemoteAddress().get4();
00570 
00571         int i = findPeer(peerAddr);
00572         if (i==-1 || myPeers[i].socket)
00573         {
00574             // nothing known about this guy, or already connected: refuse
00575             socket->close(); // reset()?
00576             delete socket;
00577             delete msg;
00578             return;
00579         }
00580         myPeers[i].socket = socket;
00581         socket->setCallbackObject(this, (void *)i);
00582         socketMap.addSocket(socket);
00583     }
00584 
00585     // dispatch to socketEstablished(), socketDataArrived(), socketPeerClosed()
00586     // or socketFailure()
00587     socket->processMessage(msg);
00588 }

void LDP::processLDPPacketFromTCP ( LDPPacket *  ldpPacket  )  [protected, virtual]

Referenced by socketDataArrived().

00648 {
00649     switch (ldpPacket->getType())
00650     {
00651     case HELLO:
00652         error("Received LDP HELLO over TCP (should arrive over UDP)");
00653 
00654     case ADDRESS:
00655         // processADDRESS(ldpPacket);
00656         error("Received LDP ADDRESS message, unsupported in this version");
00657         break;
00658 
00659     case ADDRESS_WITHDRAW:
00660         // processADDRESS_WITHDRAW(ldpPacket);
00661         error("LDP PROC DEBUG: Received LDP ADDRESS_WITHDRAW message, unsupported in this version");
00662         break;
00663 
00664     case LABEL_MAPPING:
00665         processLABEL_MAPPING(check_and_cast<LDPLabelMapping *>(ldpPacket));
00666         break;
00667 
00668     case LABEL_REQUEST:
00669         processLABEL_REQUEST(check_and_cast<LDPLabelRequest *>(ldpPacket));
00670         break;
00671 
00672     case LABEL_WITHDRAW:
00673         processLABEL_WITHDRAW(check_and_cast<LDPLabelMapping *>(ldpPacket));
00674         break;
00675 
00676     case LABEL_RELEASE:
00677         processLABEL_RELEASE(check_and_cast<LDPLabelMapping *>(ldpPacket));
00678         break;
00679 
00680     case NOTIFICATION:
00681         processNOTIFICATION(check_and_cast<LDPNotify*>(ldpPacket));
00682         break;
00683 
00684     default:
00685         error("LDP PROC DEBUG: Unrecognized LDP Message Type, type is %d", ldpPacket->getType());
00686     }
00687 }

void LDP::processLABEL_MAPPING ( LDPLabelMapping *  packet  )  [protected, virtual]

Referenced by processLDPPacketFromTCP().

01102 {
01103     FEC_TLV fec = packet->getFec();
01104     int label = packet->getLabel();
01105     IPAddress fromIP = packet->getSenderAddress();
01106 
01107     EV << "Label mapping label=" << label << " received for fec=" << fec << " from " << fromIP << endl;
01108 
01109     ASSERT(label > 0);
01110 
01111     FecVector::iterator it = findFecEntry(fecList, fec.addr, fec.length);
01112     ASSERT(it != fecList.end());
01113 
01114     FecBindVector::iterator dit = findFecEntry(fecDown, it->fecid, fromIP);
01115     ASSERT(dit == fecDown.end());
01116 
01117     // insert among received mappings
01118 
01119     fec_bind_t newItem;
01120     newItem.fecid = it->fecid;
01121     newItem.peer = fromIP;
01122     newItem.label = label;
01123     fecDown.push_back(newItem);
01124 
01125     // respond to pending requests
01126 
01127     PendingVector::iterator pit;
01128     for (pit = pending.begin(); pit != pending.end();)
01129     {
01130         if (pit->fecid != it->fecid)
01131         {
01132             pit++;
01133             continue;
01134         }
01135 
01136         EV << "there's pending request for this FEC from " << pit->peer << ", sending mapping" << endl;
01137 
01138         std::string inInterface = findInterfaceFromPeerAddr(pit->peer);
01139         std::string outInterface = findInterfaceFromPeerAddr(fromIP);
01140         LabelOpVector outLabel = LIBTable::swapLabel(label);
01141 
01142         fec_bind_t newItem;
01143         newItem.fecid = it->fecid;
01144         newItem.peer = pit->peer;
01145         newItem.label = lt->installLibEntry(-1, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
01146         fecUp.push_back(newItem);
01147 
01148         EV << "installed LIB entry inLabel=" << newItem.label << " inInterface=" << inInterface <<
01149                 " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
01150 
01151         sendMapping(LABEL_MAPPING, pit->peer, newItem.label, it->addr, it->length);
01152 
01153         // remove request from the list
01154         pit = pending.erase(pit);
01155     }
01156 
01157     delete packet;
01158 }

void LDP::processLABEL_REQUEST ( LDPLabelRequest *  packet  )  [protected, virtual]

Referenced by processLDPPacketFromTCP().

00922 {
00923     FEC_TLV fec = packet->getFec();
00924     IPAddress srcAddr = packet->getSenderAddress();
00925 
00926     EV << "Label Request from LSR " << srcAddr << " for FEC " << fec << endl;
00927 
00928     FecVector::iterator it = findFecEntry(fecList, fec.addr, fec.length);
00929     if (it == fecList.end())
00930     {
00931         EV << "FEC not recognized, sending back No route message" << endl;
00932 
00933         sendNotify(NO_ROUTE, srcAddr, fec.addr, fec.length);
00934 
00935         delete packet;
00936         return;
00937     }
00938 
00939     // do we already have mapping for this fec from our downstream peer?
00940 
00941     //
00942     // XXX this code duplicates rebuildFecList
00943     //
00944 
00945     // does upstream have mapping from us?
00946     FecBindVector::iterator uit = findFecEntry(fecUp, it->fecid, srcAddr);
00947 
00948     // shouldn't!
00949     ASSERT(uit == fecUp.end());
00950 
00951     // do we have mapping from downstream?
00952     FecBindVector::iterator dit = findFecEntry(fecDown, it->fecid, it->nextHop);
00953 
00954     // is next hop our LDP peer?
00955     bool ER = !findPeerSocket(it->nextHop);
00956 
00957     ASSERT(!(ER && dit != fecDown.end())); // can't be egress and have mapping at the same time
00958 
00959     if (ER || dit != fecDown.end())
00960     {
00961         fec_bind_t newItem;
00962         newItem.fecid = it->fecid;
00963         newItem.label = -1;
00964         newItem.peer = srcAddr;
00965         fecUp.push_back(newItem);
00966         uit = fecUp.end() - 1;
00967     }
00968 
00969     std::string inInterface = findInterfaceFromPeerAddr(srcAddr);
00970     std::string outInterface = findInterfaceFromPeerAddr(it->nextHop);
00971 
00972     if (ER)
00973     {
00974         // we are egress, that's easy:
00975         LabelOpVector outLabel = LIBTable::popLabel();
00976 
00977         uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, 0);
00978 
00979         EV << "installed (egress) LIB entry inLabel=" << uit->label << " inInterface=" << inInterface <<
00980                 " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
00981 
00982         // We are egress, let our upstream peer know
00983         // about it by sending back a Label Mapping message
00984 
00985         sendMapping(LABEL_MAPPING, srcAddr, uit->label, fec.addr, fec.length);
00986 
00987     }
00988     else if (dit != fecDown.end())
00989     {
00990         // we have mapping from DS, that's easy
00991         LabelOpVector outLabel = LIBTable::swapLabel(dit->label);
00992         uit->label = lt->installLibEntry(uit->label, inInterface, outLabel, outInterface, LDP_USER_TRAFFIC);
00993 
00994         EV << "installed LIB entry inLabel=" << uit->label << " inInterface=" << inInterface <<
00995                 " outLabel=" << outLabel << " outInterface=" << outInterface << endl;
00996 
00997         // We already have a mapping for this FEC, let our upstream peer know
00998         // about it by sending back a Label Mapping message
00999 
01000         sendMapping(LABEL_MAPPING, srcAddr, uit->label, fec.addr, fec.length);
01001     }
01002     else
01003     {
01004         // no mapping from DS, mark as pending
01005 
01006         EV << "no mapping for this FEC from the downstream router, marking as pending" << endl;
01007 
01008         pending_req_t newItem;
01009         newItem.fecid = it->fecid;
01010         newItem.peer = srcAddr;
01011         pending.push_back(newItem);
01012     }
01013 
01014     delete packet;
01015 }

void LDP::processLABEL_RELEASE ( LDPLabelMapping *  packet  )  [protected, virtual]

Referenced by processLDPPacketFromTCP().

01018 {
01019     FEC_TLV fec = packet->getFec();
01020     int label = packet->getLabel();
01021     IPAddress fromIP = packet->getSenderAddress();
01022 
01023     EV << "Mapping release received for label=" << label << " fec=" << fec << " from " << fromIP << endl;
01024 
01025     ASSERT(label > 0);
01026 
01027     // remove label from fecUp
01028 
01029     FecVector::iterator it = findFecEntry(fecList, fec.addr, fec.length);
01030     if (it == fecList.end())
01031     {
01032         EV << "FEC no longer recognized here, ignoring" << endl;
01033         delete packet;
01034         return;
01035     }
01036 
01037     FecBindVector::iterator uit = findFecEntry(fecUp, it->fecid, fromIP);
01038     if (uit == fecUp.end() || label != uit->label)
01039     {
01040         // this is ok and may happen; e.g. we removed the mapping because downstream
01041         // neighbour withdrew its mapping. we sent withdraw upstream as well and
01042         // this is upstream's response
01043         EV << "mapping not found among sent mappings, ignoring" << endl;
01044         delete packet;
01045         return;
01046     }
01047 
01048     EV << "removing from LIB table label=" << uit->label << endl;
01049     lt->removeLibEntry(uit->label);
01050 
01051     EV << "removing label from list of sent mappings" << endl;
01052     fecUp.erase(uit);
01053 
01054     delete packet;
01055 }

void LDP::processLABEL_WITHDRAW ( LDPLabelMapping *  packet  )  [protected, virtual]

Referenced by processLDPPacketFromTCP().

01058 {
01059     FEC_TLV fec = packet->getFec();
01060     int label = packet->getLabel();
01061     IPAddress fromIP = packet->getSenderAddress();
01062 
01063     EV << "Mapping withdraw received for label=" << label << " fec=" << fec << " from " << fromIP << endl;
01064 
01065     ASSERT(label > 0);
01066 
01067     // remove label from fecDown
01068 
01069     FecVector::iterator it = findFecEntry(fecList, fec.addr, fec.length);
01070     if (it == fecList.end())
01071     {
01072         EV << "matching FEC not found, ignoring withdraw message" << endl;
01073         delete packet;
01074         return;
01075     }
01076 
01077     FecBindVector::iterator dit = findFecEntry(fecDown, it->fecid, fromIP);
01078 
01079     if (dit == fecDown.end() || label != dit->label)
01080     {
01081         EV << "matching mapping not found, ignoring withdraw message" << endl;
01082         delete packet;
01083         return;
01084     }
01085 
01086     ASSERT(dit != fecDown.end());
01087     ASSERT(label == dit->label);
01088 
01089     EV << "removing label from list of received mappings" << endl;
01090     fecDown.erase(dit);
01091 
01092     EV << "sending back relase message" << endl;
01093     packet->setType(LABEL_RELEASE);
01094 
01095     // send msg to peer over TCP
01096     sendToPeer(fromIP, packet);
01097 
01098     updateFecListEntry(*it);
01099 }

void LDP::processNOTIFICATION ( LDPNotify *  packet  )  [protected, virtual]

Referenced by handleMessage(), and processLDPPacketFromTCP().

00861 {
00862     FEC_TLV fec = packet->getFec();
00863     IPAddress srcAddr = packet->getSenderAddress();
00864     int status = packet->getStatus();
00865 
00866     // XXX FIXME NO_ROUTE processing should probably be split into two functions,
00867     // this is not the cleanest thing I ever wrote :)   --Vojta
00868 
00869     if (packet->isSelfMessage())
00870     {
00871         // re-scheduled by ourselves
00872         EV << "notification retry for peer=" << srcAddr << " fec=" << fec << " status=" << status << endl;
00873     }
00874     else
00875     {
00876         // received via network
00877         EV << "notification received from=" << srcAddr << " fec=" << fec << " status=" << status << endl;
00878     }
00879 
00880     switch(status)
00881     {
00882         case NO_ROUTE:
00883         {
00884             EV << "route does not exit on that peer" << endl;
00885 
00886             FecVector::iterator it = findFecEntry(fecList, fec.addr, fec.length);
00887             if (it != fecList.end())
00888             {
00889                 if (it->nextHop == srcAddr)
00890                 {
00891                     if (!packet->isSelfMessage())
00892                     {
00893                         EV << "we are still interesed in this mapping, we will retry later" << endl;
00894 
00895                         scheduleAt(simTime() + 1.0 /* XXX FIXME */, packet);
00896                         return;
00897                     }
00898                     else
00899                     {
00900                         EV << "reissuing request" << endl;
00901 
00902                         sendMappingRequest(srcAddr, fec.addr, fec.length);
00903                     }
00904                 }
00905                 else
00906                     EV << "and we still recognize this FEC, but we use different next hop, forget it" << endl;
00907             }
00908             else
00909                 EV << "and we do not recognize this any longer, forget it" << endl;
00910 
00911             break;
00912         }
00913 
00914         default:
00915             ASSERT(false);
00916     }
00917 
00918     delete packet;
00919 }

void LDP::socketEstablished ( int  connId,
void *  yourPtr 
) [protected, virtual]

Reimplemented from TCPSocket::CallbackInterface.

00591 {
00592     peer_info& peer = myPeers[(long)yourPtr];
00593     EV << "TCP connection established with peer " << peer.peerIP << "\n";
00594 
00595     // we must update all entries with nextHop == peerIP
00596     updateFecList(peer.peerIP);
00597 
00598     // FIXME start LDP session setup (if we're on the active side?)
00599 }

void LDP::socketDataArrived ( int  connId,
void *  yourPtr,
cPacket *  msg,
bool  urgent 
) [protected, virtual]

Implements TCPSocket::CallbackInterface.

00602 {
00603     peer_info& peer = myPeers[(long)yourPtr];
00604     EV << "Message arrived over TCP from peer " << peer.peerIP << "\n";
00605 
00606     delete msg->removeControlInfo();
00607     processLDPPacketFromTCP(check_and_cast<LDPPacket *>(msg));
00608 }

void LDP::socketPeerClosed ( int  connId,
void *  yourPtr 
) [protected, virtual]

Reimplemented from TCPSocket::CallbackInterface.

00611 {
00612     peer_info& peer = myPeers[(long)yourPtr];
00613     EV << "Peer " << peer.peerIP << " closed TCP connection\n";
00614 
00615     ASSERT(false);
00616 
00617 /*
00618     // close the connection (if not already closed)
00619     if (socket.getState()==TCPSocket::PEER_CLOSED)
00620     {
00621         EV << "remote TCP closed, closing here as well\n";
00622         close();
00623     }
00624 */
00625 }

void LDP::socketClosed ( int  connId,
void *  yourPtr 
) [protected, virtual]

Reimplemented from TCPSocket::CallbackInterface.

00628 {
00629     peer_info& peer = myPeers[(long)yourPtr];
00630     EV << "TCP connection to peer " << peer.peerIP << " closed\n";
00631 
00632     ASSERT(false);
00633 
00634     // FIXME what now? reconnect after a delay?
00635 }

void LDP::socketFailure ( int  connId,
void *  yourPtr,
int  code 
) [protected, virtual]

Reimplemented from TCPSocket::CallbackInterface.

00638 {
00639     peer_info& peer = myPeers[(long)yourPtr];
00640     EV << "TCP connection to peer " << peer.peerIP << " broken\n";
00641 
00642     ASSERT(false);
00643 
00644     // FIXME what now? reconnect after a delay?
00645 }

virtual void LDP::socketStatusArrived ( int  connId,
void *  yourPtr,
TCPStatusInfo *  status 
) [inline, protected, virtual]

Reimplemented from TCPSocket::CallbackInterface.

00205 {delete status;}

bool LDP::lookupLabel ( IPDatagram *  ipdatagram,
LabelOpVector outLabel,
std::string &  outInterface,
int &  color 
) [protected, virtual]

The ipdatagram argument is an input parameter, the rest (outLabel, outInterface, color) are output parameters only.

In subclasses, this function should be implemented to determine the forwarding equivalence class for the IP datagram passed, and map it to an outLabel and outInterface.

The color parameter (which can be set to an arbitrary value) will only be used for the NAM trace if one will be recorded.

Implements IClassifier.

01187 {
01188     IPAddress destAddr = ipdatagram->getDestAddress();
01189     int protocol = ipdatagram->getTransportProtocol();
01190 
01191     // never match and always route via L3 if:
01192 
01193     // OSPF traffic (TED)
01194     if (protocol == IP_PROT_OSPF)
01195         return false;
01196 
01197     // LDP traffic (both discovery...
01198     if (protocol == IP_PROT_UDP && check_and_cast<UDPPacket*>(ipdatagram->getEncapsulatedMsg())->getDestinationPort() == LDP_PORT)
01199         return false;
01200 
01201     // ...and session)
01202     if (protocol == IP_PROT_TCP && check_and_cast<TCPSegment*>(ipdatagram->getEncapsulatedMsg())->getDestPort() == LDP_PORT)
01203         return false;
01204     if (protocol == IP_PROT_TCP && check_and_cast<TCPSegment*>(ipdatagram->getEncapsulatedMsg())->getSrcPort() == LDP_PORT)
01205         return false;
01206 
01207     // regular traffic, classify, label etc.
01208 
01209     FecVector::iterator it;
01210     for (it = fecList.begin(); it != fecList.end(); it++)
01211     {
01212         if (!destAddr.prefixMatches(it->addr, it->length))
01213             continue;
01214 
01215         EV << "FEC matched: " << *it << endl;
01216 
01217         FecBindVector::iterator dit = findFecEntry(fecDown, it->fecid, it->nextHop);
01218         if (dit != fecDown.end())
01219         {
01220             outLabel = LIBTable::pushLabel(dit->label);
01221             outInterface = findInterfaceFromPeerAddr(it->nextHop);
01222             color = LDP_USER_TRAFFIC;
01223             EV << "mapping found, outLabel=" << outLabel << ", outInterface=" << outInterface << endl;
01224             return true;
01225         }
01226         else
01227         {
01228             EV << "no mapping for this FEC exists" << endl;
01229             return false;
01230         }
01231     }
01232     return false;
01233 }

void LDP::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [protected, virtual]

Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed.

Implements INotifiable.

01236 {
01237     Enter_Method_Silent();
01238     printNotificationBanner(category, details);
01239 
01240     ASSERT(category==NF_IPv4_ROUTE_ADDED || category==NF_IPv4_ROUTE_DELETED);
01241 
01242     EV << "routing table changed, rebuild list of known FEC" << endl;
01243 
01244     rebuildFecList();
01245 }


Member Data Documentation

simtime_t LDP::holdTime [protected]

simtime_t LDP::helloInterval [protected]

Referenced by handleMessage(), and initialize().

FecVector LDP::fecList [protected]

PeerVector LDP::myPeers [protected]

IInterfaceTable* LDP::ift [protected]

IRoutingTable* LDP::rt [protected]

LIBTable* LDP::lt [protected]

TED* LDP::tedmod [protected]

NotificationBoard* LDP::nb [protected]

Referenced by announceLinkChange(), and initialize().

Referenced by initialize(), and sendHelloTo().

Referenced by initialize().

cMessage* LDP::sendHelloMsg [protected]

Referenced by handleMessage(), initialize(), LDP(), and ~LDP().

int LDP::maxFecid [protected]

Referenced by initialize(), and rebuildFecList().


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:20 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5