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