00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <omnetpp.h>
00017 #include <iostream>
00018 #include <fstream>
00019 #include <algorithm>
00020 #include "ConstType.h"
00021 #include "LDP.h"
00022 #include "LIBTable.h"
00023 #include "InterfaceTableAccess.h"
00024 #include "IPv4InterfaceData.h"
00025 #include "RoutingTableAccess.h"
00026 #include "LIBTableAccess.h"
00027 #include "TEDAccess.h"
00028 #include "NotifierConsts.h"
00029 #include "UDPPacket.h"
00030 #include "TCPSegment.h"
00031
00032
00033 Define_Module(LDP);
00034
00035
00036 std::ostream& operator<<(std::ostream& os, const LDP::fec_bind_t& f)
00037 {
00038 os << "fecid=" << f.fecid << " peer=" << f.peer << " label=" << f.label;
00039 return os;
00040 }
00041
00042 bool fecPrefixCompare(const LDP::fec_t& a, const LDP::fec_t& b)
00043 {
00044 return a.length > b.length;
00045 }
00046
00047 std::ostream& operator<<(std::ostream& os, const LDP::fec_t& f)
00048 {
00049 os << "fecid=" << f.fecid << " addr=" << f.addr << " length=" << f.length << " nextHop=" << f.nextHop;
00050 return os;
00051 }
00052
00053 std::ostream& operator<<(std::ostream& os, const LDP::pending_req_t& r)
00054 {
00055 os << "fecid=" << r.fecid << " peer=" << r.peer;
00056 return os;
00057 }
00058
00059 std::ostream& operator<<(std::ostream& os, const LDP::peer_info& p)
00060 {
00061 os << "peerIP=" << p.peerIP << " interface=" << p.linkInterface <<
00062 " activeRole=" << (p.activeRole ? "true" : "false") <<
00063 " socket=" << (p.socket ? TCPSocket::stateName(p.socket->getState()) : "NULL");
00064 return os;
00065 }
00066
00067 bool operator==(const FEC_TLV& a, const FEC_TLV& b)
00068 {
00069 return a.length == b.length && a.addr == b.addr;
00070 }
00071
00072 bool operator!=(const FEC_TLV& a, const FEC_TLV& b)
00073 {
00074 return !operator==(a, b);
00075 }
00076
00077 std::ostream& operator<<(std::ostream& os, const FEC_TLV& a)
00078 {
00079 os << "addr=" << a.addr << " length=" << a.length;
00080 return os;
00081 }
00082
00083
00084 LDP::LDP()
00085 {
00086 sendHelloMsg = NULL;
00087 }
00088
00089 LDP::~LDP()
00090 {
00091 for (unsigned int i=0; i<myPeers.size(); i++)
00092 cancelAndDelete(myPeers[i].timeout);
00093
00094 cancelAndDelete(sendHelloMsg);
00095
00096
00097 }
00098
00099 void LDP::initialize(int stage)
00100 {
00101 if (stage != 3)
00102 return;
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
00122 sendHelloMsg = new cMessage("LDPSendHello");
00123 scheduleAt(simTime() + exponential(0.1), sendHelloMsg);
00124
00125
00126 udpSocket.setOutputGate(gate("udpOut"));
00127 udpSocket.bind(LDP_PORT);
00128
00129
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
00136 rebuildFecList();
00137
00138
00139 nb->subscribe(this, NF_IPv4_ROUTE_ADDED);
00140 nb->subscribe(this, NF_IPv4_ROUTE_DELETED);
00141 }
00142
00143 void LDP::handleMessage(cMessage *msg)
00144 {
00145 EV << "Received: (" << msg->getClassName() << ")" << msg->getName() << "\n";
00146 if (msg==sendHelloMsg)
00147 {
00148
00149
00150 EV << "Multicasting LDP Hello to neighboring routers\n";
00151 sendHelloTo(IPAddress::ALL_ROUTERS_MCAST);
00152
00153
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
00171 processLDPHello(check_and_cast<LDPHello *>(msg));
00172 }
00173 else if (!strcmp(msg->getArrivalGate()->getName(), "tcpIn"))
00174 {
00175 processMessageFromTCP(msg);
00176 }
00177 }
00178
00179 void LDP::sendToPeer(IPAddress dest, cMessage *msg)
00180 {
00181 getPeerSocket(dest)->send(msg);
00182 }
00183
00184 void LDP::sendMappingRequest(IPAddress dest, IPAddress addr, int length)
00185 {
00186 LDPLabelRequest *requestMsg = new LDPLabelRequest("Lb-Req");
00187 requestMsg->setByteLength(LDP_HEADER_BYTES);
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 }
00200
00201 void LDP::updateFecListEntry(LDP::fec_t oldItem)
00202 {
00203
00204 FecBindVector::iterator dit = findFecEntry(fecDown, oldItem.fecid, oldItem.nextHop);
00205
00206
00207 bool ER = findPeerSocket(oldItem.nextHop)==NULL;
00208
00209 ASSERT(!(ER && dit != fecDown.end()));
00210
00211
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
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
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
00246 EV << "sending withdraw message upstream" << endl;
00247 sendMapping(LABEL_WITHDRAW, uit->peer, uit->label, oldItem.addr, oldItem.length);
00248
00249
00250 uit = fecUp.erase(uit);
00251 }
00252 }
00253
00254 if (!ER && dit == fecDown.end())
00255 {
00256
00257 EV << "sending request message downstream" << endl;
00258 sendMappingRequest(oldItem.nextHop, oldItem.addr, oldItem.length);
00259 }
00260 }
00261
00262 void LDP::rebuildFecList()
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
00272
00273 const IPRoute *re = rt->getRoute(i);
00274
00275
00276 if (re->getHost().isMulticast())
00277 continue;
00278
00279
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
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
00301 it->nextHop = nextHop;
00302 updateFecListEntry(*it);
00303 fecList.push_back(*it);
00304 oldList.erase(it);
00305 }
00306 else
00307 {
00308
00309 fecList.push_back(*it);
00310 oldList.erase(it);
00311 continue;
00312 }
00313 }
00314
00315
00316
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
00380
00381 std::sort(fecList.begin(), fecList.end(), fecPrefixCompare);
00382 }
00383
00384 void LDP::updateFecList(IPAddress nextHop)
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 }
00395
00396 void LDP::sendHelloTo(IPAddress dest)
00397 {
00398 LDPHello *hello = new LDPHello("LDP-Hello");
00399 hello->setByteLength(LDP_HEADER_BYTES);
00400 hello->setType(HELLO);
00401 hello->setSenderAddress(rt->getRouterId());
00402
00403 hello->setHoldTime(SIMTIME_DBL(holdTime));
00404
00405
00406 hello->addPar("color") = LDP_HELLO_TRAFFIC;
00407
00408 udpSocket.sendTo(hello, dest, LDP_PORT);
00409 }
00410
00411 void LDP::processHelloTimeout(cMessage *msg)
00412 {
00413
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();
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
00446
00447
00448
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
00467
00468
00469 uit = fecUp.erase(uit);
00470 }
00471
00472 EV << "updating fecList" << endl;
00473
00474 updateFecList(peerIP);
00475
00476
00477
00478 unsigned int index = tedmod->linkIndex(rt->getRouterId(), peerIP);
00479 tedmod->ted[index].state = false;
00480 announceLinkChange(index);
00481 tedmod->rebuildRoutingTable();
00482 }
00483
00484 void LDP::processLDPHello(LDPHello *msg)
00485 {
00486 UDPControlInfo *controlInfo = check_and_cast<UDPControlInfo *>(msg->getControlInfo());
00487
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
00497 EV << "that's myself, ignore\n";
00498 return;
00499 }
00500
00501
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
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
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
00536 sendHelloTo(peerAddr);
00537 if (info.activeRole)
00538 {
00539 EV << "Establishing session with it\n";
00540 openTCPConnectionToPeer(peerIndex);
00541 }
00542 }
00543
00544 void LDP::openTCPConnectionToPeer(int peerIndex)
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 }
00555
00556 void LDP::processMessageFromTCP(cMessage *msg)
00557 {
00558 TCPSocket *socket = socketMap.findSocketFor(msg);
00559 if (!socket)
00560 {
00561
00562
00563 socket = new TCPSocket(msg);
00564 socket->setOutputGate(gate("tcpOut"));
00565
00566
00567
00568
00569 IPAddress peerAddr = socket->getRemoteAddress().get4();
00570
00571 int i = findPeer(peerAddr);
00572 if (i==-1 || myPeers[i].socket)
00573 {
00574
00575 socket->close();
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
00586
00587 socket->processMessage(msg);
00588 }
00589
00590 void LDP::socketEstablished(int, void *yourPtr)
00591 {
00592 peer_info& peer = myPeers[(long)yourPtr];
00593 EV << "TCP connection established with peer " << peer.peerIP << "\n";
00594
00595
00596 updateFecList(peer.peerIP);
00597
00598
00599 }
00600
00601 void LDP::socketDataArrived(int, void *yourPtr, cPacket *msg, bool)
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 }
00609
00610 void LDP::socketPeerClosed(int, void *yourPtr)
00611 {
00612 peer_info& peer = myPeers[(long)yourPtr];
00613 EV << "Peer " << peer.peerIP << " closed TCP connection\n";
00614
00615 ASSERT(false);
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 }
00626
00627 void LDP::socketClosed(int, void *yourPtr)
00628 {
00629 peer_info& peer = myPeers[(long)yourPtr];
00630 EV << "TCP connection to peer " << peer.peerIP << " closed\n";
00631
00632 ASSERT(false);
00633
00634
00635 }
00636
00637 void LDP::socketFailure(int, void *yourPtr, int code)
00638 {
00639 peer_info& peer = myPeers[(long)yourPtr];
00640 EV << "TCP connection to peer " << peer.peerIP << " broken\n";
00641
00642 ASSERT(false);
00643
00644
00645 }
00646
00647 void LDP::processLDPPacketFromTCP(LDPPacket *ldpPacket)
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
00656 error("Received LDP ADDRESS message, unsupported in this version");
00657 break;
00658
00659 case ADDRESS_WITHDRAW:
00660
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 }
00688
00689 IPAddress LDP::locateNextHop(IPAddress dest)
00690 {
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 InterfaceEntry *ie = rt->getInterfaceForDestAddr(dest);
00714 if (!ie)
00715 return IPAddress();
00716
00717 std::string iName = ie->getName();
00718 return findPeerAddrFromInterface(iName);
00719 }
00720
00721
00722
00723 IPAddress LDP::findPeerAddrFromInterface(std::string interfaceName)
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
00741 }
00742 }
00743
00744
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
00758 return i==(int)myPeers.size() ? IPAddress() : myPeers[i].peerIP;
00759 }
00760
00761
00762 std::string LDP::findInterfaceFromPeerAddr(IPAddress peerIP)
00763 {
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
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 }
00784
00785
00786
00787
00788
00789
00790 LDP::FecBindVector::iterator LDP::findFecEntry(FecBindVector& fecs, int fecid, IPAddress peer)
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 }
00805
00806 LDP::FecVector::iterator LDP::findFecEntry(FecVector& fecs, IPAddress addr, int length)
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)
00815 continue;
00816
00817 break;
00818 }
00819 return it;
00820 }
00821
00822 void LDP::sendNotify(int status, IPAddress dest, IPAddress addr, int length)
00823 {
00824
00825 LDPNotify *lnMessage = new LDPNotify("Lb-Notify");
00826 lnMessage->setByteLength(LDP_HEADER_BYTES);
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 }
00840
00841 void LDP::sendMapping(int type, IPAddress dest, int label, IPAddress addr, int length)
00842 {
00843
00844 LDPLabelMapping *lmMessage = new LDPLabelMapping("Lb-Mapping");
00845 lmMessage->setByteLength(LDP_HEADER_BYTES);
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 }
00859
00860 void LDP::processNOTIFICATION(LDPNotify *packet)
00861 {
00862 FEC_TLV fec = packet->getFec();
00863 IPAddress srcAddr = packet->getSenderAddress();
00864 int status = packet->getStatus();
00865
00866
00867
00868
00869 if (packet->isSelfMessage())
00870 {
00871
00872 EV << "notification retry for peer=" << srcAddr << " fec=" << fec << " status=" << status << endl;
00873 }
00874 else
00875 {
00876
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 , 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 }
00920
00921 void LDP::processLABEL_REQUEST(LDPLabelRequest *packet)
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
00940
00941
00942
00943
00944
00945
00946 FecBindVector::iterator uit = findFecEntry(fecUp, it->fecid, srcAddr);
00947
00948
00949 ASSERT(uit == fecUp.end());
00950
00951
00952 FecBindVector::iterator dit = findFecEntry(fecDown, it->fecid, it->nextHop);
00953
00954
00955 bool ER = !findPeerSocket(it->nextHop);
00956
00957 ASSERT(!(ER && dit != fecDown.end()));
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
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
00983
00984
00985 sendMapping(LABEL_MAPPING, srcAddr, uit->label, fec.addr, fec.length);
00986
00987 }
00988 else if (dit != fecDown.end())
00989 {
00990
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
00998
00999
01000 sendMapping(LABEL_MAPPING, srcAddr, uit->label, fec.addr, fec.length);
01001 }
01002 else
01003 {
01004
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 }
01016
01017 void LDP::processLABEL_RELEASE(LDPLabelMapping *packet)
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
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
01041
01042
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 }
01056
01057 void LDP::processLABEL_WITHDRAW(LDPLabelMapping *packet)
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
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
01096 sendToPeer(fromIP, packet);
01097
01098 updateFecListEntry(*it);
01099 }
01100
01101 void LDP::processLABEL_MAPPING(LDPLabelMapping *packet)
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
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
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
01154 pit = pending.erase(pit);
01155 }
01156
01157 delete packet;
01158 }
01159
01160 int LDP::findPeer(IPAddress peerAddr)
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 }
01167
01168 TCPSocket *LDP::findPeerSocket(IPAddress peerAddr)
01169 {
01170
01171 int i = findPeer(peerAddr);
01172 if (i==-1 || !(myPeers[i].socket) || myPeers[i].socket->getState()!=TCPSocket::CONNECTED)
01173 return NULL;
01174 return myPeers[i].socket;
01175 }
01176
01177 TCPSocket *LDP::getPeerSocket(IPAddress peerAddr)
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 }
01185
01186 bool LDP::lookupLabel(IPDatagram *ipdatagram, LabelOpVector& outLabel, std::string& outInterface, int& color)
01187 {
01188 IPAddress destAddr = ipdatagram->getDestAddress();
01189 int protocol = ipdatagram->getTransportProtocol();
01190
01191
01192
01193
01194 if (protocol == IP_PROT_OSPF)
01195 return false;
01196
01197
01198 if (protocol == IP_PROT_UDP && check_and_cast<UDPPacket*>(ipdatagram->getEncapsulatedMsg())->getDestinationPort() == LDP_PORT)
01199 return false;
01200
01201
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
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 }
01234
01235 void LDP::receiveChangeNotification(int category, const cPolymorphic *details)
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 }
01246
01247 void LDP::announceLinkChange(int tedlinkindex)
01248 {
01249 TEDChangeInfo d;
01250 d.setTedLinkIndicesArraySize(1);
01251 d.setTedLinkIndices(0, tedlinkindex);
01252 nb->fireChangeNotification(NF_TED_CHANGED, &d);
01253 }
01254
01255