#include <LDP.h>
Public Types | |
typedef std::vector< fec_t > | FecVector |
typedef std::vector< fec_bind_t > | FecBindVector |
typedef std::vector < pending_req_t > | PendingVector |
typedef std::vector< peer_info > | PeerVector |
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 TCPSocket * | getPeerSocket (IPAddress peerAddr) |
virtual TCPSocket * | findPeerSocket (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 |
IInterfaceTable * | ift |
IRoutingTable * | rt |
LIBTable * | lt |
TED * | tedmod |
NotificationBoard * | nb |
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 |
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 |
LDP::LDP | ( | ) |
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 }
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 }
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 }
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] |
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 }
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] |
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 }
simtime_t LDP::holdTime [protected] |
Referenced by initialize(), processLDPHello(), and sendHelloTo().
simtime_t LDP::helloInterval [protected] |
Referenced by handleMessage(), and initialize().
FecVector LDP::fecList [protected] |
FecBindVector LDP::fecUp [protected] |
FecBindVector LDP::fecDown [protected] |
PendingVector LDP::pending [protected] |
Referenced by initialize(), processLABEL_MAPPING(), and processLABEL_REQUEST().
PeerVector LDP::myPeers [protected] |
IInterfaceTable* LDP::ift [protected] |
Referenced by findPeerAddrFromInterface(), initialize(), processLDPHello(), and rebuildFecList().
IRoutingTable* LDP::rt [protected] |
Referenced by initialize(), processLABEL_MAPPING(), processLABEL_RELEASE(), processLABEL_REQUEST(), rebuildFecList(), and updateFecListEntry().
TED* LDP::tedmod [protected] |
Referenced by initialize(), processHelloTimeout(), and processLDPHello().
NotificationBoard* LDP::nb [protected] |
Referenced by announceLinkChange(), and initialize().
UDPSocket LDP::udpSocket [protected] |
Referenced by initialize(), and sendHelloTo().
TCPSocket LDP::serverSocket [protected] |
Referenced by initialize().
TCPSocketMap LDP::socketMap [protected] |
Referenced by openTCPConnectionToPeer(), and processMessageFromTCP().
cMessage* LDP::sendHelloMsg [protected] |
Referenced by handleMessage(), initialize(), LDP(), and ~LDP().
int LDP::maxFecid [protected] |
Referenced by initialize(), and rebuildFecList().