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