#include <RSVP.h>
Inheritance diagram for RSVP:

Public Member Functions | |
| RSVP () | |
| virtual | ~RSVP () |
Protected Member Functions | |
| void | processSignallingMessage (SignallingMsg *msg) |
| void | processPSB_TIMER (PsbTimerMsg *msg) |
| void | processPSB_TIMEOUT (PsbTimeoutMsg *msg) |
| void | processRSB_REFRESH_TIMER (RsbRefreshTimerMsg *msg) |
| void | processRSB_COMMIT_TIMER (RsbCommitTimerMsg *msg) |
| void | processRSB_TIMEOUT (RsbTimeoutMsg *msg) |
| void | processHELLO_TIMER (HelloTimerMsg *msg) |
| void | processHELLO_TIMEOUT (HelloTimeoutMsg *msg) |
| void | processPATH_NOTIFY (PathNotifyMsg *msg) |
| void | processRSVPMessage (RSVPMessage *msg) |
| void | processHelloMsg (RSVPHelloMsg *msg) |
| void | processPathMsg (RSVPPathMsg *msg) |
| void | processResvMsg (RSVPResvMsg *msg) |
| void | processPathTearMsg (RSVPPathTear *msg) |
| void | processPathErrMsg (RSVPPathError *msg) |
| PathStateBlock_t * | createPSB (RSVPPathMsg *msg) |
| PathStateBlock_t * | createIngressPSB (const traffic_session_t &session, const traffic_path_t &path) |
| void | removePSB (PathStateBlock_t *psb) |
| ResvStateBlock_t * | createRSB (RSVPResvMsg *msg) |
| ResvStateBlock_t * | createEgressRSB (PathStateBlock_t *psb) |
| void | updateRSB (ResvStateBlock_t *rsb, RSVPResvMsg *msg) |
| void | removeRSB (ResvStateBlock_t *rsb) |
| void | removeRsbFilter (ResvStateBlock_t *rsb, unsigned int index) |
| void | refreshPath (PathStateBlock_t *psbEle) |
| void | refreshResv (ResvStateBlock_t *rsbEle) |
| void | refreshResv (ResvStateBlock_t *rsbEle, IPAddress PHOP) |
| void | commitResv (ResvStateBlock_t *rsb) |
| void | scheduleRefreshTimer (PathStateBlock_t *psbEle, double delay) |
| void | scheduleTimeout (PathStateBlock_t *psbEle) |
| void | scheduleRefreshTimer (ResvStateBlock_t *rsbEle, double delay) |
| void | scheduleCommitTimer (ResvStateBlock_t *rsbEle) |
| void | scheduleTimeout (ResvStateBlock_t *rsbEle) |
| void | sendPathErrorMessage (PathStateBlock_t *psb, int errCode) |
| void | sendPathErrorMessage (SessionObj_t session, SenderTemplateObj_t sender, SenderTspecObj_t tspec, IPAddress nextHop, int errCode) |
| void | sendPathTearMessage (IPAddress peerIP, const SessionObj_t &session, const SenderTemplateObj_t &sender, IPAddress LIH, IPAddress NHOP, bool force) |
| void | sendPathNotify (int handler, const SessionObj_t &session, const SenderTemplateObj_t &sender, int status, double delay) |
| void | setupHello () |
| void | startHello (IPAddress peer, double delay) |
| void | recoveryEvent (IPAddress peer) |
| bool | allocateResource (IPAddress OI, const SessionObj_t &session, double bandwidth) |
| void | preempt (IPAddress OI, int priority, double bandwidth) |
| bool | doCACCheck (const SessionObj_t &session, const SenderTspecObj_t &tspec, IPAddress OI) |
| void | announceLinkChange (int tedlinkindex) |
| void | sendToIP (cMessage *msg, IPAddress destAddr) |
| bool | evalNextHopInterface (IPAddress destAddr, const EroVector &ERO, IPAddress &OI) |
| PathStateBlock_t * | findPSB (const SessionObj_t &session, const SenderTemplateObj_t &sender) |
| ResvStateBlock_t * | findRSB (const SessionObj_t &session, const SenderTemplateObj_t &sender, unsigned int &index) |
| PathStateBlock_t * | findPsbById (int id) |
| ResvStateBlock_t * | findRsbById (int id) |
| std::vector< traffic_session_t >::iterator | findSession (const SessionObj_t &session) |
| std::vector< traffic_path_t >::iterator | findPath (traffic_session_t *session, const SenderTemplateObj_t &sender) |
| HelloState_t * | findHello (IPAddress peer) |
| void | print (RSVPPathMsg *p) |
| void | print (RSVPResvMsg *r) |
| void | readTrafficFromXML (const cXMLElement *traffic) |
| void | readTrafficSessionFromXML (const cXMLElement *session) |
| EroVector | readTrafficRouteFromXML (const cXMLElement *route) |
| void | createPath (const SessionObj_t &session, const SenderTemplateObj_t &sender) |
| void | pathProblem (PathStateBlock_t *psb) |
| void | addSession (const cXMLElement &node) |
| void | delSession (const cXMLElement &node) |
| virtual int | numInitStages () const |
| virtual void | initialize (int stage) |
| virtual void | handleMessage (cMessage *msg) |
| virtual void | processCommand (const cXMLElement &node) |
Private Types | |
| typedef std::vector< PathStateBlock_t > | PSBVector |
| typedef std::vector< ResvStateBlock_t > | RSBVector |
| typedef std::vector< HelloState_t > | HelloVector |
Private Member Functions | |
| int | getInLabel (const SessionObj_t &session, const SenderTemplateObj_t &sender) |
Private Attributes | |
| std::vector< traffic_session_t > | traffic |
| double | helloInterval |
| double | helloTimeout |
| double | retryInterval |
| TED * | tedmod |
| RoutingTable * | rt |
| InterfaceTable * | ift |
| LIBTable * | lt |
| NotificationBoard * | nb |
| IRSVPClassifier * | rpct |
| int | maxPsbId |
| int | maxRsbId |
| int | maxSrcInstance |
| IPAddress | routerId |
| PSBVector | PSBList |
| RSBVector | RSBList |
| HelloVector | HelloList |
Friends | |
| class | SimpleClassifier |
Classes | |
| struct | HelloState_t |
| struct | PathStateBlock_t |
| struct | ResvStateBlock_t |
| struct | traffic_path_t |
| struct | traffic_session_t |
|
|
|
|
|
|
|
|
|
|
|
00042 {
00043 }
|
|
|
00046 {
00047 // TODO cancelAndDelete timers in all data structures
00048 }
|
|
|
01855 {
01856 Enter_Method_Silent();
01857
01858 readTrafficSessionFromXML(&node);
01859 }
|
|
||||||||||||||||
|
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 // Note: UnRB[7] <= UnRW[setupPri] <= UnRW[holdingPri] <= BW[0]
00737 // UnRW[7] is the actual BW left on the link
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 // announce changes
00751
00752 announceLinkChange(index);
00753
00754 return true;
00755 }
|
|
|
00758 {
00759 TEDChangeInfo d;
00760 d.setTedLinkIndicesArraySize(1);
00761 d.setTedLinkIndices(0, tedlinkindex);
00762 nb->fireChangeNotification(NF_TED_CHANGED, &d);
00763 }
|
|
|
00766 {
00767 EV << "commit reservation (RSB " << rsb->id << ")" << endl;
00768
00769 // allocate bandwidth as needed
00770
00771 EV << "currently allocated: " << rsb->Flowspec_Object << endl;
00772
00773 while(true)
00774 {
00775 // remove RSB if empty
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 // allocated (deallocated) successfully
00805
00806 EV << "additional bandwidth of " << needed << " allocated sucessfully" << endl;
00807
00808 rsb->Flowspec_Object.req_bandwidth += needed;
00809 }
00810 else
00811 {
00812 // bandwidth not available
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 // path already existed, this must be preemption
00830
00831 sendPathErrorMessage(psb, PATH_ERR_PREEMPTED);
00832
00833 lt->removeLibEntry(oldInLabel);
00834 }
00835 else
00836 {
00837 // path not established yet, report as unfeasible
00838
00839 sendPathErrorMessage(psb, PATH_ERR_UNFEASIBLE);
00840 }
00841
00842 continue;
00843 }
00844
00845 }
00846
00847 break;
00848 }
00849
00850 // install labels into lib
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 bool ER = psb->OutInterface.isUnspecified();
00865 if (!IR)
00866 {
00867 IPAddress localInf = tedmod->interfaceAddrByPeerAddress(psb->Previous_Hop_Address);
00868 inInterface = rt->interfaceByAddress(localInf)->name();
00869 }
00870 else
00871 inInterface = "any";
00872
00873 // outlabel and outgoing interface
00874
00875 LabelOp lop;
00876
00877 if (tedmod->isLocalAddress(psb->OutInterface))
00878 {
00879 // regular next hop
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->interfaceByAddress(psb->OutInterface)->name();
00886 }
00887 else
00888 {
00889 // egress router
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->interfaceForDestAddr(psb->Session_Object.DestAddress);
00900 if (ie)
00901 outInterface = ie->name(); // FIXME why use name to identify an interface?
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 // path established
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 // remember our current label
00924 rsb->inLabelVector[i] = inLabel;
00925
00926 // bind fec
00927 rpct->bind(psb->Session_Object, psb->Sender_Template_Object, inLabel);
00928 }
00929
00930 // schedule commit of merging backups too...
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 }
|
|
|
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 }
|
|
||||||||||||
|
01236 {
01237 EroVector ERO = path.ERO;
01238
01239 while(ERO.size() > 0 && ERO[0].node == routerId)
01240 {
01241 // remove ourselves from the beginning of the hop list
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 }
|
|
||||||||||||
|
00091 {
00092 if (findPSB(session, sender))
00093 {
00094 EV << "path (PSB) already exists, doing nothing" << endl;
00095 return;
00096 }
00097
00098 // find entry in traffic database
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 // PSB successfully created, send path message downstream
00122 scheduleRefreshTimer(psb, 0.0);
00123 }
00124 else
00125 {
00126 EV << "ingress PSB couln't be created" << endl;
00127
00128 // inform the owner of this path
00129 sendPathNotify(pit->owner, sit->sobj, pit->sender, PATH_UNFEASIBLE, 0.0);
00130
00131 // remove non-permanent path
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(id(), sit->sobj, pit->sender, PATH_RETRY, retryInterval);
00143 }
00144 }
00145 }
|
|
|
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; // not enough resources
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 //psbEle.LIH = msg->getLIH();
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 }
|
|
|
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 }
|
|
|
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 // only specified paths will be removed, session remains
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 // remove path from session
01902
01903 remove = true;
01904 break;
01905 }
01906 }
01907 else
01908 {
01909 // remove all paths
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->interfaceAddrByPeerAddress(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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
01114 {
01115 if (ERO.size() > 0)
01116 {
01117 // explicit routing
01118
01119 if (ERO[0].L)
01120 {
01121 InterfaceEntry *ie = rt->interfaceForDestAddr(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->ipv4()->inetAddress();
01130
01131 }
01132 else
01133 {
01134 OI = tedmod->interfaceAddrByPeerAddress(ERO[0].node);
01135 }
01136
01137 IPAddress peer = tedmod->peerByLocalAddress(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 // ok, only if next hop is up and running
01143
01144 return h->ok;
01145 }
01146 else
01147 {
01148 // hop-by-hop routing
01149
01150 if (!tedmod->isLocalAddress(destAddr))
01151 {
01152 InterfaceEntry *ie = rt->interfaceForDestAddr(destAddr);
01153
01154 if (!ie)
01155 {
01156 EV << "destination address " << destAddr << " is currently unroutable" << endl;
01157 return false;
01158 }
01159
01160 OI = ie->ipv4()->inetAddress();
01161
01162 HelloState_t *h = findHello(tedmod->peerByLocalAddress(OI));
01163 if (!h)
01164 {
01165 // outgoing interface is not LSR, we are egress router
01166
01167 OI = IPAddress();
01168
01169 return true;
01170 }
01171 else
01172 {
01173 // outgoing interface is LSR
01174
01175 ASSERT(h->ok); // rt->interfaceForDestAddr() wouldn't choose this entry
01176
01177 return h->ok;
01178 }
01179 }
01180 else
01181 {
01182 // destAddress is ours, we're egress
01183
01184 return true;
01185 }
01186 }
01187 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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; // prevent warning
02119 }
|
|
||||||||||||||||
|
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 // don't break here, may be in different (if outInterface is different)
02087 }
02088 return NULL;
02089 }
|
|
|
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; // prevent warning
02133 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
00051 {
00052 // we have to wait for stage 2 until interfaces get registered (stage 0)
00053 // and get their auto-assigned IP addresses (stage 2); routerId gets
00054 // assigned in state 3
00055 if (stage==4)
00056 {
00057 tedmod = TEDAccess().get();
00058 rt = RoutingTableAccess().get();
00059 ift = InterfaceTableAccess().get();
00060 routerId = rt->routerId();
00061 lt = LIBTableAccess().get();
00062 nb = NotificationBoardAccess().get();
00063
00064 rpct = check_and_cast<IRSVPClassifier*>(parentModule()->submodule("classifier"));
00065
00066 maxPsbId = 0;
00067 maxRsbId = 0;
00068 maxSrcInstance = 0;
00069
00070 retryInterval = 1.0;
00071
00072 // setup hello
00073 setupHello();
00074
00075 // process traffic configuration
00076 readTrafficFromXML(par("traffic").xmlValue());
00077 }
00078 }
|
|
|
00284 {return 5;}
|
|
|
01767 {
01768 ASSERT(psb);
01769 ASSERT(!psb->OutInterface.isUnspecified());
01770
01771 IPAddress nextHop = tedmod->peerByLocalAddress(psb->OutInterface);
01772
01773 EV << "sending PathTear to " << nextHop << endl;
01774
01775 sendPathTearMessage(nextHop, psb->Session_Object, psb->Sender_Template_Object,
01776 tedmod->interfaceAddrByPeerAddress(nextHop), routerId, true);
01777
01778 // schedule re-creation if path is permanent
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(id(), 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 // remove path
01803
01804 EV << "removing PSB" << endl;
01805
01806 removePSB(psb);
01807 }
|
|
||||||||||||||||
|
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 // preempt RSB
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 }
|
|
|
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 }
|
|
|
02201 {
02202 EV << "PATH_MESSAGE: lspid " << p->getLspId() << " ERO " << vectorToString(p->getERO()) << endl;
02203 }
|
|
|
Called by ScenarioManager whenever a script command needs to be carried out by the module. The command is represented by the XML element or element tree. The command name can be obtained as:
const char *command = node->getTagName() Parameters are XML attributes, e.g. a "neighbour" parameter can be retrieved as:
const char *attr = node->getAttribute("neighbour")
More complex input can be passed in child elements.
Implements IScriptable. 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 }
|
|
|
00410 {
00411 IPAddress peer = msg->getPeer();
00412
00413 EV << "hello timeout, considering " << peer << " failed" << endl;
00414
00415 // update hello state (set to failed and turn hello off)
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 // update TED and routing table
00424
00425 unsigned int index = tedmod->linkIndex(routerId, peer);
00426 tedmod->ted[index].state = false;
00427 announceLinkChange(index);
00428 tedmod->rebuildRoutingTable();
00429
00430 // send PATH_ERROR for existing paths
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 }
|
|
|
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 // see comment elsewhere (in TED.cc)
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 }
|
|
|
01369 {
01370 EV << "Received RSVP_HELLO" << endl;
01371 //print(msg);
01372
01373 IPControlInfo *controlInfo = check_and_cast<IPControlInfo*>(msg->controlInfo());
01374 IPAddress sender = controlInfo->srcAddr();
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 // mismatch encountered
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 // if peer was considered down, we have stopped sending hellos: resume now
01434 if (!h->timer->isScheduled())
01435 scheduleAt(simTime(), h->timer);
01436 }
01437
01438 if (request)
01439 {
01440 // immediately respond to a request with an ack
01441 h->ack = true;
01442 h->request = false;
01443
01444 cancelEvent(h->timer);
01445 scheduleAt(simTime(), h->timer);
01446 }
01447 else
01448 {
01449 // next message will be regular
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 }
|
|
|
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 }
|
|
|
01462 {
01463 EV << "Received PATH_ERROR" << endl;
01464 //print(msg);
01465
01466 int lspid = msg->getLspId();
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 }
|
|
|
01572 {
01573 EV << "Received PATH_MESSAGE" << endl;
01574 print(msg);
01575
01576 // process ERO *************************************************************
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 // create PSB if doesn't exist yet *****************************************
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 // schedule timer&timeout **************************************************
01614
01615 scheduleTimeout(psb);
01616
01617 // create RSB if we're egress and doesn't exist yet ************************
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 }
|
|
|
01511 {
01512 EV << "Received PATH_TEAR" << endl;
01513 //print(msg);
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 // ignore message if backup exists and force flag is not set
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 // merging backup exists
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 // forward path teardown downstream
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->interfaceAddrByPeerAddress(psb->ERO[0].node), routerId, msg->getForce());
01562 }
01563
01564 // remove path state block
01565
01566 removePSB(psb);
01567
01568 delete msg;
01569 }
|
|
|
00480 {
00481 PathStateBlock_t *psb = findPsbById(msg->getId());
00482 ASSERT(psb);
00483
00484 if (tedmod->isLocalAddress(psb->OutInterface))
00485 {
00486 ASSERT(psb->OutInterface == tedmod->interfaceAddrByPeerAddress(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 }
|
|
|
00471 {
00472 PathStateBlock_t *psb = findPsbById(msg->getId());
00473 ASSERT(psb);
00474
00475 refreshPath(psb);
00476 scheduleRefreshTimer(psb, PSB_REFRESH_INTERVAL);
00477 }
|
|
|
01637 {
01638 EV << "Received RESV_MESSAGE" << endl;
01639 print(msg);
01640
01641 IPAddress OI = msg->getLIH();
01642
01643 // find matching PSB for every flow ****************************************
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 // remove descriptor from message
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 // find matching RSB *******************************************************
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 // reservation is new, propagate upstream immediately
01691 scheduleRefreshTimer(rsb, 0.0);
01692 }
01693 else
01694 updateRSB(rsb, msg);
01695
01696 scheduleTimeout(rsb);
01697
01698 delete msg;
01699 }
|
|
|
00513 {
00514 ResvStateBlock_t *rsb = findRsbById(msg->getId());
00515 commitResv(rsb);
00516 }
|
|
|
00497 {
00498 ResvStateBlock_t *rsb = findRsbById(msg->getId());
00499 if (rsb->commitTimerMsg->isScheduled())
00500 {
00501 // reschedule after commit
00502 scheduleRefreshTimer(rsb, 0.0);
00503 }
00504 else
00505 {
00506 refreshResv(rsb);
00507
00508 scheduleRefreshTimer(rsb, RSB_REFRESH_INTERVAL);
00509 }
00510 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 // session already exits, add new paths
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 // session not found, create new
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 // make sure path doesn't exist yet
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.moduleByPath(str);
00267 newPath.owner = mod->id();
00268 }
00269 else
00270 {
00271 newPath.owner = id();
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 // schedule path creation
00298
00299 sendPathNotify(id(), 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 }
|
|
|
01702 {
01703 // called when peer's operation is restored
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 // rebuild routing table if link state changed
01711 if (rtmodified)
01712 tedmod->rebuildRoutingTable();
01713
01714 // refresh all paths towards this neighbour
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 }
|
|
|
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->peerByLocalAddress(OI);
00591
00592 ASSERT(ERO.size() == 0 ||ERO[0].node.equals(nextHop) || ERO[0].L);
00593
00594 sendToIP(pm, nextHop);
00595 }
|
|
||||||||||||
|
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 //if (it->LIH != LIH)
00646 // continue;
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 // see comment elsewhere (in TED.cc)
00679 length /= 10;
00680
00681 msg->setByteLength(length);
00682
00683 sendToIP(msg, PHOP);
00684 }
|
|
|
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 < 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; // IR nothing to refresh
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 }
|
|
|
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 // remove reservation state if exists **************************************
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 // proceed with actual removal *********************************************
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 }
|
|
|
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 // deallocate resources
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 }
|
|
||||||||||||
|
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 }
|
|
|
02055 {
02056 ASSERT(rsbEle);
02057
02058 if (rsbEle->commitTimerMsg->isScheduled())
02059 cancelEvent(rsbEle->commitTimerMsg);
02060
02061 scheduleAt(simTime(), rsbEle->commitTimerMsg);
02062 }
|
|
||||||||||||
|
02045 {
02046 ASSERT(rsbEle);
02047
02048 if (rsbEle->refreshTimerMsg->isScheduled())
02049 cancelEvent(rsbEle->refreshTimerMsg);
02050
02051 scheduleAt(simTime() + delay, rsbEle->refreshTimerMsg);
02052 }
|
|
||||||||||||
|
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 }
|
|
|
02035 {
02036 ASSERT(rsbEle);
02037
02038 if (rsbEle->timeoutMsg->isScheduled())
02039 cancelEvent(rsbEle->timeoutMsg);
02040
02041 scheduleAt(simTime() + RSB_TIMEOUT_INTERVAL, rsbEle->timeoutMsg);
02042 }
|
|
|
02007 {
02008 ASSERT(psbEle);
02009
02010 if (psbEle->timeoutMsg->isScheduled())
02011 cancelEvent(psbEle->timeoutMsg);
02012
02013 scheduleAt(simTime() + PSB_TIMEOUT_INTERVAL, psbEle->timeoutMsg);
02014 }
|
|
||||||||||||||||||||||||
|
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 // see comment elsewhere (in TED.cc)
01986 length /= 10;
01987
01988 msg->setByteLength(length);
01989
01990 sendToIP(msg, nextHop);
01991 }
|
|
||||||||||||
|
01970 {
01971 sendPathErrorMessage(psb->Session_Object, psb->Sender_Template_Object, psb->Sender_Tspec_Object, psb->Previous_Hop_Address, errCode);
01972 }
|
|
||||||||||||||||||||||||
|
00388 {
00389 if (handler < 0)
00390 return; // handler not specified
00391
00392 cModule *mod = simulation.module(handler);
00393
00394 if (!mod)
00395 return; // handler no longer exists
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 == id())
00404 scheduleAt(simTime() + delay, msg);
00405 else
00406 sendDirect(msg, delay, mod, "from_rsvp");
00407 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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, "to_ip");
02004 }
|
|
|
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->interfaceByName(token));
00333
00334 IPAddress peer = tedmod->peerByLocalAddress(ift->interfaceByName(token)->ipv4()->inetAddress());
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 // peer is down until we know he is ok
00349
00350 h.ok = false;
00351 }
00352 else
00353 {
00354 // don't use HELLO at all, consider all peers running all the time
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 // sender found
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 // label must be updated in lib table
01000
01001 scheduleCommitTimer(rsb);
01002 }
01003
01004 break;
01005 }
01006 }
01007 if (m == rsb->FlowDescriptor.size())
01008 {
01009 // sender not found
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 // resv is new and must be forwarded
01016
01017 scheduleCommitTimer(rsb);
01018 scheduleRefreshTimer(rsb, 0.0);
01019 }
01020 }
01021 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.4.1