00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "packet.h"
00054 #include "trace.h"
00055 #include "classifier-addr-mpls.h"
00056
00057 int hdr_mpls::offset_;
00058
00059 static class shimhdreaderClass : public PacketHeaderClass {
00060 public:
00061 shimhdreaderClass() : PacketHeaderClass("PacketHeader/MPLS",
00062 sizeof(hdr_mpls)) {
00063 bind_offset(&hdr_mpls::offset_);
00064 }
00065 } class_shimhdreader;
00066
00067 static class MPLSAddrClassifierClass : public TclClass {
00068 public:
00069 MPLSAddrClassifierClass() : TclClass("Classifier/Addr/MPLS") {}
00070 virtual TclObject* create(int, const char*const*) {
00071 return (new MPLSAddressClassifier());
00072 }
00073 virtual void bind();
00074 virtual int method(int argc, const char*const* argv);
00075 } class_mpls_addr_classifier;
00076
00077 void MPLSAddrClassifierClass::bind()
00078 {
00079 TclClass::bind();
00080 add_method("minimum-lspid");
00081 add_method("dont-care");
00082 add_method("ordered-control?");
00083 add_method("on-demand?");
00084 add_method("enable-ordered-control");
00085 add_method("enable-on-demand");
00086 }
00087
00088 int MPLSAddrClassifierClass::method(int ac, const char*const* av)
00089 {
00090 Tcl& tcl = Tcl::instance();
00091 int argc = ac - 2;
00092 const char*const* argv = av + 2;
00093
00094 if (argc == 2) {
00095 if (strcmp(argv[1], "minimum-lspid") == 0) {
00096 tcl.resultf("%d", MPLS_MINIMUM_LSPID);
00097 return (TCL_OK);
00098 } else if (strcmp(argv[1], "dont-care") == 0) {
00099 tcl.resultf("%d", MPLS_DONTCARE);
00100 return (TCL_OK);
00101 } if (strcmp(argv[1], "ordered-control?") == 0) {
00102 tcl.resultf("%d",
00103 MPLSAddressClassifier::ordered_control_);
00104 return (TCL_OK);
00105 } else if (strcmp(argv[1], "on-demand?") == 0) {
00106 tcl.resultf("%d", MPLSAddressClassifier::on_demand_);
00107 return (TCL_OK);
00108 } else if (strcmp(argv[1], "enable-ordered-control") == 0) {
00109 MPLSAddressClassifier::ordered_control_ = 1;
00110 return (TCL_OK);
00111 } else if (strcmp(argv[1], "enable-on-demand") == 0) {
00112 MPLSAddressClassifier::on_demand_ = 1;
00113 return (TCL_OK);
00114 }
00115 }
00116 return TclClass::method(ac, av);
00117 }
00118
00119 int MPLSAddressClassifier::on_demand_ = 0;
00120 int MPLSAddressClassifier::ordered_control_ = 0;
00121
00122 MPLSAddressClassifier::MPLSAddressClassifier() :
00123 data_driven_(0), control_driven_(0)
00124 {
00125 PFT_.NB_ = 0;
00126 ERB_.NB_ = 0;
00127 LIB_.NB_ = 0;
00128 ttl_ = 32;
00129 }
00130
00131 void MPLSAddressClassifier::delay_bind_init_all()
00132 {
00133 delay_bind_init_one("ttl_");
00134 delay_bind_init_one("trace_mpls_");
00135 delay_bind_init_one("label_");
00136 delay_bind_init_one("enable_reroute_");
00137 delay_bind_init_one("reroute_option_");
00138 delay_bind_init_one("data_driven_");
00139 delay_bind_init_one("control_driven_");
00140 AddressClassifier::delay_bind_init_all();
00141 }
00142
00143
00144 int MPLSAddressClassifier::delay_bind_dispatch(const char *vn,
00145 const char* ln, TclObject *t)
00146 {
00147 if (delay_bind(vn, ln, "ttl_", &ttl_, t))
00148 return TCL_OK;
00149 if (delay_bind(vn, ln, "trace_mpls_", &trace_mpls_, t))
00150 return TCL_OK;
00151 if (delay_bind(vn, ln, "label_", &label_, t))
00152 return TCL_OK;
00153 if (delay_bind(vn, ln, "enable_reroute_", &enable_reroute_, t))
00154 return TCL_OK;
00155 if (delay_bind(vn, ln, "reroute_option_", &reroute_option_, t))
00156 return TCL_OK;
00157 if (delay_bind(vn, ln, "data_driven_", &data_driven_, t))
00158 return TCL_OK;
00159 if (delay_bind(vn, ln, "control_driven_", &control_driven_, t))
00160 return TCL_OK;
00161 return AddressClassifier::delay_bind_dispatch(vn, ln, t);
00162 }
00163
00164 int MPLSAddressClassifier::classify(Packet* p)
00165 {
00166 int nexthop = MPLSclassify(p);
00167
00168 if ((enable_reroute_ == 1) && (size_ > 0) &&
00169 (is_link_down(nexthop)))
00170
00171 nexthop = do_reroute(p);
00172 if (nexthop == MPLS_GOTO_L3)
00173 return AddressClassifier::classify(p);
00174
00175
00176 return (nexthop == -1) ? Classifier::ONCE : nexthop;
00177 }
00178
00179 int MPLSAddressClassifier::is_link_down(int node)
00180 {
00181 Tcl& tcl = Tcl::instance();
00182 tcl.evalf("[%s set mpls_mod_] get-link-status %d", name(), node);
00183 return (strcmp(tcl.result(), "down") == 0) ? 1 : 0;
00184 }
00185
00186 int MPLSAddressClassifier::do_reroute(Packet* p)
00187 {
00188 int oIface, oLabel, LIBptr;
00189 PI_.shimhdr_ = GetShimHeader(p);
00190 int iLabel = PI_.shimhdr_->label_;
00191
00192 if (aPathLookup(PI_.dst_.addr_, PI_.phb_, oIface, oLabel, LIBptr) == 0)
00193 return convertL2toL2(iLabel, oIface, oLabel, LIBptr);
00194 else {
00195 PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);
00196 trace("L", size_, iLabel, "Drop(linkFail)", -1, -1, -1);
00197 switch (reroute_option_) {
00198 case MPLS_DROPPACKET:
00199 return -1;
00200 case MPLS_L3FORWARDING:
00201 return MPLS_GOTO_L3;
00202 case MPLS_MAKENEWLSP:
00203 Tcl& tcl = Tcl::instance();
00204 if (!control_driven_)
00205 tcl.evalf("%s ldp-trigger-by-switch %d",
00206 name(), PI_.dst_.addr_);
00207 return -1;
00208 }
00209 return -1;
00210 }
00211 }
00212
00213 int MPLSAddressClassifier::convertL3toL2(int oIface, int oLabel, int LIBptr)
00214 {
00215 int iLabel= -1;
00216 int ptr;
00217
00218 while (oLabel >= 0) {
00219
00220 if (oLabel == 0) {
00221
00222 trace("U",size_, iLabel, "Push(penultimate)",
00223 oIface, oLabel, ttl_);
00224 } else {
00225
00226 PI_.shimhdr_ = push(PI_.shimhdr_,oLabel);
00227 trace("U",size_, iLabel, "Push(ingress)",
00228 oIface, oLabel, ttl_);
00229 }
00230 if (LIBptr >= 0) {
00231
00232 iLabel = oLabel;
00233 ptr = LIBptr;
00234 LIBlookup(ptr, oIface, oLabel, LIBptr);
00235 } else
00236 break;
00237 }
00238
00239 if (oLabel < 0) {
00240 if (size_ > 0)
00241 PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);
00242 trace("U",size_, iLabel , "L3(errorLabel)", -1,-1, -1);
00243 return MPLS_GOTO_L3;
00244 }
00245 if (oIface < 0) {
00246 PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);
00247 trace("U", size_, iLabel, "L3(errorOIF)", -1 , -1, -1);
00248 return MPLS_GOTO_L3;
00249 } else
00250
00251 return oIface;
00252 }
00253
00254 int MPLSAddressClassifier::convertL2toL2(int iLabel, int oIface,
00255 int oLabel, int LIBptr)
00256 {
00257 int ttl = PI_.shimhdr_->ttl_;
00258 int ptr;
00259
00260
00261 if (oLabel == 0) {
00262
00263 PI_.shimhdr_ = pop(PI_.shimhdr_);
00264 trace("L", size_, iLabel, "Pop(penultimate)",
00265 oIface, oLabel, ttl);
00266 } else if (oLabel > 0) {
00267
00268 swap(PI_.shimhdr_,oLabel);
00269 trace("L", size_, iLabel, "Swap", oIface, oLabel, ttl);
00270 } else {
00271
00272 PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);
00273 trace("L", size_, iLabel, "L3(errorLabel)", -1, -1, -1);
00274 return MPLS_GOTO_L3;
00275 }
00276 while (LIBptr >= 0) {
00277
00278 iLabel= oLabel;
00279 ptr = LIBptr;
00280 LIBlookup(ptr, oIface, oLabel, LIBptr);
00281 PI_.shimhdr_ = push(PI_.shimhdr_,oLabel);
00282 trace("L", size_, iLabel, "Push(tunnel)",
00283 oIface, oLabel, ttl_);
00284 }
00285 if (oIface < 0) {
00286 if (size_ > 0)
00287 PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);
00288 trace("L",size_, iLabel , "L3(errorOIf)", -1 , -1, -1);
00289 return MPLS_GOTO_L3;
00290 }
00291
00292 return oIface;
00293 }
00294
00295
00296 int MPLSAddressClassifier::processIP()
00297 {
00298 int oIface,oLabel,LIBptr;
00299 int iLabel = -1;
00300
00301
00302 if (PFTlookup(PI_.dst_.addr_, PI_.phb_, oIface, oLabel, LIBptr) == 0)
00303
00304 return convertL3toL2(oIface,oLabel,LIBptr);
00305
00306
00307
00308 if (data_driven_)
00309 Tcl::instance().evalf("%s ldp-trigger-by-switch %d",
00310 name(), PI_.dst_.addr_);
00311 trace("U", size_, iLabel, "L3", -1, -1, -1);
00312 return MPLS_GOTO_L3;
00313 }
00314
00315
00316 int MPLSAddressClassifier::processLabelP()
00317 {
00318 int oIface,oLabel,LIBptr;
00319 int iLabel = PI_.shimhdr_->label_;
00320
00321 PI_.shimhdr_ = checkTTL(PI_.shimhdr_);
00322
00323 if (size_ == 0)
00324
00325 return MPLS_GOTO_L3;
00326
00327
00328 if (LIBlookup(-1, iLabel, oIface, oLabel, LIBptr) == 0)
00329 return convertL2toL2(iLabel,oIface,oLabel,LIBptr);
00330
00331 PI_.shimhdr_ = DelAllShimHeader(PI_.shimhdr_);
00332 trace("L",size_, iLabel,"L3(errorLabel)", -1, -1, -1);
00333 return ( MPLS_GOTO_L3 );
00334 }
00335
00336 int MPLSAddressClassifier::MPLSclassify(Packet* p)
00337 {
00338 GetIPInfo(p, PI_.dst_, PI_.phb_, PI_.srcnode_);
00339 PI_.shimhdr_ = GetShimHeader(p);
00340
00341
00342
00343
00344
00345 if (size_ == 0)
00346
00347 return processIP();
00348
00349
00350 int ret = processLabelP();
00351 if (ret == MPLS_GOTO_L3) {
00352 PI_.shimhdr_ = GetShimHeader(p);
00353 return processIP();
00354 }
00355 return ret;
00356 }
00357
00358 hdr_mpls *MPLSAddressClassifier::checkTTL(hdr_mpls *shimhdr)
00359 {
00360 shimhdr->ttl_--;
00361 int ttl = shimhdr->ttl_;
00362 int iLabel= shimhdr->label_;
00363
00364 if (ttl == 0) {
00365 shimhdr = DelAllShimHeader(shimhdr);
00366 trace("L", size_, iLabel, "L3(TTL=0)", -1, -1, ttl);
00367 }
00368 return shimhdr;
00369 }
00370
00371 void MPLSAddressClassifier::GetIPInfo(Packet* p, ns_addr_t &dst,
00372 int &phb, int &srcnode)
00373 {
00374 hdr_ip* iphdr = hdr_ip::access(p);
00375 dst = iphdr->dst_;
00376 srcnode = iphdr->src_.addr_;
00377 phb = MPLS_DEFAULT_PHB;
00378 }
00379
00380 hdr_mpls *MPLSAddressClassifier::GetShimHeader(Packet* p)
00381 {
00382 hdr_mpls *shimhdr = hdr_mpls::access(p);
00383 size_ = 0;
00384 if ((shimhdr->label_ == 0) && (shimhdr->bflag_ == 0) &&
00385 (shimhdr->ttl_ == 0)) {
00386 shimhdr->bflag_ = -1;
00387 shimhdr->label_ = -1;
00388 shimhdr->ttl_ = -1;
00389 shimhdr->top_ = shimhdr;
00390 shimhdr->nexthdr_= shimhdr;
00391 } else {
00392 while (shimhdr->top_ != shimhdr) {
00393 shimhdr = shimhdr->top_;
00394 size_ += 4;
00395 }
00396 }
00397 return shimhdr;
00398 }
00399
00400 hdr_mpls *MPLSAddressClassifier::DelAllShimHeader(hdr_mpls *shimhdr)
00401 {
00402 while (shimhdr->bflag_ != -1)
00403 shimhdr = pop(shimhdr);
00404 return(shimhdr);
00405 }
00406
00407 hdr_mpls *MPLSAddressClassifier::push(hdr_mpls *shimhdr, int oLabel)
00408 {
00409 hdr_mpls *newhdr;
00410
00411 newhdr = (hdr_mpls *) malloc( sizeof(hdr_mpls) );
00412 newhdr->label_ = oLabel;
00413 newhdr->bflag_ = 1;
00414 newhdr->ttl_ = ttl_;
00415 newhdr->top_ = newhdr;
00416 newhdr->nexthdr_ = shimhdr;
00417
00418 shimhdr->top_ = newhdr;
00419 size_ += 4;
00420
00421 return newhdr;
00422 }
00423
00424 hdr_mpls *MPLSAddressClassifier::pop(hdr_mpls *shimhdr)
00425 {
00426 shimhdr = shimhdr->nexthdr_;
00427 free(shimhdr->top_);
00428 shimhdr->top_ = shimhdr;
00429 size_ -= 4;
00430 return shimhdr;
00431 }
00432
00433 void MPLSAddressClassifier::install(int slot, NsObject *target) {
00434 Tcl& tcl = Tcl::instance();
00435 if ((slot >= 0) && (slot < nslot_) &&
00436 (slot_[slot] != NULL)) {
00437 if (strcmp(slot_[slot]->name(), target->name()) != 0)
00438 tcl.evalf("%s routing-update %d %.15g",
00439 name(), slot,
00440 Scheduler::instance().clock());
00441 else
00442 tcl.evalf("%s routing-nochange %d %.15g",
00443 name(), slot,
00444 Scheduler::instance().clock());
00445 } else
00446 tcl.evalf("%s routing-new %d %.15g",
00447 name(), slot,
00448 Scheduler::instance().clock());
00449 Classifier::install(slot,target);
00450 }
00451
00452 int MPLSAddressClassifier::command(int argc, const char*const* argv)
00453 {
00454 Tcl& tcl = Tcl::instance();
00455 if (argc == 2) {
00456 if (strcmp(argv[1], "control-driven?") == 0) {
00457 tcl.resultf("%d", control_driven_);
00458 return (TCL_OK);
00459 } else if (strcmp(argv[1], "data-driven?") == 0) {
00460 tcl.resultf("%d", data_driven_);
00461 return (TCL_OK);
00462 } else if (strcmp(argv[1], "enable-control-driven") == 0) {
00463
00464
00465 control_driven_ = 1;
00466 data_driven_ = 0;
00467 return (TCL_OK);
00468 } else if (strcmp(argv[1], "enable-data-driven") == 0) {
00469 control_driven_ = 0;
00470 data_driven_ = 1;
00471 return (TCL_OK);
00472 }
00473 } else if (argc == 3) {
00474 if (strcmp(argv[1], "PFTdump") == 0) {
00475
00476 PFTdump(argv[2]);
00477 return (TCL_OK);
00478 } else if (strcmp(argv[1], "ERBdump") == 0) {
00479 ERBdump(argv[2]);
00480 return (TCL_OK);
00481 } else if (strcmp(argv[1], "LIBdump") == 0) {
00482 LIBdump(argv[2]);
00483 return (TCL_OK);
00484 } else if (strcmp(argv[1], "get-fec-for-lspid") == 0) {
00485
00486 int LSPid = atoi(argv[2]);
00487 int LIBptr = -1;
00488 int ERBnb;
00489 ERBnb = ERBlocate(LSPid, -1, LIBptr);
00490 if (ERBnb >= 0)
00491 tcl.resultf("%d", ERB_.Entry_[ERBnb].FEC_);
00492 else
00493 tcl.result("-1");
00494 return (TCL_OK);
00495 }
00496 } else if (argc == 4) {
00497 if (strcmp(argv[1], "exist-fec") == 0) {
00498
00499 int LIBptr;
00500 int PFTnb = PFTlocate(atoi(argv[2]), atoi(argv[3]),
00501 LIBptr);
00502 if (PFTnb > -1)
00503 tcl.result("1");
00504 else
00505 tcl.result("-1");
00506 return (TCL_OK);
00507 }
00508 int PFTnb = -1;
00509 int LIBptr = -1;
00510 int iLabel, oLabel, iIface, oIface;
00511 int fec = atoi(argv[2]);
00512 int LSPid = atoi(argv[3]);
00513 int PHB = LSPid;
00514 if (LSPid < 0)
00515 PFTnb = PFTlocate(fec,PHB, LIBptr);
00516 else
00517 ERBlocate(LSPid,fec, LIBptr);
00518
00519 if (strcmp(argv[1], "GetInIface") == 0) {
00520
00521 if (LIBptr > -1) {
00522 LIBgetIncoming(LIBptr,iIface,iLabel);
00523 tcl.resultf("%d", iIface);
00524 } else
00525 tcl.result("-1");
00526 return (TCL_OK);
00527 } else if (strcmp(argv[1], "GetInLabel") == 0) {
00528
00529 if (LIBptr > -1) {
00530 LIBgetIncoming(LIBptr,iIface,iLabel);
00531 tcl.resultf("%d", iLabel);
00532 } else
00533 tcl.result("-1");
00534 return (TCL_OK);
00535 } else if (strcmp(argv[1], "GetOutIface") == 0) {
00536
00537 if (LIBptr > -1) {
00538 LIBlookup(LIBptr, oIface, oLabel, LIBptr);
00539 tcl.resultf("%d", oIface);
00540 } else
00541 tcl.result("-1");
00542 return (TCL_OK);
00543 } else if (strcmp(argv[1], "GetOutLabel") == 0) {
00544
00545 if (LIBptr > -1) {
00546 LIBlookup(LIBptr, oIface, oLabel, LIBptr);
00547 tcl.resultf("%d", oLabel);
00548 } else
00549 tcl.result("-1");
00550 return (TCL_OK);
00551 } else if (strcmp(argv[1], "install") == 0) {
00552 int slot = atoi(argv[2]);
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 NsObject* target = (NsObject*)TclObject::lookup(argv[3]);
00573
00574
00575 install(slot,target);
00576 return (TCL_OK);
00577 }
00578 } else if (argc == 5) {
00579 if (strcmp(argv[1], "ErLspBinding") == 0) {
00580
00581 int addr = atoi(argv[2]);
00582 int PHB = atoi(argv[3]);
00583 int LSPid = atoi(argv[4]);
00584 if ( !ErLspBinding(addr, PHB,-1, LSPid) )
00585 tcl.result("1");
00586 else
00587 tcl.result("-1");
00588 return (TCL_OK);
00589 }
00590 } else if (argc == 6) {
00591
00592 if (strcmp(argv[1], "ErLspStacking") == 0) {
00593 int erfec0 = atoi(argv[2]);
00594 int erlspid0 = atoi(argv[3]);
00595 int erfec = atoi(argv[4]);
00596 int erlspid = atoi(argv[5]);
00597 if (ErLspStacking(erfec0,erlspid0,erfec,erlspid) == 0)
00598 tcl.result("1");
00599 else
00600 tcl.result("-1");
00601 return (TCL_OK);
00602 } else if (strcmp(argv[1], "FlowAggregation") == 0) {
00603
00604
00605 int fineaddr = atoi(argv[2]);
00606 int finePHB = atoi(argv[3]);
00607 int coarseaddr = atoi(argv[4]);
00608 int coarsePHB = atoi(argv[5]);
00609 if (FlowAggregation(fineaddr, finePHB, coarseaddr,
00610 coarsePHB) == 0)
00611 tcl.result("1");
00612 else
00613 tcl.result("-1");
00614 return (TCL_OK);
00615 } else if (strcmp(argv[1], "aPathBinding") == 0) {
00616
00617
00618 int FEC = atoi(argv[2]);
00619 int PHB = atoi(argv[3]);
00620 int erFEC = atoi(argv[4]);
00621 int LSPid = atoi(argv[5]);
00622 if (aPathBinding(FEC, PHB, erFEC, LSPid) == 0)
00623 tcl.result("1");
00624 else
00625 tcl.result("-1");
00626 return (TCL_OK);
00627 }
00628 } else if (argc == 8) {
00629 int addr = atoi(argv[2]);
00630 int LSPid = atoi(argv[3]);
00631 int PHB = LSPid;
00632 int LIBptr, PFTnb,ERBnb ;
00633 if (LSPid == MPLS_DEFAULT_PHB)
00634 PFTnb = PFTlocate(addr,PHB,LIBptr);
00635 else
00636 ERBnb = ERBlocate(LSPid,addr,LIBptr);
00637
00638 if (strcmp(argv[1], "LSPrelease") == 0) {
00639
00640
00641 if (LSPid < 0) {
00642
00643 if (PFTnb >= 0) {
00644
00645 LIBupdate(LIBptr, atoi(argv[4]),
00646 atoi(argv[5]), atoi(argv[6]),
00647 atoi(argv[7]));
00648 if (LIBisdeleted(LIBptr) == 0)
00649 PFTdeleteLIBptr(LIBptr);
00650 }
00651 } else {
00652
00653 if ( ERBnb >= 0 ) {
00654
00655 LIBupdate(LIBptr, atoi(argv[4]),
00656 atoi(argv[5]), atoi(argv[6]),
00657 atoi(argv[7]));
00658 if (LIBisdeleted(LIBptr) == 0) {
00659 ERBdelete(ERBnb);
00660 PFTdeleteLIBptr(LIBptr);
00661 }
00662 }
00663 }
00664 return (TCL_OK);
00665 } else if (strcmp(argv[1], "LSPsetup") == 0) {
00666
00667
00668 if (LSPid == MPLS_DEFAULT_PHB) {
00669
00670 if (PFTnb < 0) {
00671
00672 int ptr = LIBinsert(atoi(argv[4]),
00673 atoi(argv[5]),
00674 atoi(argv[6]),
00675 atoi(argv[7]));
00676 if (ptr > -1) {
00677 PFTinsert(addr,
00678 MPLS_DEFAULT_PHB,
00679 ptr);
00680 return (TCL_OK);
00681 } else
00682 return (TCL_ERROR);
00683 }
00684
00685
00686 if (LIBptr <= -1) {
00687 int ptr = LIBinsert(atoi(argv[4]),
00688 atoi(argv[5]),
00689 atoi(argv[6]),
00690 atoi(argv[7]));
00691 if (ptr > -1) {
00692 PFTupdate(PFTnb, ptr);
00693 return (TCL_OK);
00694 } else
00695 return (TCL_ERROR);
00696 }
00697
00698
00699 if (!((enable_reroute_ == 1) &&
00700 (LIB_.Entry_[LIBptr].oIface_ > -1) &&
00701 (reroute_option_ == MPLS_MAKENEWLSP) &&
00702 (atoi(argv[6]) > -1) &&
00703 (is_link_down(LIB_.Entry_[LIBptr].oIface_))
00704 )) {
00705 LIBupdate(LIBptr, atoi(argv[4]),
00706 atoi(argv[5]), atoi(argv[6]),
00707 atoi(argv[7]));
00708 return (TCL_OK);
00709 }
00710 PFT_.Entry_[PFTnb].aPATHptr_ =
00711 LIBinsert(atoi(argv[4]), atoi(argv[5]),
00712 atoi(argv[6]),atoi(argv[7]));
00713 for (int i=0; i < LIB_.NB_; i++) {
00714 if (LIB_.Entry_[i].oIface_!=atoi(argv[2]))
00715 continue;
00716 for (int k=0; k<PFT_.NB_; k++) {
00717 if (PFT_.Entry_[k].LIBptr_ != i)
00718 continue;
00719 PFT_.Entry_[k].aPATHptr_ =
00720 PFT_.Entry_[PFTnb].aPATHptr_;
00721 }
00722 }
00723 return (TCL_OK);
00724 }
00725
00726
00727 if (ERBnb < 0) {
00728
00729 int ptr = LIBinsert(atoi(argv[4]),
00730 atoi(argv[5]),
00731 atoi(argv[6]),
00732 atoi(argv[7]));
00733 if (ptr > -1) {
00734 ERBinsert(LSPid,addr,ptr);
00735 return (TCL_OK);
00736 } else
00737 return (TCL_ERROR);
00738 }
00739
00740
00741 if (LIBptr > -1)
00742 LIBupdate(LIBptr, atoi(argv[4]), atoi(argv[5]),
00743 atoi(argv[6]), atoi(argv[7]));
00744 else {
00745 int ptr =
00746 LIBinsert(atoi(argv[4]),atoi(argv[5]),
00747 atoi(argv[6]),atoi(argv[7]));
00748 if (ptr > -1)
00749 ERBupdate(ERBnb, ptr);
00750 else
00751 return (TCL_ERROR);
00752 }
00753 return (TCL_OK);
00754 }
00755 }
00756
00757 return (AddressClassifier::command(argc, argv));
00758 }
00759
00760
00761
00762
00763
00764 void MPLSAddressClassifier::PFTinsert(int FEC, int PHB, int LIBptr)
00765 {
00766 PFT_.Entry_[PFT_.NB_].FEC_ = FEC;
00767 PFT_.Entry_[PFT_.NB_].PHB_ = PHB;
00768 PFT_.Entry_[PFT_.NB_].LIBptr_ = LIBptr;
00769 PFT_.Entry_[PFT_.NB_].aPATHptr_ = -1;
00770 PFT_.NB_++;
00771 }
00772
00773 void MPLSAddressClassifier::PFTdelete(int entrynb)
00774 {
00775 PFT_.Entry_[entrynb].FEC_ = -1;
00776 PFT_.Entry_[entrynb].PHB_ = -1;
00777 PFT_.Entry_[entrynb].LIBptr_ = -1;
00778 }
00779
00780 void MPLSAddressClassifier::PFTdeleteLIBptr(int LIBptr)
00781 {
00782 for (int i = 0; i < PFT_.NB_; i++) {
00783 if (PFT_.Entry_[i].LIBptr_ != LIBptr)
00784 continue;
00785 PFT_.Entry_[i].FEC_ = -1;
00786 PFT_.Entry_[i].PHB_ = -1;
00787 PFT_.Entry_[i].LIBptr_ = -1;
00788 }
00789 }
00790
00791 void MPLSAddressClassifier::PFTupdate(int entrynb, int LIBptr)
00792 {
00793 PFT_.Entry_[entrynb].LIBptr_ = LIBptr;
00794 }
00795
00796 int MPLSAddressClassifier::PFTlocate(int FEC, int PHB, int &LIBptr)
00797 {
00798 LIBptr = -1;
00799 if (FEC < 0)
00800 return -1;
00801 for (int i = 0; i < PFT_.NB_; i++)
00802 if ((PFT_.Entry_[i].FEC_ == FEC) && (PFT_.Entry_[i].PHB_ == PHB)) {
00803 LIBptr = PFT_.Entry_[i].LIBptr_;
00804 return i;
00805 }
00806 return -1;
00807 }
00808
00809 int MPLSAddressClassifier::PFTlookup(int FEC, int PHB, int &oIface,
00810 int &oLabel, int &LIBptr)
00811 {
00812 oIface = oLabel = LIBptr = -1;
00813 if (FEC < 0)
00814 return -1;
00815 for (int i = 0; i < PFT_.NB_; i++)
00816 if ((PFT_.Entry_[i].FEC_ == FEC) && (PFT_.Entry_[i].PHB_ == PHB))
00817 return LIBlookup(PFT_.Entry_[i].LIBptr_,
00818 oIface, oLabel, LIBptr);
00819 return -1;
00820 }
00821
00822 void MPLSAddressClassifier::PFTdump(const char *id)
00823 {
00824 fflush(stdout);
00825 printf(" --) ___PFT dump___ [node: %s] (--\n", id);
00826 printf("---------------------------------------------\n");
00827 printf(" FEC PHB LIBptr AltanativePath\n");
00828 for (int i = 0; i < PFT_.NB_; i++) {
00829 if (PFT_.Entry_[i].FEC_ == -1)
00830 continue;
00831 printf(" %d ", PFT_.Entry_[i].FEC_);
00832 printf(" %d ", PFT_.Entry_[i].PHB_);
00833 printf(" %d ", PFT_.Entry_[i].LIBptr_);
00834 printf(" %d\n", PFT_.Entry_[i].aPATHptr_);
00835 }
00836 printf("\n");
00837 }
00838
00839
00840
00841
00842
00843 void MPLSAddressClassifier::ERBinsert(int LSPid, int FEC, int LIBptr)
00844 {
00845 ERB_.Entry_[ERB_.NB_].LSPid_ = LSPid;
00846 ERB_.Entry_[ERB_.NB_].FEC_ = FEC;
00847 ERB_.Entry_[ERB_.NB_].LIBptr_ = LIBptr;
00848 ERB_.NB_++;
00849 }
00850
00851 void MPLSAddressClassifier::ERBdelete(int entrynb)
00852 {
00853 ERB_.Entry_[entrynb].FEC_ = -1;
00854 ERB_.Entry_[entrynb].LSPid_ = -1;
00855 ERB_.Entry_[entrynb].LIBptr_ = -1;
00856 }
00857
00858 void MPLSAddressClassifier::ERBupdate(int entrynb, int LIBptr)
00859 {
00860 ERB_.Entry_[entrynb].LIBptr_ = LIBptr;
00861 }
00862
00863 int MPLSAddressClassifier::ERBlocate(int LSPid, int FEC, int &LIBptr)
00864 {
00865 LIBptr = -1;
00866 for (int i = 0; i < ERB_.NB_; i++)
00867 if (ERB_.Entry_[i].LSPid_ == LSPid) {
00868 LIBptr = ERB_.Entry_[i].LIBptr_;
00869 return(i);
00870 }
00871 return -1;
00872 }
00873
00874 void MPLSAddressClassifier::ERBdump(const char *id)
00875 {
00876 fflush(stdout);
00877 printf(" --) ___ERB dump___ [node: %s] (--\n", id);
00878 printf("---------------------------------------------\n");
00879 printf(" FEC LSPid LIBptr\n");
00880 for (int i = 0; i < ERB_.NB_; i++) {
00881 if (ERB_.Entry_[i].FEC_ == -1)
00882 continue;
00883 printf(" %d ", ERB_.Entry_[i].FEC_);
00884 printf(" %d ", ERB_.Entry_[i].LSPid_);
00885 printf(" %d\n", ERB_.Entry_[i].LIBptr_);
00886 }
00887 printf("\n");
00888 }
00889
00890
00891
00892
00893 int MPLSAddressClassifier::LIBinsert(int iIface, int iLabel,
00894 int oIface, int oLabel)
00895 {
00896 if (LIB_.NB_ == MPLS_MaxLIBEntryNB - 1) {
00897 fprintf(stderr,
00898 "Error in LIBinstall: higher than MaxLIBEntryNB\n");
00899 return -1;
00900 }
00901
00902 LIB_.Entry_[LIB_.NB_].iIface_ = -1;
00903 LIB_.Entry_[LIB_.NB_].iLabel_ = -1;
00904 LIB_.Entry_[LIB_.NB_].oIface_ = -1;
00905 LIB_.Entry_[LIB_.NB_].oLabel_ = -1;
00906
00907 if (iIface < 0) iIface = -1;
00908 if (iLabel < 0) iLabel = -1;
00909 if (oIface < 0) oIface = -1;
00910 if (oLabel < 0) oLabel = -1;
00911
00912 LIB_.Entry_[LIB_.NB_].iIface_ = iIface;
00913 LIB_.Entry_[LIB_.NB_].iLabel_ = iLabel;
00914 LIB_.Entry_[LIB_.NB_].oIface_ = oIface;
00915 LIB_.Entry_[LIB_.NB_].oLabel_ = oLabel;
00916 LIB_.Entry_[LIB_.NB_].LIBptr_ = -1;
00917
00918 LIB_.NB_++;
00919 return(LIB_.NB_-1);
00920 }
00921
00922 int MPLSAddressClassifier::LIBisdeleted(int entrynb)
00923 {
00924 if ((LIB_.Entry_[entrynb].iIface_ == -1) &&
00925 (LIB_.Entry_[entrynb].iLabel_ == -1) &&
00926 (LIB_.Entry_[entrynb].oIface_ == -1) &&
00927 (LIB_.Entry_[entrynb].oLabel_ == -1)) {
00928
00929 LIB_.Entry_[entrynb].LIBptr_ = -1;
00930
00931 for (int i = 0; i < LIB_.NB_; i++)
00932 if ((LIB_.Entry_[i].LIBptr_ == entrynb))
00933 LIB_.Entry_[i].LIBptr_ = -1;
00934 return 0;
00935 }
00936 return -1;
00937 }
00938
00939 void MPLSAddressClassifier::LIBupdate(int entrynb, int iIface, int iLabel,
00940 int oIface, int oLabel)
00941 {
00942 if (iIface != MPLS_DONTCARE)
00943 LIB_.Entry_[entrynb].iIface_ = iIface;
00944 if (iLabel != MPLS_DONTCARE)
00945 LIB_.Entry_[entrynb].iLabel_ = iLabel;
00946 if (oIface != MPLS_DONTCARE)
00947 LIB_.Entry_[entrynb].oIface_ = oIface;
00948 if (oLabel != MPLS_DONTCARE)
00949 LIB_.Entry_[entrynb].oLabel_ = oLabel;
00950 }
00951
00952 int MPLSAddressClassifier::LIBlookup(int entrynb, int &oIface,
00953 int &oLabel, int &LIBptr)
00954 {
00955 oIface = oLabel = LIBptr = -1;
00956
00957 if (entrynb < 0)
00958 return -1;
00959 oIface = LIB_.Entry_[entrynb].oIface_;
00960 oLabel = LIB_.Entry_[entrynb].oLabel_;
00961 LIBptr = LIB_.Entry_[entrynb].LIBptr_;
00962 return 0;
00963 }
00964
00965 int MPLSAddressClassifier::LIBlookup(int iIface, int iLabel, int &oIface,
00966 int &oLabel, int &LIBptr)
00967 {
00968 oIface = oLabel = LIBptr = -1;
00969 if (iLabel < 0)
00970 return -1;
00971 for (int i = 0; i < LIB_.NB_; i++)
00972 if ((LIB_.Entry_[i].iLabel_ == iLabel)) {
00973 oIface = LIB_.Entry_[i].oIface_;
00974 oLabel = LIB_.Entry_[i].oLabel_;
00975 LIBptr = LIB_.Entry_[i].LIBptr_;
00976 return 0;
00977 }
00978 return -1;
00979 }
00980
00981 int MPLSAddressClassifier::LIBgetIncoming(int entrynb, int &iIface,
00982 int &iLabel)
00983 {
00984 if (entrynb < 0)
00985 return -1;
00986 iIface = LIB_.Entry_[entrynb].iIface_;
00987 iLabel = LIB_.Entry_[entrynb].iLabel_;
00988 return 0;
00989 }
00990
00991 void MPLSAddressClassifier::LIBdump(const char *id)
00992 {
00993 fflush(stdout);
00994 printf(" ___LIB dump___ [node: %s]\n", id);
00995 printf("---------------------------------------------\n");
00996 printf(" # iIface iLabel oIface oLabel LIBptr\n");
00997 for (int i = 0; i < LIB_.NB_; i++) {
00998 if (!LIBisdeleted(i))
00999 continue;
01000 printf(" %d: ", i);
01001 printf(" %d ", LIB_.Entry_[i].iIface_);
01002 printf(" %d ", LIB_.Entry_[i].iLabel_);
01003 printf(" %d ", LIB_.Entry_[i].oIface_);
01004 printf(" %d ", LIB_.Entry_[i].oLabel_);
01005 printf(" %d\n", LIB_.Entry_[i].LIBptr_);
01006 }
01007 printf("\n");
01008 }
01009
01010
01011
01012
01013
01014 int MPLSAddressClassifier::ErLspStacking(int erFEC0,int erLSPid0,
01015 int erFEC, int erLSPid)
01016 {
01017 int erLIBptr0 =-1, erLIBptr =-1;
01018
01019 if ((ERBlocate(erLSPid0,erFEC0,erLIBptr0) < 0) || (erLIBptr0 < 0))
01020 return -1;
01021 if ((ERBlocate(erLSPid,erFEC,erLIBptr) < 0) || (erLIBptr < 0))
01022 return -1;
01023 LIB_.Entry_[erLIBptr0].LIBptr_ = erLIBptr;
01024 return 0;
01025 }
01026
01027 int MPLSAddressClassifier::ErLspBinding(int FEC,int PHB, int erFEC, int LSPid)
01028 {
01029 int LIBptr=-1;
01030 int erLIBptr=-1;
01031
01032 if ((ERBlocate(LSPid, erFEC, erLIBptr) < 0) || (erLIBptr < 0))
01033 return -1;
01034
01035 int PFTnb = PFTlocate(FEC,PHB, LIBptr);
01036 if ((PFTnb < 0))
01037 PFTinsert(FEC,PHB, erLIBptr);
01038 else {
01039 if (LIBptr < 0)
01040 PFTupdate(PFTnb, LIBptr);
01041 else {
01042 int i = LIBptr;
01043 while (i < 0) {
01044 LIBptr = i;;
01045 i = LIB_.Entry_[LIBptr].LIBptr_;
01046 }
01047 LIB_.Entry_[LIBptr].LIBptr_ = erLIBptr;
01048 }
01049 }
01050 return 0;
01051 }
01052
01053 int MPLSAddressClassifier::FlowAggregation(int fineFEC, int finePHB,
01054 int coarseFEC, int coarsePHB)
01055 {
01056 int fLIBptr=-1;
01057 int cLIBptr=-1;
01058
01059 if ((PFTlocate(coarseFEC,coarsePHB, cLIBptr) < 0) || (cLIBptr < 0))
01060 return -1;
01061
01062 int PFTnb = PFTlocate(fineFEC,finePHB, fLIBptr);
01063 if ((PFTnb < 0))
01064 PFTinsert(fineFEC,finePHB, cLIBptr);
01065 else {
01066 if (fLIBptr < 0)
01067 PFTupdate(PFTnb, cLIBptr);
01068 else {
01069 int i=fLIBptr;
01070 while (i < 0) {
01071 fLIBptr = i;;
01072 i = LIB_.Entry_[fLIBptr].LIBptr_;
01073 }
01074 LIB_.Entry_[fLIBptr].LIBptr_ = cLIBptr;
01075 }
01076 }
01077 return 0;
01078 }
01079
01080 int MPLSAddressClassifier::aPathBinding(int FEC, int PHB, int erFEC, int LSPid)
01081 {
01082 int entrynb,tmp,erLIBptr;
01083
01084 entrynb = PFTlocate(FEC,PHB,tmp);
01085 if ((entrynb < 0) || (ERBlocate(LSPid,erFEC,erLIBptr) < 0))
01086 return -1;
01087 PFT_.Entry_[entrynb].aPATHptr_ = erLIBptr;
01088 return 0;
01089 }
01090
01091 int MPLSAddressClassifier::aPathLookup(int FEC,int PHB, int &oIface,
01092 int &oLabel, int &LIBptr)
01093 {
01094 oIface = oLabel = LIBptr = -1;
01095
01096 if (FEC < 0)
01097 return -1;
01098 for (int i = 0; i < PFT_.NB_; i++)
01099 if ((PFT_.Entry_[i].FEC_ == FEC) &&
01100 (PFT_.Entry_[i].PHB_ == PHB))
01101 return LIBlookup(PFT_.Entry_[i].aPATHptr_,
01102 oIface, oLabel, LIBptr);
01103 return -1;
01104 }
01105
01106 void MPLSAddressClassifier::trace(char *ptype, int psize, int ilabel,
01107 char *op, int oiface, int olabel, int ttl)
01108 {
01109 if (trace_mpls_ != 1)
01110 return;
01111 Tcl::instance().evalf("%s trace-packet-switching " TIME_FORMAT
01112 " %d %d %s %d %s %d %d %d %d",
01113 name(),
01114 Scheduler::instance().clock(),
01115 PI_.srcnode_,
01116 PI_.dst_.addr_,
01117 ptype,
01118 ilabel,
01119 op,
01120 oiface,
01121 olabel,
01122 ttl,
01123 psize);
01124 }