#include <RSVP.h>
Inheritance diagram for RSVP:
typedef std::vector<HelloState_t> RSVP::HelloVector [private] |
typedef std::vector<PathStateBlock_t> RSVP::PSBVector [private] |
typedef std::vector<ResvStateBlock_t> RSVP::RSBVector [private] |
RSVP::~RSVP | ( | ) | [virtual] |
void RSVP::addSession | ( | const cXMLElement & | node | ) | [protected] |
bool RSVP::allocateResource | ( | IPAddress | OI, | |
const SessionObj_t & | session, | |||
double | bandwidth | |||
) | [protected] |
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 }
void RSVP::announceLinkChange | ( | int | tedlinkindex | ) | [protected] |
00758 { 00759 TEDChangeInfo d; 00760 d.setTedLinkIndicesArraySize(1); 00761 d.setTedLinkIndices(0, tedlinkindex); 00762 nb->fireChangeNotification(NF_TED_CHANGED, &d); 00763 }
void RSVP::commitResv | ( | ResvStateBlock_t * | rsb | ) | [protected] |
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 }
RSVP::ResvStateBlock_t * RSVP::createEgressRSB | ( | PathStateBlock_t * | psb | ) | [protected] |
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 }
RSVP::PathStateBlock_t * RSVP::createIngressPSB | ( | const traffic_session_t & | session, | |
const traffic_path_t & | path | |||
) | [protected] |
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 }
void RSVP::createPath | ( | const SessionObj_t & | session, | |
const SenderTemplateObj_t & | sender | |||
) | [protected] |
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 }
RSVP::PathStateBlock_t * RSVP::createPSB | ( | RSVPPathMsg * | msg | ) | [protected] |
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 }
RSVP::ResvStateBlock_t * RSVP::createRSB | ( | RSVPResvMsg * | msg | ) | [protected] |
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 }
void RSVP::delSession | ( | const cXMLElement & | node | ) | [protected] |
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 }
bool RSVP::doCACCheck | ( | const SessionObj_t & | session, | |
const SenderTspecObj_t & | tspec, | |||
IPAddress | OI | |||
) | [protected] |
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 }
bool RSVP::evalNextHopInterface | ( | IPAddress | destAddr, | |
const EroVector & | ERO, | |||
IPAddress & | OI | |||
) | [protected] |
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 }
RSVP::HelloState_t * RSVP::findHello | ( | IPAddress | peer | ) | [protected] |
std::vector< RSVP::traffic_path_t >::iterator RSVP::findPath | ( | traffic_session_t * | session, | |
const SenderTemplateObj_t & | sender | |||
) | [protected] |
RSVP::PathStateBlock_t * RSVP::findPSB | ( | const SessionObj_t & | session, | |
const SenderTemplateObj_t & | sender | |||
) | [protected] |
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 }
RSVP::PathStateBlock_t * RSVP::findPsbById | ( | int | id | ) | [protected] |
RSVP::ResvStateBlock_t * RSVP::findRSB | ( | const SessionObj_t & | session, | |
const SenderTemplateObj_t & | sender, | |||
unsigned int & | index | |||
) | [protected] |
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 }
RSVP::ResvStateBlock_t * RSVP::findRsbById | ( | int | id | ) | [protected] |
std::vector< RSVP::traffic_session_t >::iterator RSVP::findSession | ( | const SessionObj_t & | session | ) | [protected] |
int RSVP::getInLabel | ( | const SessionObj_t & | session, | |
const SenderTemplateObj_t & | sender | |||
) | [private] |
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 }
void RSVP::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
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 }
void RSVP::initialize | ( | int | stage | ) | [protected, virtual] |
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 }
void RSVP::pathProblem | ( | PathStateBlock_t * | psb | ) | [protected] |
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 }
void RSVP::preempt | ( | IPAddress | OI, | |
int | priority, | |||
double | bandwidth | |||
) | [protected] |
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 }
void RSVP::print | ( | RSVPResvMsg * | r | ) | [protected] |
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 }
void RSVP::print | ( | RSVPPathMsg * | p | ) | [protected] |
02201 { 02202 EV << "PATH_MESSAGE: lspid " << p->getLspId() << " ERO " << vectorToString(p->getERO()) << endl; 02203 }
void RSVP::processCommand | ( | const cXMLElement & | node | ) | [protected, virtual] |
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 }
void RSVP::processHELLO_TIMEOUT | ( | HelloTimeoutMsg * | msg | ) | [protected] |
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 }
void RSVP::processHELLO_TIMER | ( | HelloTimerMsg * | msg | ) | [protected] |
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 }
void RSVP::processHelloMsg | ( | RSVPHelloMsg * | msg | ) | [protected] |
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 }
void RSVP::processPATH_NOTIFY | ( | PathNotifyMsg * | msg | ) | [protected] |
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 }
void RSVP::processPathErrMsg | ( | RSVPPathError * | msg | ) | [protected] |
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 }
void RSVP::processPathMsg | ( | RSVPPathMsg * | msg | ) | [protected] |
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 }
void RSVP::processPathTearMsg | ( | RSVPPathTear * | msg | ) | [protected] |
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 }
void RSVP::processPSB_TIMEOUT | ( | PsbTimeoutMsg * | msg | ) | [protected] |
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 }
void RSVP::processPSB_TIMER | ( | PsbTimerMsg * | msg | ) | [protected] |
00471 { 00472 PathStateBlock_t *psb = findPsbById(msg->getId()); 00473 ASSERT(psb); 00474 00475 refreshPath(psb); 00476 scheduleRefreshTimer(psb, PSB_REFRESH_INTERVAL); 00477 }
void RSVP::processResvMsg | ( | RSVPResvMsg * | msg | ) | [protected] |
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 }
void RSVP::processRSB_COMMIT_TIMER | ( | RsbCommitTimerMsg * | msg | ) | [protected] |
void RSVP::processRSB_REFRESH_TIMER | ( | RsbRefreshTimerMsg * | msg | ) | [protected] |
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 }
void RSVP::processRSB_TIMEOUT | ( | RsbTimeoutMsg * | msg | ) | [protected] |
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 }
void RSVP::processRSVPMessage | ( | RSVPMessage * | msg | ) | [protected] |
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 }
void RSVP::processSignallingMessage | ( | SignallingMsg * | msg | ) | [protected] |
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 }
void RSVP::readTrafficFromXML | ( | const cXMLElement * | traffic | ) | [protected] |
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 }
EroVector RSVP::readTrafficRouteFromXML | ( | const cXMLElement * | route | ) | [protected] |
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 }
void RSVP::readTrafficSessionFromXML | ( | const cXMLElement * | session | ) | [protected] |
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 }
void RSVP::recoveryEvent | ( | IPAddress | peer | ) | [protected] |
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 }
void RSVP::refreshPath | ( | PathStateBlock_t * | psbEle | ) | [protected] |
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 }
void RSVP::refreshResv | ( | ResvStateBlock_t * | rsbEle, | |
IPAddress | PHOP | |||
) | [protected] |
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 }
void RSVP::refreshResv | ( | ResvStateBlock_t * | rsbEle | ) | [protected] |
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 }
void RSVP::removePSB | ( | PathStateBlock_t * | psb | ) | [protected] |
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 }
void RSVP::removeRSB | ( | ResvStateBlock_t * | rsb | ) | [protected] |
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 }
void RSVP::removeRsbFilter | ( | ResvStateBlock_t * | rsb, | |
unsigned int | index | |||
) | [protected] |
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 }
void RSVP::scheduleCommitTimer | ( | ResvStateBlock_t * | rsbEle | ) | [protected] |
void RSVP::scheduleRefreshTimer | ( | ResvStateBlock_t * | rsbEle, | |
double | delay | |||
) | [protected] |
void RSVP::scheduleRefreshTimer | ( | PathStateBlock_t * | psbEle, | |
double | delay | |||
) | [protected] |
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 }
void RSVP::scheduleTimeout | ( | ResvStateBlock_t * | rsbEle | ) | [protected] |
02035 { 02036 ASSERT(rsbEle); 02037 02038 if (rsbEle->timeoutMsg->isScheduled()) 02039 cancelEvent(rsbEle->timeoutMsg); 02040 02041 scheduleAt(simTime() + RSB_TIMEOUT_INTERVAL, rsbEle->timeoutMsg); 02042 }
void RSVP::scheduleTimeout | ( | PathStateBlock_t * | psbEle | ) | [protected] |
02007 { 02008 ASSERT(psbEle); 02009 02010 if (psbEle->timeoutMsg->isScheduled()) 02011 cancelEvent(psbEle->timeoutMsg); 02012 02013 scheduleAt(simTime() + PSB_TIMEOUT_INTERVAL, psbEle->timeoutMsg); 02014 }
void RSVP::sendPathErrorMessage | ( | SessionObj_t | session, | |
SenderTemplateObj_t | sender, | |||
SenderTspecObj_t | tspec, | |||
IPAddress | nextHop, | |||
int | errCode | |||
) | [protected] |
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 }
void RSVP::sendPathErrorMessage | ( | PathStateBlock_t * | psb, | |
int | errCode | |||
) | [protected] |
01970 { 01971 sendPathErrorMessage(psb->Session_Object, psb->Sender_Template_Object, psb->Sender_Tspec_Object, psb->Previous_Hop_Address, errCode); 01972 }
void RSVP::sendPathNotify | ( | int | handler, | |
const SessionObj_t & | session, | |||
const SenderTemplateObj_t & | sender, | |||
int | status, | |||
double | delay | |||
) | [protected] |
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 }
void RSVP::sendPathTearMessage | ( | IPAddress | peerIP, | |
const SessionObj_t & | session, | |||
const SenderTemplateObj_t & | sender, | |||
IPAddress | LIH, | |||
IPAddress | NHOP, | |||
bool | force | |||
) | [protected] |
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 }
void RSVP::sendToIP | ( | cMessage * | msg, | |
IPAddress | destAddr | |||
) | [protected] |
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 }
void RSVP::setupHello | ( | ) | [protected] |
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 }
void RSVP::startHello | ( | IPAddress | peer, | |
double | delay | |||
) | [protected] |
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 }
void RSVP::updateRSB | ( | ResvStateBlock_t * | rsb, | |
RSVPResvMsg * | msg | |||
) | [protected] |
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 }
friend class SimpleClassifier [friend] |
double RSVP::helloInterval [private] |
HelloVector RSVP::HelloList [private] |
double RSVP::helloTimeout [private] |
InterfaceTable* RSVP::ift [private] |
int RSVP::maxPsbId [private] |
int RSVP::maxRsbId [private] |
int RSVP::maxSrcInstance [private] |
NotificationBoard* RSVP::nb [private] |
PSBVector RSVP::PSBList [private] |
double RSVP::retryInterval [private] |
IPAddress RSVP::routerId [private] |
IRSVPClassifier* RSVP::rpct [private] |
RSBVector RSVP::RSBList [private] |
RoutingTable* RSVP::rt [private] |
TED* RSVP::tedmod [private] |
std::vector<traffic_session_t> RSVP::traffic [private] |