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 #include "config.h"
00068
00069 #include <iostream>
00070
00071 #include "ldp.h"
00072
00073 int hdr_ldp::offset_;
00074
00075 static class LDPHeaderClass : public PacketHeaderClass {
00076 public:
00077 LDPHeaderClass() : PacketHeaderClass("PacketHeader/LDP",
00078 sizeof(hdr_ldp)) {
00079 bind_offset(&hdr_ldp::offset_);
00080 }
00081 } class_ldphdr;
00082
00083 static class LDPClass : public TclClass {
00084 public:
00085 LDPClass() : TclClass("Agent/LDP") {}
00086 TclObject* create(int, const char*const*) {
00087 return (new LDPAgent());
00088 }
00089 } class_agentldp;
00090
00091 LDPAgent::LDPAgent() : Agent(PT_LDP),
00092 new_msgid_(0), trace_ldp_(0), peer_(0)
00093 {
00094 MSGT_.NB = 0;
00095 }
00096
00097 void LDPAgent::delay_bind_init_all()
00098 {
00099 delay_bind_init_one("trace_ldp_");
00100 Agent::delay_bind_init_all();
00101 }
00102
00103 int LDPAgent::delay_bind_dispatch(const char *varName, const char *localName,
00104 TclObject *tracer)
00105 {
00106 if (delay_bind_bool(varName,localName,"trace_ldp_",&trace_ldp_,tracer))
00107 return TCL_OK;
00108 return Agent::delay_bind_dispatch(varName, localName, tracer);
00109 }
00110
00111 int LDPAgent::PKTsize(const char *pathvec, const char *er)
00112 {
00113
00114 int psize = 10;
00115
00116 psize += 8;
00117
00118 int len = strlen(pathvec);
00119 if (len > 1) {
00120 psize += 4;
00121 for (int i=0; i<len; i++)
00122 if ( *(pathvec+i) == ' ' ) {
00123 psize += 4;
00124 }
00125 }
00126
00127 len = strlen(er);
00128 if (len > 1) {
00129 psize += 4;
00130 for (int i=0; i<len; i++)
00131 if (*(er+i) == ' ')
00132 psize += 4;
00133 }
00134 return (psize);
00135 }
00136
00137 void LDPAgent::PKTinit(hdr_ldp *hdrldp, int msgtype,
00138 const char *pathvec, const char *er)
00139 {
00140 hdrldp->msgtype = msgtype;
00141 hdrldp->msgid = new_msgid_;
00142 hdrldp->fec = -1;
00143 hdrldp->label = -1;
00144 hdrldp->reqmsgid= -1;
00145 hdrldp->status = -1;
00146
00147 int i;
00148 int len = strlen(pathvec);
00149 hdrldp->pathvec = (char *) malloc(len+1);
00150 for (i=0; i<len; i++) {
00151 if ( *(pathvec+i) == ' ' )
00152 *(hdrldp->pathvec+i) = '_';
00153 else
00154 *(hdrldp->pathvec+i) = *(pathvec+i);
00155 }
00156 *(hdrldp->pathvec+len) = '\0';
00157
00158 len = strlen(er);
00159 hdrldp->er = (char *) malloc(len+1);
00160 for (i=0; i<len; i++) {
00161 if ( *(er+i) == ' ' )
00162 *(hdrldp->er+i) = '_';
00163 else
00164 *(hdrldp->er+i) = *(er+i);
00165 }
00166 *(hdrldp->er+len) = '\0';
00167
00168 hdrldp->lspid = -1;
00169 hdrldp->rc = -1;
00170 }
00171
00172 int LDPAgent::command(int argc, const char*const* argv)
00173 {
00174 Tcl& tcl = Tcl::instance();
00175 if (argc == 2) {
00176 if (strcmp(argv[1], "msgtbl-dump") == 0) {
00177 MSGTdump();
00178 return (TCL_OK);
00179 } else if (strcmp(argv[1], "new-msgid") == 0) {
00180 tcl.resultf("%d", ++new_msgid_);
00181 return (TCL_OK);
00182 } else if (strcmp(argv[1], "peer-ldpnode") == 0) {
00183 tcl.resultf("%d", peer_);
00184 return (TCL_OK);
00185 }
00186 } else if (argc == 3) {
00187 if (strcmp(argv[1], "set-peer") == 0) {
00188 peer_ = atoi(argv[2]);
00189 return (TCL_OK);
00190 }
00191
00192
00193 int MsgID = atoi(argv[2]);
00194 int msgid,fec,lspid,src,pmsgid,labelop;
00195 int entrynb = MSGTlocate(MsgID);
00196 MSGTlookup(entrynb,msgid,fec,lspid,src,pmsgid,labelop);
00197
00198 if (strcmp(argv[1], "msgtbl-clear") == 0) {
00199
00200 if (entrynb > -1)
00201 MSGTdelete(entrynb);
00202 return (TCL_OK);
00203 } else if (strcmp(argv[1], "msgtbl-get-src") == 0) {
00204
00205 tcl.resultf("%d", src);
00206 return (TCL_OK);
00207 } else if (strcmp(argv[1], "msgtbl-get-reqmsgid") == 0) {
00208
00209 tcl.resultf("%d",pmsgid);
00210 return (TCL_OK);
00211 } else if (strcmp(argv[1], "msgtbl-get-labelop") == 0) {
00212
00213 tcl.resultf("%d", labelop);
00214 return (TCL_OK);
00215 } else if (strcmp(argv[1], "msgtbl-get-erlspid") == 0) {
00216
00217
00218
00219 tcl.resultf("%d",MSGT_.Entry[entrynb].ERLspID);
00220 return (TCL_OK);
00221 } else if (strcmp(argv[1], "msgtbl-set-labelpass") == 0) {
00222
00223
00224
00225 MSGT_.Entry[entrynb].LabelOp = LDP_LabelPASS;
00226 return (TCL_OK);
00227 }
00228 } else if (argc == 4) {
00229 if (strcmp(argv[1], "notification-msg") == 0) {
00230
00231
00232
00233 size_ = PKTsize("*", "*");
00234 if ( atoi(argv[3]) > -1 )
00235 size_ += 16;
00236 else
00237 size_ += 8;
00238 Packet* pkt = allocpkt();
00239 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00240 PKTinit(hdrldp, LDP_NotificationMSG, "*", "*");
00241
00242 if (strcmp(argv[2], "LoopDetected") == 0)
00243 hdrldp->status = LDP_LoopDetected;
00244 else if (strcmp(argv[2], "NoRoute") == 0)
00245 hdrldp->status = LDP_NoRoute;
00246
00247 hdrldp->lspid = atoi(argv[3]);
00248 send(pkt, 0);
00249 return (TCL_OK);
00250 } else if (strcmp(argv[1], "withdraw-msg") == 0) {
00251
00252
00253
00254 size_ = PKTsize("*","*");
00255 if ( atoi(argv[3]) > -1 )
00256 size_ += 16;
00257 else
00258 size_ += 8;
00259 Packet* pkt = allocpkt();
00260 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00261 PKTinit(hdrldp, LDP_WithdrawMSG, "*", "*");
00262 hdrldp->fec = atoi(argv[2]);
00263 hdrldp->lspid = atoi(argv[3]);
00264 send(pkt, 0);
00265 return (TCL_OK);
00266 } else if (strcmp(argv[1], "release-msg") == 0) {
00267
00268
00269
00270 size_ = PKTsize("*","*");
00271 if ( atoi(argv[3]) > -1 )
00272 size_ += 16;
00273 else
00274 size_ += 8;
00275 Packet* pkt = allocpkt();
00276 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00277 PKTinit(hdrldp, LDP_ReleaseMSG,"*","*");
00278 hdrldp->fec = atoi(argv[2]);
00279 hdrldp->lspid = atoi(argv[3]);
00280 send(pkt, 0);
00281 return (TCL_OK);
00282 } else if (strcmp(argv[1], "request-msg") == 0) {
00283
00284
00285
00286 size_ = PKTsize(argv[3],"*");
00287 size_ += 8;
00288 Packet* pkt = allocpkt();
00289 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00290 PKTinit(hdrldp, LDP_RequestMSG, argv[3], "*");
00291 hdrldp->fec = atoi(argv[2]);
00292 send(pkt, 0);
00293 return (TCL_OK);
00294 } else if (strcmp(argv[1], "msgtbl-set-labelstack") == 0) {
00295
00296
00297
00298 int MsgID = atoi(argv[2]);
00299 int ERLspID = atoi(argv[3]);
00300 int entrynb = MSGTlocate(MsgID);
00301 MSGT_.Entry[entrynb].LabelOp = LDP_LabelSTACK;
00302 MSGT_.Entry[entrynb].ERLspID = ERLspID;
00303 return (TCL_OK);
00304 }
00305 } else if (argc == 5) {
00306 if (strcmp(argv[1], "msgtbl-get-msgid") == 0) {
00307
00308
00309
00310 int msgid,tmp;
00311 int fec = atoi(argv[2]);
00312 int LspID = atoi(argv[3]);
00313 int src = atoi(argv[4]);
00314 int entrynb = MSGTlocate(fec,LspID,src);
00315
00316 MSGTlookup(entrynb,msgid,tmp,tmp,tmp,tmp,tmp);
00317 tcl.resultf("%d", msgid);
00318 return (TCL_OK);
00319 }
00320 } else if (argc == 6) {
00321 if (strcmp(argv[1], "mapping-msg") == 0) {
00322
00323
00324
00325 size_ = PKTsize(argv[4],"*");
00326 if ( atoi(argv[5]) > -1 )
00327 size_ += 24;
00328 else
00329 size_ += 16;
00330 Packet* pkt = allocpkt();
00331 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00332 PKTinit(hdrldp, LDP_MappingMSG, argv[4], "*");
00333 hdrldp->fec = atoi(argv[2]);
00334 hdrldp->label = atoi(argv[3]);
00335 hdrldp->reqmsgid= atoi(argv[5]);
00336 send(pkt, 0);
00337 return (TCL_OK);
00338 } else if (strcmp(argv[1], "cr-mapping-msg") == 0) {
00339
00340
00341
00342
00343 size_ = PKTsize("*","*");
00344 size_ += 32;
00345 Packet* pkt = allocpkt();
00346 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00347 PKTinit(hdrldp, LDP_MappingMSG, "*", "*");
00348 hdrldp->fec = atoi(argv[2]);
00349 hdrldp->label = atoi(argv[3]);
00350 hdrldp->lspid = atoi(argv[4]);
00351 hdrldp->reqmsgid= atoi(argv[5]);
00352 send(pkt, 0);
00353 return (TCL_OK);
00354 }
00355 } else if (argc == 7) {
00356 if (strcmp(argv[1], "cr-request-msg") == 0) {
00357
00358
00359
00360 size_ = PKTsize(argv[3],argv[4]);
00361 if (atoi(argv[6]) > -1)
00362 size_ += 24;
00363 else
00364 size_ += 16;
00365 Packet* pkt = allocpkt();
00366 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00367 PKTinit(hdrldp, LDP_RequestMSG, argv[3], argv[4]);
00368 hdrldp->fec = atoi(argv[2]);
00369 hdrldp->lspid = atoi(argv[5]);
00370 hdrldp->rc = atoi(argv[6]);
00371 send(pkt, 0);
00372 return (TCL_OK);
00373 } else if (strcmp(argv[1], "msgtbl-install") == 0) {
00374
00375
00376
00377
00378 int msgid = atoi(argv[2]);
00379 int fec = atoi(argv[3]);
00380 int LspID = atoi(argv[4]);
00381 int src = atoi(argv[5]);
00382 int PMsgID = atoi(argv[6]);
00383 int entrynb = MSGTinsert(msgid,fec,LspID,src,PMsgID);
00384 tcl.resultf("%d", entrynb);
00385 return (TCL_OK);
00386 }
00387 }
00388 return (Agent::command(argc, argv));
00389 }
00390
00391 void LDPAgent::recv(Packet* pkt, Handler*)
00392 {
00393 char out[400];
00394 Tcl& tcl = Tcl::instance();
00395
00396 hdr_ldp *hdrldp = hdr_ldp::access(pkt);
00397 int msgtype = hdrldp->msgtype;
00398 int msgid = hdrldp->msgid;
00399 int fec = hdrldp->fec;
00400 int label = hdrldp->label;
00401 int reqmsgid= hdrldp->reqmsgid;
00402 int status = hdrldp->status;
00403 int lspid = hdrldp->lspid;
00404 int rc = hdrldp->rc;
00405
00406 char pathvec[400];
00407 char er[400];
00408 strcpy(pathvec, hdrldp->pathvec);
00409 strcpy(er, hdrldp->er);
00410
00411 ns_addr_t src = hdr_ip::access(pkt)->src_;
00412 trace(src, hdrldp);
00413
00414 free(hdrldp->pathvec);
00415 free(hdrldp->er);
00416 Packet::free(pkt);
00417
00418 switch (msgtype) {
00419 case LDP_NotificationMSG:
00420 char code[30];
00421 strcpy(code, parse_status(status));
00422 sprintf(out, "%s get-notification-msg %d %s %d",
00423 name(), src.addr_, code, lspid);
00424 tcl.eval(out);
00425 break;
00426
00427 case LDP_MappingMSG:
00428 if (lspid >= 0) {
00429
00430 sprintf(out, "%s get-cr-mapping-msg %d %d %d %d %d %d",
00431 name(), msgid, src.addr_, fec,
00432 label, lspid, reqmsgid);
00433 } else {
00434 sprintf(out, "%s get-mapping-msg %d %d %d %d %s %d",
00435 name(), msgid, src.addr_, fec,
00436 label, pathvec, reqmsgid);
00437 }
00438 tcl.eval(out);
00439 break;
00440
00441 case LDP_RequestMSG:
00442 if (lspid >= 0) {
00443 sprintf(out,
00444 "%s get-cr-request-msg %d %d %d %s %s %d %d",
00445 name(), msgid, src.addr_, fec, pathvec,
00446 er, lspid, rc);
00447 } else {
00448 sprintf(out, "%s get-request-msg %d %d %d %s",
00449 name(), msgid, src.addr_, fec, pathvec);
00450 }
00451 tcl.eval(out);
00452 break;
00453
00454 case LDP_WithdrawMSG:
00455 sprintf(out, "%s get-withdraw-msg %d %d %d",
00456 name(), src.addr_, fec, lspid);
00457 tcl.eval(out);
00458 break;
00459
00460 case LDP_ReleaseMSG:
00461 sprintf(out, "%s get-release-msg %d %d %d",
00462 name(), src.addr_, fec, lspid);
00463 tcl.eval(out);
00464 break;
00465 }
00466 }
00467
00468 int LDPAgent::MSGTinsert(int MsgID, int FEC, int LspID, int Src, int PMsgID)
00469 {
00470 if (MSGT_.NB == LDP_MaxMSGTEntryNB - 1)
00471 return(-1);
00472
00473 if (MSGTlocate(FEC, LspID, Src) > -1)
00474 return(-1);
00475
00476 MSGT_.Entry[MSGT_.NB].MsgID = MsgID;
00477 MSGT_.Entry[MSGT_.NB].FEC = FEC;
00478 MSGT_.Entry[MSGT_.NB].LspID = LspID;
00479 MSGT_.Entry[MSGT_.NB].Src = Src;
00480 MSGT_.Entry[MSGT_.NB].PMsgID = PMsgID;
00481 MSGT_.Entry[MSGT_.NB].LabelOp = LDP_LabelALLOC;
00482 MSGT_.Entry[MSGT_.NB].ERLspID = -1;
00483
00484 MSGT_.NB++;
00485
00486 return(MSGT_.NB-1);
00487 }
00488
00489 void LDPAgent::MSGTdelete(int entrynb)
00490 {
00491 if ( (entrynb > -1) && (entrynb < MSGT_.NB) ) {
00492 MSGT_.Entry[entrynb].MsgID = -1;
00493 MSGT_.Entry[entrynb].FEC = MSGT_.Entry[entrynb].LspID = -1;
00494 MSGT_.Entry[entrynb].Src = MSGT_.Entry[entrynb].PMsgID = -1;
00495 MSGT_.Entry[entrynb].LabelOp = -1;
00496 MSGT_.Entry[entrynb].ERLspID = -1;
00497 }
00498 }
00499
00500 int LDPAgent::MSGTlocate(int MsgID)
00501 {
00502 if ( MsgID < 0 )
00503 return(-1);
00504
00505 for (int i=0; i<MSGT_.NB; i++) {
00506 if ( MSGT_.Entry[i].MsgID == MsgID )
00507 return(i);
00508 }
00509
00510 return(-1);
00511 }
00512
00513 int LDPAgent::MSGTlocate(int FEC, int LspID, int Src)
00514 {
00515 int i;
00516 if ( (FEC < 0) && (Src < 0) ) {
00517 if ( LspID > -1) {
00518 for (i=0; i<MSGT_.NB; i++)
00519 if ( MSGT_.Entry[i].LspID == LspID )
00520 return(i);
00521 }
00522 return(-1);
00523 }
00524
00525 for (i=0; i<MSGT_.NB; i++) {
00526 if ( (MSGT_.Entry[i].FEC == FEC ) &&
00527 (MSGT_.Entry[i].LspID == LspID) &&
00528 (MSGT_.Entry[i].Src == Src ) )
00529
00530 return(i);
00531 }
00532
00533 return(-1);
00534 }
00535
00536 void LDPAgent::MSGTlookup(int entrynb, int &MsgID, int &FEC, int &LspID,
00537 int &Src, int &PMsgID, int &LabelOp)
00538 {
00539 if ( (entrynb > -1) && (entrynb < MSGT_.NB) ) {
00540 MsgID = MSGT_.Entry[entrynb].MsgID;
00541 FEC = MSGT_.Entry[entrynb].FEC;
00542 LspID = MSGT_.Entry[entrynb].LspID;
00543 Src = MSGT_.Entry[entrynb].Src;
00544 PMsgID = MSGT_.Entry[entrynb].PMsgID;
00545 LabelOp= MSGT_.Entry[entrynb].LabelOp;
00546 } else {
00547 MsgID = FEC = LspID = Src = PMsgID = LabelOp = -1;
00548 }
00549 }
00550
00551 void LDPAgent::MSGTdump()
00552 {
00553 for (int i = 0; i < MSGT_.NB; i++) {
00554 cerr << " # MsgID =" << MSGT_.Entry[i].MsgID << " ";
00555 cerr << " # FEC =" << MSGT_.Entry[i].FEC << " ";
00556 cerr << " # LspID =" << MSGT_.Entry[i].LspID << " ";
00557 cerr << " # Src =" << MSGT_.Entry[i].Src << " ";
00558 cerr << " # PMsgID=" << MSGT_.Entry[i].PMsgID<< " ";
00559 cerr << " # LabelOp=" << MSGT_.Entry[i].LabelOp << "\n";
00560 }
00561 }
00562
00563 void LDPAgent::trace(ns_addr_t src, hdr_ldp *hdrldp)
00564 {
00565
00566
00567 if (trace_ldp_ == 1) {
00568 const char *msgtype = parse_msgtype(hdrldp->msgtype,
00569 hdrldp->lspid);
00570 const char *status = (hdrldp->msgtype == 0x0001) ?
00571 parse_status(hdrldp->status) : "*";
00572 Tcl::instance().evalf("%s trace-ldp-packet %d %d %s %d %d %d "
00573 "%s %d %s %d %d %s %7f",
00574 name(),
00575 src.addr_,
00576 src.port_,
00577 msgtype,
00578 hdrldp->msgid,
00579 hdrldp->fec,
00580 hdrldp->label,
00581 hdrldp->pathvec,
00582 hdrldp->lspid,
00583 hdrldp->er,
00584 hdrldp->rc,
00585 hdrldp->reqmsgid,
00586 status,
00587 Scheduler::instance().clock());
00588 }
00589 }
00590
00591 char* LDPAgent::parse_msgtype(int msgtype, int lspid)
00592 {
00593
00594 switch (msgtype) {
00595 case LDP_NotificationMSG:
00596 return("Notification");
00597
00598 case LDP_MappingMSG:
00599 if (lspid >= 0)
00600 return("CR-Mapping");
00601 else
00602 return("Mapping");
00603
00604 case LDP_RequestMSG:
00605 if (lspid >= 0)
00606 return("CR-Request");
00607 else
00608 return("Request");
00609
00610 case LDP_WithdrawMSG:
00611 return("Withdraw");
00612
00613 case LDP_ReleaseMSG:
00614 return("Release");
00615 }
00616
00617 return ("Error");
00618 }
00619
00620 char* LDPAgent::parse_status(int status)
00621 {
00622 switch (status) {
00623 case LDP_LoopDetected:
00624 return "LoopDetected";
00625
00626 case LDP_NoRoute:
00627 return "NoRoute";
00628
00629 default:
00630 return "Unknown";
00631 }
00632 }