00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "RSVP.h"
00016 #include "IPControlInfo.h"
00017 #include "IPAddressResolver.h"
00018 #include "common.h"
00019 #include "Utils.h"
00020 #include "XMLUtils.h"
00021 #include "IPv4InterfaceData.h"
00022 #include "TEDAccess.h"
00023 #include "RoutingTableAccess.h"
00024 #include "InterfaceTableAccess.h"
00025 #include "LIBTableAccess.h"
00026 #include "NotifierConsts.h"
00027
00028 #define PSB_REFRESH_INTERVAL 5.0
00029 #define RSB_REFRESH_INTERVAL 6.0
00030
00031 #define PSB_TIMEOUT_INTERVAL 16.0
00032 #define RSB_TIMEOUT_INTERVAL 19.0
00033
00034 #define PATH_ERR_UNFEASIBLE 1
00035 #define PATH_ERR_PREEMPTED 2
00036 #define PATH_ERR_NEXTHOP_FAILED 3
00037
00038 Define_Module(RSVP);
00039
00040
00041 RSVP::RSVP()
00042 {
00043 }
00044
00045 RSVP::~RSVP()
00046 {
00047
00048 }
00049
00050 void RSVP::initialize(int stage)
00051 {
00052
00053
00054
00055 if (stage==4)
00056 {
00057 tedmod = TEDAccess().get();
00058 rt = RoutingTableAccess().get();
00059 ift = InterfaceTableAccess().get();
00060 routerId = rt->getRouterId();
00061 lt = LIBTableAccess().get();
00062 nb = NotificationBoardAccess().get();
00063
00064 rpct = check_and_cast<IRSVPClassifier*>(getParentModule()->getSubmodule("classifier"));
00065
00066 maxPsbId = 0;
00067 maxRsbId = 0;
00068 maxSrcInstance = 0;
00069
00070 retryInterval = 1.0;
00071
00072
00073 setupHello();
00074
00075
00076 readTrafficFromXML(par("traffic").xmlValue());
00077 }
00078 }
00079
00080 int RSVP::getInLabel(const SessionObj_t& session, const SenderTemplateObj_t& sender)
00081 {
00082 unsigned int index;
00083 ResvStateBlock_t *rsb = findRSB(session, sender, index);
00084 if (!rsb)
00085 return -1;
00086
00087 return rsb->inLabelVector[index];
00088 }
00089
00090 void RSVP::createPath(const SessionObj_t& session, const SenderTemplateObj_t& sender)
00091 {
00092 if (findPSB(session, sender))
00093 {
00094 EV << "path (PSB) already exists, doing nothing" << endl;
00095 return;
00096 }
00097
00098
00099
00100 std::vector<traffic_session_t>::iterator sit;
00101 sit = findSession(session);
00102
00103 if (sit == traffic.end())
00104 {
00105 EV << "session not found in traffic database, path won't be created" << endl;
00106 return;
00107 }
00108
00109 std::vector<traffic_path_t>::iterator pit;
00110 pit = findPath(&(*sit), sender);
00111
00112 if (pit == sit->paths.end())
00113 {
00114 EV << "path doesn't belong to this session according to our database, doing nothing" << endl;
00115 return;
00116 }
00117
00118 PathStateBlock_t *psb = createIngressPSB(*sit, *pit);
00119 if (psb)
00120 {
00121
00122 scheduleRefreshTimer(psb, 0.0);
00123 }
00124 else
00125 {
00126 EV << "ingress PSB couln't be created" << endl;
00127
00128
00129 sendPathNotify(pit->owner, sit->sobj, pit->sender, PATH_UNFEASIBLE, 0.0);
00130
00131
00132 if (!pit->permanent)
00133 {
00134 EV << "removing path from traffic database" << endl;
00135
00136 sit->paths.erase(pit--);
00137 }
00138 else
00139 {
00140 EV << "path is permanent, we will try again later" << endl;
00141
00142 sendPathNotify(getId(), sit->sobj, pit->sender, PATH_RETRY, retryInterval);
00143 }
00144 }
00145 }
00146
00147 void RSVP::readTrafficFromXML(const cXMLElement* traffic)
00148 {
00149 ASSERT(traffic);
00150 ASSERT(!strcmp(traffic->getTagName(), "sessions"));
00151 checkTags(traffic, "session");
00152 cXMLElementList list = traffic->getChildrenByTagName("session");
00153 for (cXMLElementList::iterator it=list.begin(); it != list.end(); it++)
00154 readTrafficSessionFromXML(*it);
00155 }
00156
00157 EroVector RSVP::readTrafficRouteFromXML(const cXMLElement *route)
00158 {
00159 checkTags(route, "node lnode");
00160
00161 EroVector ERO;
00162
00163 for (cXMLElement *hop = route->getFirstChild(); hop; hop = hop->getNextSibling())
00164 {
00165 EroObj_t h;
00166 if (!strcmp(hop->getTagName(), "node"))
00167 {
00168 h.L = false;
00169 h.node = IPAddressResolver().resolve(hop->getNodeValue()).get4();
00170 }
00171 else if (!strcmp(hop->getTagName(), "lnode"))
00172 {
00173 h.L = true;
00174 h.node = IPAddressResolver().resolve(hop->getNodeValue()).get4();
00175 }
00176 else
00177 {
00178 ASSERT(false);
00179 }
00180 ERO.push_back(h);
00181 }
00182
00183 return ERO;
00184 }
00185
00186 void RSVP::readTrafficSessionFromXML(const cXMLElement *session)
00187 {
00188 checkTags(session, "tunnel_id endpoint setup_pri holding_pri paths");
00189
00190 traffic_session_t newSession;
00191
00192 newSession.sobj.Tunnel_Id = getParameterIntValue(session, "tunnel_id");
00193 newSession.sobj.Extended_Tunnel_Id = routerId.getInt();
00194 newSession.sobj.DestAddress = getParameterIPAddressValue(session, "endpoint");
00195
00196 std::vector<traffic_session_t>::iterator sit = findSession(newSession.sobj);
00197
00198 bool merge;
00199
00200 if (sit != traffic.end())
00201 {
00202
00203
00204 merge = true;
00205
00206 ASSERT(!getUniqueChildIfExists(session, "holding_pri") || getParameterIntValue(session, "holding_pri") == sit->sobj.holdingPri);
00207 ASSERT(!getUniqueChildIfExists(session, "setup_pri") || getParameterIntValue(session, "setup_pri") == sit->sobj.setupPri);
00208
00209 newSession.sobj.setupPri = sit->sobj.setupPri;
00210 newSession.sobj.holdingPri = sit->sobj.holdingPri;
00211
00212 sit->sobj = newSession.sobj;
00213 }
00214 else
00215 {
00216
00217
00218 merge = false;
00219
00220 newSession.sobj.setupPri = getParameterIntValue(session, "setup_pri", 7);
00221 newSession.sobj.holdingPri = getParameterIntValue(session, "holding_pri", 7);
00222 }
00223
00224 const cXMLElement *paths = getUniqueChild(session, "paths");
00225 checkTags(paths, "path");
00226
00227 cXMLElementList list = paths->getChildrenByTagName("path");
00228 for (cXMLElementList::iterator it=list.begin(); it != list.end(); it++)
00229 {
00230 cXMLElement *path = *it;
00231 checkTags(path, "sender lspid bandwidth max_delay route permanent owner color");
00232
00233 int lspid = getParameterIntValue(path, "lspid");;
00234
00235 std::vector<traffic_path_t>::iterator pit;
00236
00237 traffic_path_t newPath;
00238
00239 newPath.sender.SrcAddress = getParameterIPAddressValue(path, "sender", routerId);
00240 newPath.sender.Lsp_Id = lspid;
00241
00242
00243
00244 if (merge)
00245 {
00246 pit = findPath(&(*sit), newPath.sender);
00247 if (pit != sit->paths.end())
00248 {
00249 EV << "path " << lspid << " already exists in this session, doing nothing" << endl;
00250 continue;
00251 }
00252 }
00253 else
00254 {
00255 pit = findPath(&newSession, newPath.sender);
00256 if (pit != newSession.paths.end())
00257 {
00258 EV << "path " << lspid << " already exists in this session, doing nothing" << endl;
00259 continue;
00260 }
00261 }
00262
00263 const char *str = getParameterStrValue(path, "owner", "");
00264 if (strlen(str))
00265 {
00266 cModule *mod = simulation.getModuleByPath(str);
00267 newPath.owner = mod->getId();
00268 }
00269 else
00270 {
00271 newPath.owner = getId();
00272 }
00273
00274 newPath.permanent = getParameterBoolValue(path, "permanent", true);
00275 newPath.color = getParameterIntValue(path, "color", 0);
00276
00277 newPath.tspec.req_bandwidth = getParameterDoubleValue(path, "bandwidth", 0.0);
00278 newPath.max_delay = getParameterDoubleValue(path, "max_delay", 0.0);
00279
00280 const cXMLElement *route = getUniqueChildIfExists(path, "route");
00281 if (route)
00282 newPath.ERO = readTrafficRouteFromXML(route);
00283
00284 if (merge)
00285 {
00286 EV << "adding new path into an existing session" << endl;
00287
00288 sit->paths.push_back(newPath);
00289 }
00290 else
00291 {
00292 EV << "adding new path into new session" << endl;
00293
00294 newSession.paths.push_back(newPath);
00295 }
00296
00297
00298
00299 sendPathNotify(getId(), newSession.sobj, newPath.sender, PATH_RETRY, 0.0);
00300 }
00301
00302 if (!merge)
00303 {
00304 EV << "adding new session into database" << endl;
00305
00306 traffic.push_back(newSession);
00307 }
00308 }
00309
00310 std::vector<RSVP::traffic_path_t>::iterator RSVP::findPath(traffic_session_t *session, const SenderTemplateObj_t &sender)
00311 {
00312 std::vector<traffic_path_t>::iterator it;
00313 for (it = session->paths.begin(); it != session->paths.end(); it++)
00314 {
00315 if (it->sender != sender)
00316 continue;
00317
00318 break;
00319 }
00320 return it;
00321 }
00322
00323 void RSVP::setupHello()
00324 {
00325 helloInterval = par("helloInterval").doubleValue();
00326 helloTimeout = par("helloTimeout").doubleValue();
00327
00328 cStringTokenizer tokenizer(par("peers"));
00329 const char *token;
00330 while ((token = tokenizer.nextToken())!=NULL)
00331 {
00332 ASSERT(ift->getInterfaceByName(token));
00333
00334 IPAddress peer = tedmod->getPeerByLocalAddress(ift->getInterfaceByName(token)->ipv4Data()->getIPAddress());
00335
00336 HelloState_t h;
00337
00338 h.timer = new HelloTimerMsg("hello timer");
00339 h.timer->setPeer(peer);
00340
00341 h.timeout = new HelloTimeoutMsg("hello timeout");
00342 h.timeout->setPeer(peer);
00343
00344 h.peer = peer;
00345
00346 if (helloInterval > 0.0)
00347 {
00348
00349
00350 h.ok = false;
00351 }
00352 else
00353 {
00354
00355
00356 h.ok = true;
00357 }
00358
00359 HelloList.push_back(h);
00360
00361 if (helloInterval > 0.0)
00362 {
00363 startHello(peer, exponential(helloInterval));
00364 }
00365 }
00366 }
00367
00368 void RSVP::startHello(IPAddress peer, simtime_t delay)
00369 {
00370 EV << "scheduling hello start in " << delay << " seconds" << endl;
00371
00372 HelloState_t *h = findHello(peer);
00373 ASSERT(h);
00374
00375 ASSERT(!h->timer->isScheduled());
00376 ASSERT(!h->timeout->isScheduled());
00377 ASSERT(!h->ok);
00378
00379 h->srcInstance = ++maxSrcInstance;
00380 h->dstInstance = 0;
00381 h->request = true;
00382 h->ack = false;
00383
00384 scheduleAt(simTime() + delay, h->timer);
00385 }
00386
00387 void RSVP::sendPathNotify(int handler, const SessionObj_t& session, const SenderTemplateObj_t& sender, int status, simtime_t delay)
00388 {
00389 if (handler < 0)
00390 return;
00391
00392 cModule *mod = simulation.getModule(handler);
00393
00394 if (!mod)
00395 return;
00396
00397 PathNotifyMsg *msg = new PathNotifyMsg("path notify");
00398
00399 msg->setSession(session);
00400 msg->setSender(sender);
00401 msg->setStatus(status);
00402
00403 if (handler == getId())
00404 scheduleAt(simTime() + delay, msg);
00405 else
00406 sendDirect(msg, delay, 0, mod, "from_rsvp");
00407 }
00408
00409 void RSVP::processHELLO_TIMEOUT(HelloTimeoutMsg* msg)
00410 {
00411 IPAddress peer = msg->getPeer();
00412
00413 EV << "hello timeout, considering " << peer << " failed" << endl;
00414
00415
00416
00417 HelloState_t *hello = findHello(peer);
00418 ASSERT(hello);
00419 hello->ok = false;
00420 ASSERT(!hello->timeout->isScheduled());
00421 cancelEvent(hello->timer);
00422
00423
00424
00425 unsigned int index = tedmod->linkIndex(routerId, peer);
00426 tedmod->ted[index].state = false;
00427 announceLinkChange(index);
00428 tedmod->rebuildRoutingTable();
00429
00430
00431
00432 for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
00433 {
00434 if (it->OutInterface != tedmod->ted[index].local)
00435 continue;
00436
00437 sendPathErrorMessage(&(*it), PATH_ERR_NEXTHOP_FAILED);
00438 }
00439 }
00440
00441 void RSVP::processHELLO_TIMER(HelloTimerMsg* msg)
00442 {
00443 IPAddress peer = msg->getPeer();
00444
00445 HelloState_t *h = findHello(peer);
00446 ASSERT(h);
00447
00448 RSVPHelloMsg *hMsg = new RSVPHelloMsg("hello message");
00449
00450 hMsg->setSrcInstance(h->srcInstance);
00451 hMsg->setDstInstance(h->dstInstance);
00452
00453 hMsg->setRequest(h->request);
00454 hMsg->setAck(h->ack);
00455
00456 int length = 10;
00457
00458
00459 length /= 10;
00460
00461 hMsg->setByteLength(length);
00462
00463 sendToIP(hMsg, peer);
00464
00465 h->ack = false;
00466
00467 scheduleAt(simTime() + helloInterval, msg);
00468 }
00469
00470 void RSVP::processPSB_TIMER(PsbTimerMsg *msg)
00471 {
00472 PathStateBlock_t *psb = findPsbById(msg->getId());
00473 ASSERT(psb);
00474
00475 refreshPath(psb);
00476 scheduleRefreshTimer(psb, PSB_REFRESH_INTERVAL);
00477 }
00478
00479 void RSVP::processPSB_TIMEOUT(PsbTimeoutMsg* msg)
00480 {
00481 PathStateBlock_t *psb = findPsbById(msg->getId());
00482 ASSERT(psb);
00483
00484 if (tedmod->isLocalAddress(psb->OutInterface))
00485 {
00486 ASSERT(psb->OutInterface == tedmod->getInterfaceAddrByPeerAddress(psb->ERO[0].node));
00487
00488 sendPathTearMessage(psb->ERO[0].node, psb->Session_Object,
00489 psb->Sender_Template_Object, psb->OutInterface, routerId, false);
00490 }
00491
00492 removePSB(psb);
00493 }
00494
00495
00496 void RSVP::processRSB_REFRESH_TIMER(RsbRefreshTimerMsg *msg)
00497 {
00498 ResvStateBlock_t *rsb = findRsbById(msg->getId());
00499 if (rsb->commitTimerMsg->isScheduled())
00500 {
00501
00502 scheduleRefreshTimer(rsb, 0.0);
00503 }
00504 else
00505 {
00506 refreshResv(rsb);
00507
00508 scheduleRefreshTimer(rsb, RSB_REFRESH_INTERVAL);
00509 }
00510 }
00511
00512 void RSVP::processRSB_COMMIT_TIMER(RsbCommitTimerMsg *msg)
00513 {
00514 ResvStateBlock_t *rsb = findRsbById(msg->getId());
00515 commitResv(rsb);
00516 }
00517
00518 void RSVP::processRSB_TIMEOUT(RsbTimeoutMsg* msg)
00519 {
00520 EV << "RSB TIMEOUT RSB " << msg->getId() << endl;
00521
00522 ResvStateBlock_t *rsb = findRsbById(msg->getId());
00523
00524 ASSERT(rsb);
00525 ASSERT(tedmod->isLocalAddress(rsb->OI));
00526
00527 for (unsigned int i = 0; i < rsb->FlowDescriptor.size(); i++)
00528 {
00529 removeRsbFilter(rsb, 0);
00530 }
00531 removeRSB(rsb);
00532 }
00533
00534 bool RSVP::doCACCheck(const SessionObj_t& session, const SenderTspecObj_t& tspec, IPAddress OI)
00535 {
00536 ASSERT(tedmod->isLocalAddress(OI));
00537
00538 int k = tedmod->linkIndex(OI);
00539
00540 double sharedBW = 0.0;
00541
00542 for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
00543 {
00544 if (it->Session_Object != session)
00545 continue;
00546
00547 if (it->Flowspec_Object.req_bandwidth <= sharedBW)
00548 continue;
00549
00550 sharedBW = it->Flowspec_Object.req_bandwidth;
00551 }
00552
00553 EV << "CACCheck: link=" << OI <<
00554 " requested=" << tspec.req_bandwidth <<
00555 " shared=" << sharedBW <<
00556 " available (immediately)=" << tedmod->ted[k].UnResvBandwidth[7] <<
00557 " available (preemptible)=" << tedmod->ted[k].UnResvBandwidth[session.setupPri] << endl;
00558
00559 return (tedmod->ted[k].UnResvBandwidth[session.setupPri] + sharedBW >= tspec.req_bandwidth);
00560 }
00561
00562 void RSVP::refreshPath(PathStateBlock_t *psbEle)
00563 {
00564 EV << "refresh path (PSB " << psbEle->id << ")" << endl;
00565
00566 IPAddress& OI = psbEle->OutInterface;
00567 EroVector& ERO = psbEle->ERO;
00568
00569 ASSERT(!OI.isUnspecified());
00570 ASSERT(tedmod->isLocalAddress(OI));
00571
00572 RSVPPathMsg *pm = new RSVPPathMsg("Path");
00573
00574 pm->setSession(psbEle->Session_Object);
00575 pm->setSenderTemplate(psbEle->Sender_Template_Object);
00576 pm->setSenderTspec(psbEle->Sender_Tspec_Object);
00577
00578 RsvpHopObj_t hop;
00579 hop.Logical_Interface_Handle = OI;
00580 hop.Next_Hop_Address = routerId;
00581 pm->setHop(hop);
00582
00583 pm->setERO(ERO);
00584 pm->setColor(psbEle->color);
00585
00586 int length = 85 + (ERO.size() * 5);
00587
00588 pm->setByteLength(length);
00589
00590 IPAddress nextHop = tedmod->getPeerByLocalAddress(OI);
00591
00592 ASSERT(ERO.size() == 0 ||ERO[0].node.equals(nextHop) || ERO[0].L);
00593
00594 sendToIP(pm, nextHop);
00595 }
00596
00597 void RSVP::refreshResv(ResvStateBlock_t *rsbEle)
00598 {
00599 EV << "refresh reservation (RSB " << rsbEle->id << ")" << endl;
00600
00601 IPAddressVector phops;
00602
00603 for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
00604 {
00605 if (it->OutInterface != rsbEle->OI)
00606 continue;
00607
00608 for (int i = 0; i < (int)rsbEle->FlowDescriptor.size(); i++)
00609 {
00610 if ((FilterSpecObj_t&)it->Sender_Template_Object != rsbEle->FlowDescriptor[i].Filter_Spec_Object)
00611 continue;
00612
00613 if (tedmod->isLocalAddress(it->Previous_Hop_Address))
00614 continue;
00615
00616 if (!find(phops, it->Previous_Hop_Address))
00617 phops.push_back(it->Previous_Hop_Address);
00618 }
00619
00620 for (IPAddressVector::iterator it = phops.begin(); it != phops.end(); it++)
00621 refreshResv(rsbEle, *it);
00622 }
00623 }
00624
00625 void RSVP::refreshResv(ResvStateBlock_t *rsbEle, IPAddress PHOP)
00626 {
00627 EV << "refresh reservation (RSB " << rsbEle->id << ") PHOP " << PHOP << endl;
00628
00629 RSVPResvMsg *msg = new RSVPResvMsg(" Resv");
00630
00631 FlowDescriptorVector flows;
00632
00633 msg->setSession(rsbEle->Session_Object);
00634
00635 RsvpHopObj_t hop;
00636 hop.Logical_Interface_Handle = tedmod->peerRemoteInterface(PHOP);
00637 hop.Next_Hop_Address = PHOP;
00638 msg->setHop(hop);
00639
00640 for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
00641 {
00642 if (it->Previous_Hop_Address != PHOP)
00643 continue;
00644
00645
00646
00647
00648 if (it->Session_Object != rsbEle->Session_Object)
00649 continue;
00650
00651 for (unsigned int c = 0; c < rsbEle->FlowDescriptor.size(); c++)
00652 {
00653 if ((FilterSpecObj_t&)it->Sender_Template_Object != rsbEle->FlowDescriptor[c].Filter_Spec_Object)
00654 continue;
00655
00656 ASSERT(rsbEle->inLabelVector.size() == rsbEle->FlowDescriptor.size());
00657
00658 FlowDescriptor_t flow;
00659 flow.Filter_Spec_Object = (FilterSpecObj_t&)it->Sender_Template_Object;
00660 flow.Flowspec_Object = (FlowSpecObj_t&)it->Sender_Tspec_Object;
00661 flow.RRO = rsbEle->FlowDescriptor[c].RRO;
00662 flow.RRO.push_back(routerId);
00663 flow.label = rsbEle->inLabelVector[c];
00664 flows.push_back(flow);
00665
00666 break;
00667 }
00668 }
00669
00670 msg->setFlowDescriptor(flows);
00671
00672 int fd_length = 0;
00673 for (unsigned int i = 0; i < flows.size(); i++)
00674 fd_length += 28 + (flows[i].RRO.size() * 4);
00675
00676 int length = 34 + fd_length;
00677
00678
00679 length /= 10;
00680
00681 msg->setByteLength(length);
00682
00683 sendToIP(msg, PHOP);
00684 }
00685
00686 void RSVP::preempt(IPAddress OI, int priority, double bandwidth)
00687 {
00688 ASSERT(tedmod->isLocalAddress(OI));
00689
00690 unsigned int index = tedmod->linkIndex(OI);
00691
00692 for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
00693 {
00694 if (it->OI != OI)
00695 continue;
00696
00697 if (it->Session_Object.holdingPri != priority)
00698 continue;
00699
00700 if (it->Flowspec_Object.req_bandwidth == 0.0)
00701 continue;
00702
00703
00704
00705 for (int i = priority; i < 8; i++)
00706 tedmod->ted[index].UnResvBandwidth[i] += it->Flowspec_Object.req_bandwidth;
00707
00708 bandwidth -= it->Flowspec_Object.req_bandwidth;
00709 it->Flowspec_Object.req_bandwidth = 0.0;
00710
00711 scheduleCommitTimer(&(*it));
00712
00713
00714
00715 if (bandwidth <= 0.0)
00716 break;
00717 }
00718 }
00719
00720 bool RSVP::allocateResource(IPAddress OI, const SessionObj_t& session, double bandwidth)
00721 {
00722 if (OI.isUnspecified())
00723 return true;
00724
00725 if (!tedmod->isLocalAddress(OI))
00726 return true;
00727
00728 if (bandwidth == 0.0)
00729 return true;
00730
00731 int setupPri = session.setupPri;
00732 int holdingPri = session.holdingPri;
00733
00734 unsigned int index = tedmod->linkIndex(OI);
00735
00736
00737
00738
00739 if (tedmod->ted[index].UnResvBandwidth[setupPri] < bandwidth)
00740 return false;
00741
00742 for (int p = holdingPri; p < 8; p++)
00743 {
00744 tedmod->ted[index].UnResvBandwidth[p] -= bandwidth;
00745
00746 if (tedmod->ted[index].UnResvBandwidth[p] < 0.0)
00747 preempt(OI, p, -tedmod->ted[index].UnResvBandwidth[p]);
00748 }
00749
00750
00751
00752 announceLinkChange(index);
00753
00754 return true;
00755 }
00756
00757 void RSVP::announceLinkChange(int tedlinkindex)
00758 {
00759 TEDChangeInfo d;
00760 d.setTedLinkIndicesArraySize(1);
00761 d.setTedLinkIndices(0, tedlinkindex);
00762 nb->fireChangeNotification(NF_TED_CHANGED, &d);
00763 }
00764
00765 void RSVP::commitResv(ResvStateBlock_t *rsb)
00766 {
00767 EV << "commit reservation (RSB " << rsb->id << ")" << endl;
00768
00769
00770
00771 EV << "currently allocated: " << rsb->Flowspec_Object << endl;
00772
00773 while(true)
00774 {
00775
00776
00777 if (rsb->FlowDescriptor.size() == 0)
00778 {
00779 removeRSB(rsb);
00780 return;
00781 }
00782
00783 FlowSpecObj_t req;
00784 req.req_bandwidth = 0.0;
00785
00786 unsigned int maxFlowIndex;
00787 for (unsigned int i = 0; i < rsb->FlowDescriptor.size(); i++)
00788 {
00789 if (rsb->FlowDescriptor[i].Flowspec_Object.req_bandwidth > req.req_bandwidth)
00790 {
00791 req.req_bandwidth = rsb->FlowDescriptor[i].Flowspec_Object.req_bandwidth;
00792 maxFlowIndex = i;
00793 }
00794 }
00795
00796 EV << "currently required: " << req << endl;
00797
00798 double needed = req.req_bandwidth - rsb->Flowspec_Object.req_bandwidth;
00799
00800 if (needed != 0.0)
00801 {
00802 if (allocateResource(rsb->OI, rsb->Session_Object, needed))
00803 {
00804
00805
00806 EV << "additional bandwidth of " << needed << " allocated sucessfully" << endl;
00807
00808 rsb->Flowspec_Object.req_bandwidth += needed;
00809 }
00810 else
00811 {
00812
00813
00814 ASSERT(rsb->inLabelVector.size() == rsb->FlowDescriptor.size());
00815
00816 EV << "not enough bandwidth to accommodate this RSB" << endl;
00817
00818 int lspid = rsb->FlowDescriptor[maxFlowIndex].Filter_Spec_Object.Lsp_Id;
00819 int oldInLabel = rsb->inLabelVector[maxFlowIndex];
00820 PathStateBlock_t *psb = findPSB(rsb->Session_Object, (SenderTemplateObj_t&)rsb->FlowDescriptor[maxFlowIndex].Filter_Spec_Object);
00821
00822 EV << "removing filter lspid=" << lspid << " (max. flow)" << endl;
00823
00824 rsb->FlowDescriptor.erase(rsb->FlowDescriptor.begin() + maxFlowIndex);
00825 rsb->inLabelVector.erase(rsb->inLabelVector.begin() + maxFlowIndex);
00826
00827 if (oldInLabel != -1)
00828 {
00829
00830
00831 sendPathErrorMessage(psb, PATH_ERR_PREEMPTED);
00832
00833 lt->removeLibEntry(oldInLabel);
00834 }
00835 else
00836 {
00837
00838
00839 sendPathErrorMessage(psb, PATH_ERR_UNFEASIBLE);
00840 }
00841
00842 continue;
00843 }
00844
00845 }
00846
00847 break;
00848 }
00849
00850
00851
00852 for (unsigned int i = 0; i < rsb->FlowDescriptor.size(); i++)
00853 {
00854 int lspid = rsb->FlowDescriptor[i].Filter_Spec_Object.Lsp_Id;
00855
00856 EV << "processing lspid=" << lspid << endl;
00857
00858 PathStateBlock_t *psb = findPSB(rsb->Session_Object, rsb->FlowDescriptor[i].Filter_Spec_Object);
00859
00860 LabelOpVector outLabel;
00861 std::string inInterface, outInterface;
00862
00863 bool IR = (psb->Previous_Hop_Address == routerId);
00864
00865 if (!IR)
00866 {
00867 IPAddress localInf = tedmod->getInterfaceAddrByPeerAddress(psb->Previous_Hop_Address);
00868 inInterface = rt->getInterfaceByAddress(localInf)->getName();
00869 }
00870 else
00871 inInterface = "any";
00872
00873
00874
00875 LabelOp lop;
00876
00877 if (tedmod->isLocalAddress(psb->OutInterface))
00878 {
00879
00880
00881 lop.optcode = IR? PUSH_OPER: SWAP_OPER;
00882 lop.label = rsb->FlowDescriptor[i].label;
00883 outLabel.push_back(lop);
00884
00885 outInterface = rt->getInterfaceByAddress(psb->OutInterface)->getName();
00886 }
00887 else
00888 {
00889
00890
00891 lop.label = 0;
00892 lop.optcode = POP_OPER;
00893 outLabel.push_back(lop);
00894
00895 outInterface = "lo0";
00896
00897 if (!tedmod->isLocalAddress(psb->Session_Object.DestAddress))
00898 {
00899 InterfaceEntry *ie = rt->getInterfaceForDestAddr(psb->Session_Object.DestAddress);
00900 if (ie)
00901 outInterface = ie->getName();
00902 }
00903 }
00904
00905 EV << "installing label for " << lspid << " outLabel=" << outLabel <<
00906 " outInterface=" << outInterface << endl;
00907
00908 ASSERT(rsb->inLabelVector.size() == rsb->FlowDescriptor.size());
00909
00910 int inLabel = lt->installLibEntry(rsb->inLabelVector[i], inInterface,
00911 outLabel, outInterface, psb->color);
00912
00913 ASSERT(inLabel >= 0);
00914
00915 if (IR && rsb->inLabelVector[i] == -1)
00916 {
00917
00918 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_CREATED, 0.0);
00919 }
00920
00921 if (rsb->inLabelVector[i] != inLabel)
00922 {
00923
00924 rsb->inLabelVector[i] = inLabel;
00925
00926
00927 rpct->bind(psb->Session_Object, psb->Sender_Template_Object, inLabel);
00928 }
00929
00930
00931 for (unsigned int j = 0; j < RSBList.size(); j++)
00932 {
00933 if (RSBList[j].OI != lspid)
00934 continue;
00935
00936 scheduleCommitTimer(&RSBList[j]);
00937 }
00938 }
00939 }
00940
00941 RSVP::ResvStateBlock_t* RSVP::createRSB(RSVPResvMsg *msg)
00942 {
00943 ResvStateBlock_t rsbEle;
00944
00945 rsbEle.id = ++maxRsbId;
00946
00947 rsbEle.timeoutMsg = new RsbTimeoutMsg("rsb timeout");
00948 rsbEle.timeoutMsg->setId(rsbEle.id);
00949
00950 rsbEle.refreshTimerMsg = new RsbRefreshTimerMsg("rsb timer");
00951 rsbEle.refreshTimerMsg->setId(rsbEle.id);
00952
00953 rsbEle.commitTimerMsg = new RsbCommitTimerMsg("rsb commit");
00954 rsbEle.commitTimerMsg->setId(rsbEle.id);
00955
00956 rsbEle.Session_Object = msg->getSession();
00957 rsbEle.Next_Hop_Address = msg->getNHOP();
00958 rsbEle.OI = msg->getLIH();
00959
00960 ASSERT(rsbEle.inLabelVector.size() == rsbEle.FlowDescriptor.size());
00961
00962 for (unsigned int i = 0; i < msg->getFlowDescriptor().size(); i++)
00963 {
00964 FlowDescriptor_t flow = msg->getFlowDescriptor()[i];
00965 rsbEle.FlowDescriptor.push_back(flow);
00966 rsbEle.inLabelVector.push_back(-1);
00967 }
00968
00969 RSBList.push_back(rsbEle);
00970 ResvStateBlock_t *rsb = &(*(RSBList.end() - 1));
00971
00972 EV << "created new RSB " << rsb->id << endl;
00973
00974 return rsb;
00975 }
00976
00977 void RSVP::updateRSB(ResvStateBlock_t* rsb, RSVPResvMsg *msg)
00978 {
00979 ASSERT(rsb);
00980
00981 for (unsigned int k = 0; k < msg->getFlowDescriptor().size(); k++)
00982 {
00983 FlowDescriptor_t flow = msg->getFlowDescriptor()[k];
00984
00985 unsigned int m;
00986 for (m = 0; m < rsb->FlowDescriptor.size(); m++)
00987 {
00988 if (rsb->FlowDescriptor[m].Filter_Spec_Object == flow.Filter_Spec_Object)
00989 {
00990
00991 EV << "sender (lspid=" << flow.Filter_Spec_Object.Lsp_Id << ") found in RSB" << endl;
00992
00993 if (rsb->FlowDescriptor[m].label != flow.label)
00994 {
00995 EV << "label modified (new label=" << flow.label << ")" << endl;
00996
00997 rsb->FlowDescriptor[m].label = flow.label;
00998
00999
01000
01001 scheduleCommitTimer(rsb);
01002 }
01003
01004 break;
01005 }
01006 }
01007 if (m == rsb->FlowDescriptor.size())
01008 {
01009
01010 EV << "sender (lspid=" << flow.Filter_Spec_Object.Lsp_Id << ") not found in RSB, adding..." << endl;
01011
01012 rsb->FlowDescriptor.push_back(flow);
01013 rsb->inLabelVector.push_back(-1);
01014
01015
01016
01017 scheduleCommitTimer(rsb);
01018 scheduleRefreshTimer(rsb, 0.0);
01019 }
01020 }
01021 }
01022
01023 void RSVP::removeRsbFilter(ResvStateBlock_t *rsb, unsigned int index)
01024 {
01025 ASSERT(rsb);
01026 ASSERT(index < rsb->FlowDescriptor.size());
01027 ASSERT(rsb->inLabelVector.size() == rsb->FlowDescriptor.size());
01028
01029 int lspid = rsb->FlowDescriptor[index].Filter_Spec_Object.Lsp_Id;
01030 int inLabel = rsb->inLabelVector[index];
01031
01032 EV << "removing filter (lspid=" << lspid << ")" << endl;
01033
01034 if (inLabel != -1)
01035 lt->removeLibEntry(inLabel);
01036
01037 rsb->FlowDescriptor.erase(rsb->FlowDescriptor.begin() + index);
01038 rsb->inLabelVector.erase(rsb->inLabelVector.begin() + index);
01039
01040 scheduleCommitTimer(rsb);
01041 }
01042
01043 void RSVP::removeRSB(ResvStateBlock_t *rsb)
01044 {
01045 ASSERT(rsb);
01046 ASSERT(rsb->FlowDescriptor.size() == 0);
01047
01048 EV << "removing empty RSB " << rsb->id << endl;
01049
01050 cancelEvent(rsb->refreshTimerMsg);
01051 cancelEvent(rsb->commitTimerMsg);
01052 cancelEvent(rsb->timeoutMsg);
01053
01054 delete rsb->refreshTimerMsg;
01055 delete rsb->commitTimerMsg;
01056 delete rsb->timeoutMsg;
01057
01058 if (rsb->Flowspec_Object.req_bandwidth > 0)
01059 {
01060
01061 allocateResource(rsb->OI, rsb->Session_Object, -rsb->Flowspec_Object.req_bandwidth);
01062 }
01063
01064 for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
01065 {
01066 if (it->id != rsb->id)
01067 continue;
01068
01069 RSBList.erase(it);
01070 return;
01071 }
01072 ASSERT(false);
01073 }
01074
01075 void RSVP::removePSB(PathStateBlock_t *psb)
01076 {
01077 ASSERT(psb);
01078
01079 int lspid = psb->Sender_Template_Object.Lsp_Id;
01080
01081 EV << "removing PSB " << psb->id << " (lspid " << lspid << ")" << endl;
01082
01083
01084
01085 unsigned int filterIndex;
01086 ResvStateBlock_t *rsb = findRSB(psb->Session_Object, psb->Sender_Template_Object, filterIndex);
01087 if (rsb)
01088 {
01089 EV << "reservation state present, will be removed too" << endl;
01090
01091 removeRsbFilter(rsb, filterIndex);
01092 }
01093
01094
01095
01096 cancelEvent(psb->timerMsg);
01097 cancelEvent(psb->timeoutMsg);
01098
01099 delete psb->timerMsg;
01100 delete psb->timeoutMsg;
01101
01102 for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
01103 {
01104 if (it->id != psb->id)
01105 continue;
01106
01107 PSBList.erase(it);
01108 return;
01109 }
01110 ASSERT(false);
01111 }
01112
01113 bool RSVP::evalNextHopInterface(IPAddress destAddr, const EroVector& ERO, IPAddress& OI)
01114 {
01115 if (ERO.size() > 0)
01116 {
01117
01118
01119 if (ERO[0].L)
01120 {
01121 InterfaceEntry *ie = rt->getInterfaceForDestAddr(ERO[0].node);
01122
01123 if (!ie)
01124 {
01125 EV << "next (loose) hop address " << ERO[0].node << " is currently unroutable" << endl;
01126 return false;
01127 }
01128
01129 OI = ie->ipv4Data()->getIPAddress();
01130
01131 }
01132 else
01133 {
01134 OI = tedmod->getInterfaceAddrByPeerAddress(ERO[0].node);
01135 }
01136
01137 IPAddress peer = tedmod->getPeerByLocalAddress(OI);
01138 HelloState_t *h = findHello(peer);
01139 if (!h)
01140 error("Peer %s on interface %s is not an RSVP peer", peer.str().c_str(), OI.str().c_str());
01141
01142
01143
01144 return h->ok;
01145 }
01146 else
01147 {
01148
01149
01150 if (!tedmod->isLocalAddress(destAddr))
01151 {
01152 InterfaceEntry *ie = rt->getInterfaceForDestAddr(destAddr);
01153
01154 if (!ie)
01155 {
01156 EV << "destination address " << destAddr << " is currently unroutable" << endl;
01157 return false;
01158 }
01159
01160 OI = ie->ipv4Data()->getIPAddress();
01161
01162 HelloState_t *h = findHello(tedmod->getPeerByLocalAddress(OI));
01163 if (!h)
01164 {
01165
01166
01167 OI = IPAddress();
01168
01169 return true;
01170 }
01171 else
01172 {
01173
01174
01175 ASSERT(h->ok);
01176
01177 return h->ok;
01178 }
01179 }
01180 else
01181 {
01182
01183
01184 return true;
01185 }
01186 }
01187 }
01188
01189 RSVP::PathStateBlock_t* RSVP::createPSB(RSVPPathMsg *msg)
01190 {
01191 const EroVector& ERO = msg->getERO();
01192 IPAddress destAddr = msg->getDestAddress();
01193
01194
01195
01196 IPAddress OI;
01197
01198 if (!evalNextHopInterface(destAddr, ERO, OI))
01199 return NULL;
01200
01201 if (tedmod->isLocalAddress(OI) && !doCACCheck(msg->getSession(), msg->getSenderTspec(), OI))
01202 return NULL;
01203
01204 PathStateBlock_t psbEle;
01205
01206 psbEle.id = ++maxPsbId;
01207
01208 psbEle.timeoutMsg = new PsbTimeoutMsg("psb timeout");
01209 psbEle.timeoutMsg->setId(psbEle.id);
01210
01211 psbEle.timerMsg = new PsbTimerMsg("psb timer");
01212 psbEle.timerMsg->setId(psbEle.id);
01213
01214 psbEle.Session_Object = msg->getSession();
01215 psbEle.Sender_Template_Object = msg->getSenderTemplate();
01216 psbEle.Sender_Tspec_Object = msg->getSenderTspec();
01217
01218 psbEle.Previous_Hop_Address = msg->getNHOP();
01219
01220
01221 psbEle.OutInterface = OI;
01222 psbEle.ERO = ERO;
01223
01224 psbEle.color = msg->getColor();
01225 psbEle.handler = -1;
01226
01227 PSBList.push_back(psbEle);
01228 PathStateBlock_t *cPSB = &(*(PSBList.end() - 1));
01229
01230 EV << "created new PSB " << cPSB->id << endl;
01231
01232 return cPSB;
01233 }
01234
01235 RSVP::PathStateBlock_t* RSVP::createIngressPSB(const traffic_session_t& session, const traffic_path_t& path)
01236 {
01237 EroVector ERO = path.ERO;
01238
01239 while(ERO.size() > 0 && ERO[0].node == routerId)
01240 {
01241
01242 ERO.erase(ERO.begin());
01243 }
01244
01245 IPAddress OI;
01246
01247 if (!evalNextHopInterface(session.sobj.DestAddress, ERO, OI))
01248 return NULL;
01249
01250 if (!doCACCheck(session.sobj, path.tspec, OI))
01251 return NULL;
01252
01253 EV << "CACCheck passed, creating PSB" << endl;
01254
01255 PathStateBlock_t psbEle;
01256 psbEle.id = ++maxPsbId;
01257
01258 psbEle.timeoutMsg = new PsbTimeoutMsg("psb timeout");
01259 psbEle.timeoutMsg->setId(psbEle.id);
01260
01261 psbEle.timerMsg = new PsbTimerMsg("psb timer");
01262 psbEle.timerMsg->setId(psbEle.id);
01263
01264 psbEle.Session_Object = session.sobj;
01265 psbEle.Sender_Template_Object = path.sender;
01266 psbEle.Sender_Tspec_Object = path.tspec;
01267
01268 psbEle.Previous_Hop_Address = routerId;
01269
01270 psbEle.OutInterface = OI;
01271 psbEle.ERO = ERO;
01272 psbEle.color = path.color;
01273
01274 psbEle.handler = path.owner;
01275
01276 PSBList.push_back(psbEle);
01277 PathStateBlock_t *cPSB = &(*(PSBList.end() - 1));
01278
01279 return cPSB;
01280 }
01281
01282
01283 RSVP::ResvStateBlock_t* RSVP::createEgressRSB(PathStateBlock_t *psb)
01284 {
01285 ResvStateBlock_t rsbEle;
01286
01287 rsbEle.id = ++maxRsbId;
01288
01289 rsbEle.timeoutMsg = new RsbTimeoutMsg("rsb timeout");
01290 rsbEle.timeoutMsg->setId(rsbEle.id);
01291
01292 rsbEle.refreshTimerMsg = new RsbRefreshTimerMsg("rsb timer");
01293 rsbEle.refreshTimerMsg->setId(rsbEle.id);
01294
01295 rsbEle.commitTimerMsg = new RsbCommitTimerMsg("rsb commit");
01296 rsbEle.commitTimerMsg->setId(rsbEle.id);
01297
01298 rsbEle.Session_Object = psb->Session_Object;
01299 rsbEle.Next_Hop_Address = psb->Previous_Hop_Address;
01300
01301 rsbEle.OI = psb->OutInterface;
01302
01303 FlowDescriptor_t flow;
01304 flow.Flowspec_Object = (FlowSpecObj_t&)psb->Sender_Tspec_Object;
01305 flow.Filter_Spec_Object = (FilterSpecObj_t&)psb->Sender_Template_Object;
01306 flow.label = -1;
01307
01308 rsbEle.FlowDescriptor.push_back(flow);
01309 rsbEle.inLabelVector.push_back(-1);
01310
01311 RSBList.push_back(rsbEle);
01312 ResvStateBlock_t *rsb = &(*(RSBList.end() - 1));
01313
01314 EV << "created new (egress) RSB " << rsb->id << endl;
01315
01316 return rsb;
01317 }
01318
01319 void RSVP::handleMessage(cMessage *msg)
01320 {
01321 SignallingMsg *sMsg = dynamic_cast<SignallingMsg*>(msg);
01322 RSVPMessage *rMsg = dynamic_cast<RSVPMessage*>(msg);
01323
01324 if (sMsg)
01325 {
01326 processSignallingMessage(sMsg);
01327 return;
01328 }
01329 else if (rMsg)
01330 {
01331 processRSVPMessage(rMsg);
01332 return;
01333 }
01334 else
01335 ASSERT(false);
01336 }
01337
01338 void RSVP::processRSVPMessage(RSVPMessage *msg)
01339 {
01340 int kind = msg->getRsvpKind();
01341 switch(kind)
01342 {
01343 case PATH_MESSAGE:
01344 processPathMsg(check_and_cast<RSVPPathMsg*>(msg));
01345 break;
01346
01347 case RESV_MESSAGE:
01348 processResvMsg(check_and_cast<RSVPResvMsg*>(msg));
01349 break;
01350
01351 case PTEAR_MESSAGE:
01352 processPathTearMsg(check_and_cast<RSVPPathTear*>(msg));
01353 break;
01354
01355 case HELLO_MESSAGE:
01356 processHelloMsg(check_and_cast<RSVPHelloMsg*>(msg));
01357 break;
01358
01359 case PERROR_MESSAGE:
01360 processPathErrMsg(check_and_cast<RSVPPathError*>(msg));
01361 break;
01362
01363 default:
01364 ASSERT(false);
01365 }
01366 }
01367
01368 void RSVP::processHelloMsg(RSVPHelloMsg* msg)
01369 {
01370 EV << "Received RSVP_HELLO" << endl;
01371
01372
01373 IPControlInfo *controlInfo = check_and_cast<IPControlInfo*>(msg->getControlInfo());
01374 IPAddress sender = controlInfo->getSrcAddr();
01375 IPAddress peer = tedmod->primaryAddress(sender);
01376
01377 bool request = msg->getRequest();
01378 bool ack = msg->getAck();
01379
01380 EV << "hello sender " << peer;
01381 if (request) EV << " REQ";
01382 if (ack) EV << " ACK";
01383 EV << endl;
01384
01385 int rcvSrcInstance = msg->getSrcInstance();
01386 int rcvDstInstance = msg->getDstInstance();
01387
01388 delete msg;
01389
01390 HelloState_t *h = findHello(peer);
01391 ASSERT(h);
01392
01393 ASSERT(h->srcInstance);
01394 ASSERT(rcvSrcInstance);
01395
01396 bool failure = false;
01397
01398 if (h->srcInstance != rcvDstInstance)
01399 {
01400 if (rcvDstInstance != 0)
01401 {
01402 failure = true;
01403 }
01404 else
01405 {
01406 ASSERT(request);
01407 }
01408 }
01409
01410 if (h->dstInstance != rcvSrcInstance)
01411 {
01412 if (h->dstInstance != 0)
01413 {
01414 failure = true;
01415 }
01416 h->dstInstance = rcvSrcInstance;
01417 }
01418
01419 if (failure)
01420 {
01421
01422 h->srcInstance = ++maxSrcInstance;
01423 }
01424
01425 if (failure || !h->ok)
01426 {
01427 h->ok = true;
01428
01429 EV << "local peer " << peer << " is now considered up and running" << endl;
01430
01431 recoveryEvent(peer);
01432
01433
01434 if (!h->timer->isScheduled())
01435 scheduleAt(simTime(), h->timer);
01436 }
01437
01438 if (request)
01439 {
01440
01441 h->ack = true;
01442 h->request = false;
01443
01444 cancelEvent(h->timer);
01445 scheduleAt(simTime(), h->timer);
01446 }
01447 else
01448 {
01449
01450
01451 h->ack = false;
01452 h->request = false;
01453
01454 ASSERT(h->timer->isScheduled());
01455 }
01456
01457 cancelEvent(h->timeout);
01458 scheduleAt(simTime() + helloTimeout, h->timeout);
01459 }
01460
01461 void RSVP::processPathErrMsg(RSVPPathError* msg)
01462 {
01463 EV << "Received PATH_ERROR" << endl;
01464
01465
01466
01467 int errCode = msg->getErrorCode();
01468
01469 PathStateBlock_t *psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01470 if (!psb)
01471 {
01472 EV << "matching PSB not found, ignoring error message" << endl;
01473 delete msg;
01474 return;
01475 }
01476
01477 if (psb->Previous_Hop_Address != routerId)
01478 {
01479 EV << "forwarding error message to PHOP (" << psb->Previous_Hop_Address << ")" << endl;
01480
01481 msg->removeControlInfo();
01482 sendToIP(msg, psb->Previous_Hop_Address);
01483 }
01484 else
01485 {
01486 EV << "error reached ingress router" << endl;
01487
01488 switch(errCode)
01489 {
01490 case PATH_ERR_PREEMPTED:
01491 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_PREEMPTED, 0.0);
01492 break;
01493
01494 case PATH_ERR_UNFEASIBLE:
01495 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_UNFEASIBLE, 0.0);
01496 break;
01497
01498 case PATH_ERR_NEXTHOP_FAILED:
01499 sendPathNotify(psb->handler, psb->Session_Object, psb->Sender_Template_Object, PATH_FAILED, 0.0);
01500 break;
01501
01502 default:
01503 ASSERT(false);
01504 }
01505
01506 delete msg;
01507 }
01508 }
01509
01510 void RSVP::processPathTearMsg(RSVPPathTear *msg)
01511 {
01512 EV << "Received PATH_TEAR" << endl;
01513
01514
01515 int lspid = msg->getLspId();
01516
01517 PathStateBlock_t *psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01518 if (!psb)
01519 {
01520 EV << "received PATH_TEAR for nonexisting lspid=" << lspid << endl;
01521 delete msg;
01522 return;
01523 }
01524
01525
01526
01527 bool modified = false;
01528
01529 for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
01530 {
01531 if (it->OutInterface.getInt() != lspid)
01532 continue;
01533
01534
01535
01536 if (!msg->getForce())
01537 {
01538 EV << "merging backup tunnel exists and force flag is not set, ignoring teardown" << endl;
01539 delete msg;
01540 return;
01541 }
01542
01543 EV << "merging backup must be removed too" << endl;
01544
01545 removePSB(&(*it));
01546 --it;
01547
01548 modified = true;
01549 }
01550
01551 if (modified)
01552 psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01553
01554
01555
01556 if (psb->ERO.size() > 0)
01557 {
01558 EV << "forward teardown downstream" << endl;
01559
01560 sendPathTearMessage(psb->ERO[0].node, psb->Session_Object, psb->Sender_Template_Object,
01561 tedmod->getInterfaceAddrByPeerAddress(psb->ERO[0].node), routerId, msg->getForce());
01562 }
01563
01564
01565
01566 removePSB(psb);
01567
01568 delete msg;
01569 }
01570
01571 void RSVP::processPathMsg(RSVPPathMsg *msg)
01572 {
01573 EV << "Received PATH_MESSAGE" << endl;
01574 print(msg);
01575
01576
01577
01578 EroVector ERO = msg->getERO();
01579
01580 while(ERO.size() > 0 && ERO[0].node == routerId)
01581 {
01582 ERO.erase(ERO.begin());
01583 }
01584
01585 msg->setERO(ERO);
01586
01587
01588
01589 PathStateBlock_t *psb = findPSB(msg->getSession(), msg->getSenderTemplate());
01590
01591 if (!psb)
01592 {
01593 psb = createPSB(msg);
01594 if (!psb)
01595 {
01596 sendPathErrorMessage(msg->getSession(), msg->getSenderTemplate(),
01597 msg->getSenderTspec(), msg->getNHOP(), PATH_ERR_UNFEASIBLE);
01598 delete msg;
01599 return;
01600 }
01601 scheduleRefreshTimer(psb, 0.0);
01602
01603 if (tedmod->isLocalAddress(psb->OutInterface))
01604 {
01605 unsigned int index = tedmod->linkIndex(psb->OutInterface);
01606 if (!tedmod->ted[index].state)
01607 {
01608 sendPathErrorMessage(psb, PATH_ERR_NEXTHOP_FAILED);
01609 }
01610 }
01611 }
01612
01613
01614
01615 scheduleTimeout(psb);
01616
01617
01618
01619 unsigned int index;
01620 ResvStateBlock_t *rsb = findRSB(msg->getSession(), msg->getSenderTemplate(), index);
01621
01622 if (!rsb && psb->OutInterface.isUnspecified())
01623 {
01624 ASSERT(ERO.size() == 0);
01625 rsb = createEgressRSB(psb);
01626 ASSERT(rsb);
01627 scheduleCommitTimer(rsb);
01628 }
01629
01630 if (rsb)
01631 scheduleRefreshTimer(rsb, 0.0);
01632
01633 delete msg;
01634 }
01635
01636 void RSVP::processResvMsg(RSVPResvMsg *msg)
01637 {
01638 EV << "Received RESV_MESSAGE" << endl;
01639 print(msg);
01640
01641 IPAddress OI = msg->getLIH();
01642
01643
01644
01645 for (unsigned int m = 0; m < msg->getFlowDescriptor().size(); m++)
01646 {
01647
01648 PathStateBlock_t *psb = findPSB(msg->getSession(), (SenderTemplateObj_t&)msg->getFlowDescriptor()[m].Filter_Spec_Object);
01649 if (!psb)
01650 {
01651 EV << "matching PSB not found for lspid=" << msg->getFlowDescriptor()[m].Filter_Spec_Object.Lsp_Id << endl;
01652
01653
01654 msg->getFlowDescriptor().erase(msg->getFlowDescriptor().begin() + m);
01655 --m;
01656 }
01657 }
01658
01659 if (msg->getFlowDescriptor().size() == 0)
01660 {
01661 EV << "no matching PSB found" << endl;
01662 delete msg;
01663 return;
01664 }
01665
01666
01667
01668 ResvStateBlock_t *rsb = NULL;
01669 for (RSBVector::iterator it = RSBList.begin(); it != RSBList.end(); it++)
01670 {
01671 if (!(msg->isInSession(&it->Session_Object)))
01672 continue;
01673
01674 if (it->Next_Hop_Address != msg->getNHOP())
01675 continue;
01676
01677 if (it->OI != msg->getLIH())
01678 continue;
01679
01680 rsb = &(*it);
01681 break;
01682 }
01683
01684 if (!rsb)
01685 {
01686 rsb = createRSB(msg);
01687
01688 scheduleCommitTimer(rsb);
01689
01690
01691 scheduleRefreshTimer(rsb, 0.0);
01692 }
01693 else
01694 updateRSB(rsb, msg);
01695
01696 scheduleTimeout(rsb);
01697
01698 delete msg;
01699 }
01700
01701 void RSVP::recoveryEvent(IPAddress peer)
01702 {
01703
01704
01705 unsigned int index = tedmod->linkIndex(routerId, peer);
01706 bool rtmodified = !tedmod->ted[index].state;
01707 tedmod->ted[index].state = true;
01708 announceLinkChange(index);
01709
01710
01711 if (rtmodified)
01712 tedmod->rebuildRoutingTable();
01713
01714
01715 for (PSBVector::iterator it = PSBList.begin(); it != PSBList.end(); it++)
01716 {
01717 if (it->OutInterface != tedmod->ted[index].local)
01718 continue;
01719
01720 scheduleRefreshTimer(&(*it), 0.0);
01721 }
01722 }
01723
01724 void RSVP::processSignallingMessage(SignallingMsg *msg)
01725 {
01726 int command = msg->getCommand();
01727 switch(command)
01728 {
01729 case MSG_PSB_TIMER:
01730 processPSB_TIMER(check_and_cast<PsbTimerMsg*>(msg));
01731 break;
01732
01733 case MSG_PSB_TIMEOUT:
01734 processPSB_TIMEOUT(check_and_cast<PsbTimeoutMsg*>(msg));
01735 break;
01736
01737 case MSG_RSB_REFRESH_TIMER:
01738 processRSB_REFRESH_TIMER(check_and_cast<RsbRefreshTimerMsg*>(msg));
01739 break;
01740
01741 case MSG_RSB_COMMIT_TIMER:
01742 processRSB_COMMIT_TIMER(check_and_cast<RsbCommitTimerMsg*>(msg));
01743 break;
01744
01745 case MSG_RSB_TIMEOUT:
01746 processRSB_TIMEOUT(check_and_cast<RsbTimeoutMsg*>(msg));
01747 break;
01748
01749 case MSG_HELLO_TIMER:
01750 processHELLO_TIMER(check_and_cast<HelloTimerMsg*>(msg));
01751 break;
01752
01753 case MSG_HELLO_TIMEOUT:
01754 processHELLO_TIMEOUT(check_and_cast<HelloTimeoutMsg*>(msg));
01755 break;
01756
01757 case MSG_PATH_NOTIFY:
01758 processPATH_NOTIFY(check_and_cast<PathNotifyMsg*>(msg));
01759 break;
01760
01761 default:
01762 ASSERT(false);
01763 }
01764 }
01765
01766 void RSVP::pathProblem(PathStateBlock_t *psb)
01767 {
01768 ASSERT(psb);
01769 ASSERT(!psb->OutInterface.isUnspecified());
01770
01771 IPAddress nextHop = tedmod->getPeerByLocalAddress(psb->OutInterface);
01772
01773 EV << "sending PathTear to " << nextHop << endl;
01774
01775 sendPathTearMessage(nextHop, psb->Session_Object, psb->Sender_Template_Object,
01776 tedmod->getInterfaceAddrByPeerAddress(nextHop), routerId, true);
01777
01778
01779
01780 std::vector<traffic_session_t>::iterator sit = findSession(psb->Session_Object);
01781 ASSERT(sit != traffic.end());
01782 traffic_session_t *s = &(*sit);
01783
01784 std::vector<traffic_path_t>::iterator pit = findPath(s, psb->Sender_Template_Object);
01785 ASSERT(pit != s->paths.end());
01786 traffic_path_t *p = &(*pit);
01787
01788 if (p->permanent)
01789 {
01790 EV << "this path is permanent, we will try to re-create it later" << endl;
01791
01792 sendPathNotify(getId(), psb->Session_Object, psb->Sender_Template_Object, PATH_RETRY, retryInterval);
01793
01794 }
01795 else
01796 {
01797 EV << "removing path from traffic database" << endl;
01798
01799 sit->paths.erase(pit);
01800 }
01801
01802
01803
01804 EV << "removing PSB" << endl;
01805
01806 removePSB(psb);
01807 }
01808
01809 void RSVP::processPATH_NOTIFY(PathNotifyMsg* msg)
01810 {
01811 PathStateBlock_t *psb;
01812
01813 switch(msg->getStatus())
01814 {
01815 case PATH_RETRY:
01816 createPath(msg->getSession(), msg->getSender());
01817 break;
01818
01819 case PATH_UNFEASIBLE:
01820 case PATH_PREEMPTED:
01821 case PATH_FAILED:
01822 psb = findPSB(msg->getSession(), msg->getSender());
01823 if (psb)
01824 pathProblem(psb);
01825 break;
01826
01827 case PATH_CREATED:
01828 EV << "Path successfully established" << endl;
01829 break;
01830
01831
01832 default:
01833 ASSERT(false);
01834 }
01835
01836 delete msg;
01837 }
01838
01839
01840 std::vector<RSVP::traffic_session_t>::iterator RSVP::findSession(const SessionObj_t& session)
01841 {
01842 std::vector<traffic_session_t>::iterator it;
01843 for (it = traffic.begin(); it != traffic.end(); it++)
01844 {
01845 if (it->sobj != session)
01846 continue;
01847
01848 break;
01849 }
01850
01851 return it;
01852 }
01853
01854 void RSVP::addSession(const cXMLElement& node)
01855 {
01856 Enter_Method_Silent();
01857
01858 readTrafficSessionFromXML(&node);
01859 }
01860
01861 void RSVP::delSession(const cXMLElement& node)
01862 {
01863 Enter_Method_Silent();
01864
01865 checkTags(&node, "tunnel_id extended_tunnel_id endpoint paths");
01866
01867 SessionObj_t sobj;
01868
01869 sobj.Tunnel_Id = getParameterIntValue(&node, "tunnel_id");
01870 sobj.Extended_Tunnel_Id = getParameterIPAddressValue(&node, "extended_tunnel_id", routerId).getInt();
01871 sobj.DestAddress = getParameterIPAddressValue(&node, "endpoint");
01872
01873 std::vector<traffic_session_t>::iterator sit = findSession(sobj);
01874 ASSERT(sit != traffic.end());
01875 traffic_session_t *session = &(*sit);
01876
01877 const cXMLElement *paths = getUniqueChildIfExists(&node, "paths");
01878 cXMLElementList pathList;
01879 if (paths)
01880 {
01881
01882
01883 checkTags(paths, "path");
01884 pathList = paths->getChildrenByTagName("path");
01885 }
01886
01887 std::vector<traffic_path_t>::iterator it;
01888 for (it = session->paths.begin(); it != session->paths.end(); it++)
01889 {
01890 bool remove;
01891
01892 if (paths)
01893 {
01894 remove = false;
01895
01896 for (cXMLElementList::iterator p=pathList.begin(); p != pathList.end(); p++)
01897 {
01898 if (it->sender.Lsp_Id != getParameterIntValue(*p, "lspid"))
01899 continue;
01900
01901
01902
01903 remove = true;
01904 break;
01905 }
01906 }
01907 else
01908 {
01909
01910
01911 remove = true;
01912 }
01913
01914 if (remove)
01915 {
01916 PathStateBlock_t *psb = findPSB(session->sobj, it->sender);
01917 if (psb)
01918 {
01919 ASSERT(psb->ERO.size() > 0);
01920
01921 sendPathTearMessage(psb->ERO[0].node, psb->Session_Object, psb->Sender_Template_Object,
01922 tedmod->getInterfaceAddrByPeerAddress(psb->ERO[0].node), routerId, true);
01923
01924 removePSB(psb);
01925 }
01926
01927 session->paths.erase(it--);
01928 }
01929 }
01930
01931 if (!paths)
01932 {
01933 traffic.erase(sit);
01934 }
01935 }
01936
01937 void RSVP::processCommand(const cXMLElement& node)
01938 {
01939 if (!strcmp(node.getTagName(), "add-session"))
01940 {
01941 addSession(node);
01942 }
01943 else if (!strcmp(node.getTagName(), "del-session"))
01944 {
01945 delSession(node);
01946 }
01947 else
01948 ASSERT(false);
01949 }
01950
01951 void RSVP::sendPathTearMessage(IPAddress peerIP, const SessionObj_t& session, const SenderTemplateObj_t& sender, IPAddress LIH, IPAddress NHOP, bool force)
01952 {
01953 RSVPPathTear *msg = new RSVPPathTear("PathTear");
01954 msg->setSenderTemplate(sender);
01955 msg->setSession(session);
01956 RsvpHopObj_t hop;
01957 hop.Logical_Interface_Handle = LIH;
01958 hop.Next_Hop_Address = NHOP;
01959 msg->setHop(hop);
01960 msg->setForce(force);
01961
01962 int length = 44;
01963
01964 msg->setByteLength(length);
01965
01966 sendToIP(msg, peerIP);
01967 }
01968
01969 void RSVP::sendPathErrorMessage(PathStateBlock_t *psb, int errCode)
01970 {
01971 sendPathErrorMessage(psb->Session_Object, psb->Sender_Template_Object, psb->Sender_Tspec_Object, psb->Previous_Hop_Address, errCode);
01972 }
01973
01974 void RSVP::sendPathErrorMessage(SessionObj_t session, SenderTemplateObj_t sender, SenderTspecObj_t tspec, IPAddress nextHop, int errCode)
01975 {
01976 RSVPPathError *msg = new RSVPPathError("PathErr");
01977 msg->setErrorCode(errCode);
01978 msg->setErrorNode(routerId);
01979 msg->setSession(session);
01980 msg->setSenderTemplate(sender);
01981 msg->setSenderTspec(tspec);
01982
01983 int length = 52;
01984
01985
01986 length /= 10;
01987
01988 msg->setByteLength(length);
01989
01990 sendToIP(msg, nextHop);
01991 }
01992
01993
01994 void RSVP::sendToIP(cMessage *msg, IPAddress destAddr)
01995 {
01996 IPControlInfo *controlInfo = new IPControlInfo();
01997 controlInfo->setDestAddr(destAddr);
01998 controlInfo->setProtocol(IP_PROT_RSVP);
01999 msg->setControlInfo(controlInfo);
02000
02001 msg->addPar("color") = RSVP_TRAFFIC;
02002
02003 send(msg, "ipOut");
02004 }
02005
02006 void RSVP::scheduleTimeout(PathStateBlock_t *psbEle)
02007 {
02008 ASSERT(psbEle);
02009
02010 if (psbEle->timeoutMsg->isScheduled())
02011 cancelEvent(psbEle->timeoutMsg);
02012
02013 scheduleAt(simTime() + PSB_TIMEOUT_INTERVAL, psbEle->timeoutMsg);
02014 }
02015
02016 void RSVP::scheduleRefreshTimer(PathStateBlock_t *psbEle, simtime_t delay)
02017 {
02018 ASSERT(psbEle);
02019
02020 if (psbEle->OutInterface.isUnspecified())
02021 return;
02022
02023 if (!tedmod->isLocalAddress(psbEle->OutInterface))
02024 return;
02025
02026 if (psbEle->timerMsg->isScheduled())
02027 cancelEvent(psbEle->timerMsg);
02028
02029 EV << "scheduling PSB " << psbEle->id << " refresh " << (simTime() + delay) << endl;
02030
02031 scheduleAt(simTime() + delay, psbEle->timerMsg);
02032 }
02033
02034 void RSVP::scheduleTimeout(ResvStateBlock_t *rsbEle)
02035 {
02036 ASSERT(rsbEle);
02037
02038 if (rsbEle->timeoutMsg->isScheduled())
02039 cancelEvent(rsbEle->timeoutMsg);
02040
02041 scheduleAt(simTime() + RSB_TIMEOUT_INTERVAL, rsbEle->timeoutMsg);
02042 }
02043
02044 void RSVP::scheduleRefreshTimer(ResvStateBlock_t *rsbEle, simtime_t delay)
02045 {
02046 ASSERT(rsbEle);
02047
02048 if (rsbEle->refreshTimerMsg->isScheduled())
02049 cancelEvent(rsbEle->refreshTimerMsg);
02050
02051 scheduleAt(simTime() + delay, rsbEle->refreshTimerMsg);
02052 }
02053
02054 void RSVP::scheduleCommitTimer(ResvStateBlock_t *rsbEle)
02055 {
02056 ASSERT(rsbEle);
02057
02058 if (rsbEle->commitTimerMsg->isScheduled())
02059 cancelEvent(rsbEle->commitTimerMsg);
02060
02061 scheduleAt(simTime(), rsbEle->commitTimerMsg);
02062 }
02063
02064 RSVP::ResvStateBlock_t* RSVP::findRSB(const SessionObj_t& session, const SenderTemplateObj_t& sender, unsigned int& index)
02065 {
02066 RSBVector::iterator it;
02067
02068 for (it = RSBList.begin(); it != RSBList.end(); it++)
02069 {
02070 if (it->Session_Object != session)
02071 continue;
02072
02073 FlowDescriptorVector::iterator fit;
02074 index = 0;
02075 for (fit = it->FlowDescriptor.begin(); fit != it->FlowDescriptor.end(); fit++)
02076 {
02077 if ((SenderTemplateObj_t&)fit->Filter_Spec_Object != sender)
02078 {
02079 ++index;
02080 continue;
02081 }
02082
02083 return &(*it);
02084 }
02085
02086
02087 }
02088 return NULL;
02089 }
02090
02091 RSVP::PathStateBlock_t* RSVP::findPSB(const SessionObj_t& session, const SenderTemplateObj_t& sender)
02092 {
02093 PSBVector::iterator it;
02094 for (it = PSBList.begin(); it != PSBList.end(); it++)
02095 {
02096 if (it->Session_Object != session)
02097 continue;
02098
02099 if (it->Sender_Template_Object != sender)
02100 continue;
02101
02102 return &(*it);
02103 }
02104
02105 return NULL;
02106 }
02107
02108 RSVP::PathStateBlock_t* RSVP::findPsbById(int id)
02109 {
02110 for (unsigned int i = 0; i < PSBList.size(); i++)
02111 {
02112 if (PSBList[i].id != id)
02113 continue;
02114
02115 return &PSBList[i];
02116 }
02117 ASSERT(false);
02118 return NULL;
02119 }
02120
02121
02122 RSVP::ResvStateBlock_t* RSVP::findRsbById(int id)
02123 {
02124 for (unsigned int i = 0; i < RSBList.size(); i++)
02125 {
02126 if (RSBList[i].id != id)
02127 continue;
02128
02129 return &RSBList[i];
02130 }
02131 ASSERT(false);
02132 return NULL;
02133 }
02134
02135 RSVP::HelloState_t* RSVP::findHello(IPAddress peer)
02136 {
02137 for (HelloVector::iterator it = HelloList.begin(); it != HelloList.end(); it++)
02138 {
02139 if (it->peer != peer)
02140 continue;
02141
02142 return &(*it);
02143 }
02144 return NULL;
02145 }
02146
02147 bool operator==(const SessionObj_t& a, const SessionObj_t& b)
02148 {
02149 return (a.DestAddress == b.DestAddress &&
02150 a.Tunnel_Id == b.Tunnel_Id &&
02151 a.Extended_Tunnel_Id == b.Extended_Tunnel_Id);
02152
02153
02154 }
02155
02156 bool operator!=(const SessionObj_t& a, const SessionObj_t& b)
02157 {
02158 return !operator==(a, b);
02159 }
02160
02161 bool operator==(const FilterSpecObj_t& a, const FilterSpecObj_t& b)
02162 {
02163 return a.SrcAddress==b.SrcAddress && a.Lsp_Id==b.Lsp_Id;
02164 }
02165
02166 bool operator!=(const FilterSpecObj_t& a, const FilterSpecObj_t& b)
02167 {
02168 return !operator==(a, b);
02169 }
02170
02171 bool operator==(const SenderTemplateObj_t& a, const SenderTemplateObj_t& b)
02172 {
02173 return a.SrcAddress == b.SrcAddress && a.Lsp_Id == b.Lsp_Id;
02174 }
02175
02176 bool operator!=(const SenderTemplateObj_t& a, const SenderTemplateObj_t& b)
02177 {
02178 return !operator==(a, b);
02179 }
02180
02181 std::ostream& operator<<(std::ostream& os, const FlowSpecObj_t& a)
02182 {
02183 os << "{bandwidth:" << a.req_bandwidth << "}";
02184 return os;
02185 }
02186
02187 std::ostream& operator<<(std::ostream& os, const SessionObj_t& a)
02188 {
02189 os << "{tunnelId:" << a.Tunnel_Id << " exTunnelId:" << a.Extended_Tunnel_Id <<
02190 " destAddr:" << a.DestAddress << "}";
02191 return os;
02192 }
02193
02194 std::ostream& operator<<(std::ostream& os, const SenderTemplateObj_t& a)
02195 {
02196 os << "{lspid:" << a.Lsp_Id << " sender:" << a.SrcAddress << "}";
02197 return os;
02198 }
02199
02200 void RSVP::print(RSVPPathMsg *p)
02201 {
02202 EV << "PATH_MESSAGE: lspid " << p->getLspId() << " ERO " << vectorToString(p->getERO()) << endl;
02203 }
02204
02205 void RSVP::print(RSVPResvMsg *r)
02206 {
02207 EV << "RESV_MESSAGE: " << endl;
02208 for (unsigned int i = 0; i < r->getFlowDescriptor().size(); i++)
02209 {
02210 EV << " lspid " << r->getFlowDescriptor()[i].Filter_Spec_Object.Lsp_Id <<
02211 " label " << r->getFlowDescriptor()[i].label << endl;
02212 }
02213 }
02214