11 using namespace forest;
24 int main(
int argc,
char *argv[]) {
30 (sscanf(argv[3],
"%d", &firstComt)) != 1 ||
31 (sscanf(argv[4],
"%d", &lastComt)) != 1 ||
32 sscanf(argv[6],
"%d", &finTime) != 1) {
33 fatal(
"usage: ComtCtl nmIp myIp firstComt lastComt topoFile "
36 if (!
init(nmIp, myIp, firstComt, lastComt, argv[5])) {
37 fatal(
"ComtCtl: initialization failure");
49 bool init(ipa_t nmIp1, ipa_t myIp1,
int firstComt1,
int lastComt1,
50 const char *topoFile) {
52 firstComt = firstComt1;
lastComt = lastComt1;
60 if (firstComt < 1 || lastComt < 1 || firstComt >
lastComt) {
61 logger->
log(
"init: invalid comtree range\n",2);
66 int maxNode = 5000;
int maxLink = 10000;
67 int maxRtr = 4500;
int maxCtl = 400;
69 net =
new NetInfo(maxNode, maxLink, maxRtr, maxCtl);
72 logger->
log(
"init: cannot initialize ComtInfo object",2);
75 ifstream fs; fs.open(topoFile);
77 logger->
log(
"ComtCtl::init: could not read topology file, or "
78 "error in topology file",2);
85 comtSet =
new UiSetPair((lastComt-firstComt)+1);
89 if (firstComt <= comt && comt <= lastComt) {
90 comtSet->swap((comt-firstComt)+1);
104 logger->
log(
"init: can't initialize substrate",2);
107 sub->setRtrReady(
true);
111 logger->
log(
"init: could not initialize comtree set lock",2);
118 fAdr_t& rtrAdr, ipa_t& rtrIp, ipp_t& rtrPort, uint64_t& nonce) {
122 if (bootSock < 0)
return false;
130 CtlPkt cp(CtlPkt::BOOT_LEAF,CtlPkt::REQUEST,1,p.payload());
131 int plen = cp.
pack();
132 if (plen == 0) { close(bootSock);
return false; }
142 ipa_t srcIp; ipp_t srcPort;
145 if (now > resendTime) {
148 close(bootSock);
return false;
150 resendTime += 1000000;
155 if (nbytes < 0)
continue;
160 logger->
log(
"unexpected response to boot request",
162 close(bootSock);
return false;
165 if (repCp.
type != CtlPkt::CONFIG_LEAF ||
166 repCp.
mode != CtlPkt::REQUEST) {
167 logger->
log(
"unexpected response from NetMgr",2,reply);
168 close(bootSock);
return false;
172 myAdr = repCp.adr1; rtrAdr = repCp.adr2;
173 rtrIp = repCp.ip1; rtrPort = repCp.port1;
178 repCp.
reset(CtlPkt::CONFIG_LEAF,CtlPkt::POS_REPLY,repCp.
seqNum,
181 if (plen == 0) { close(bootSock);
return false; }
187 close(bootSock);
return false;
195 if (now > resendTime) {
198 close(bootSock);
return false;
200 resendTime += 1000000;
204 if (nbytes < 0) { usleep(100000);
continue; }
207 logger->
log(
"unexpected response to boot request",
209 close(bootSock);
return false;
213 if (repCp.
type == CtlPkt::CONFIG_LEAF &&
214 repCp.
mode == CtlPkt::REQUEST) {
216 repCp.
reset(CtlPkt::CONFIG_LEAF,CtlPkt::POS_REPLY,
219 if (plen == 0) { close(bootSock);
return false; }
226 close(bootSock);
return false;
228 }
else if (repCp.
type != CtlPkt::BOOT_LEAF ||
229 repCp.
mode != CtlPkt::POS_REPLY) {
230 logger->
log(
"unexpected response from NetMgr",
232 close(bootSock);
return false;
236 close(bootSock);
return true;
268 bool success =
false;
273 success = handleComtreeDisplay(sock);
278 case CtlPkt::CLIENT_ADD_COMTREE:
279 success = handleAddComtReq(px,cp,cph);
281 case CtlPkt::CLIENT_DROP_COMTREE:
282 success = handleDropComtReq(px,cp,cph);
284 case CtlPkt::CLIENT_JOIN_COMTREE:
285 success = handleJoinComtReq(px,cp,cph);
287 case CtlPkt::CLIENT_LEAVE_COMTREE:
288 success = handleLeaveComtReq(px,cp,cph);
290 case CtlPkt::COMTREE_PATH:
291 success = handleComtPath(px,cp,cph);
293 case CtlPkt::COMTREE_NEW_LEAF:
294 success = handleComtNewLeaf(px,cp,cph);
296 case CtlPkt::COMTREE_PRUNE:
297 success = handleComtPrune(px,cp,cph);
300 cph.errReply(px,cp,
"invalid control packet "
306 logger->
log(
"handler: operation failed",2,p);
320 bool handleComtreeDisplay(
int sock) {
341 if (!buf.readAlphas(word)) {
342 logger->
log(
"handleComtreeDisplay: could not read "
343 "request from remote display",2);
346 if (word ==
"getNet") {
351 logger->
log(
"handleComtreeDisplay: unable to "
352 "send network topology to display",2);
355 }
else if (word ==
"getComtSet") {
357 comtSet <<
"comtSet(";
364 string s = comtSet.str();
365 if (count > 0) s.erase(s.end()-1);
368 logger->
log(
"handleComtreeDisplay: unable to "
369 "send comtree set to display",2);
372 }
else if (word.compare(
"getComtree") == 0) {
374 if (!buf.readInt(comt)) {
375 s =
"invalid comtree request\n";
380 s =
"invalid comtree request\n";
386 logger->
log(
"handleComtreeDisplay: unable to "
387 "send comtree status update to "
392 logger->
log(
"handleComtreeDisplay: unrecognized request "
393 + word +
" from comtreeDisplay",2);
412 cph.
errReply(px,cp,
"missing required attribute");
417 int comt = newComtreeNum();
419 cph.
errReply(px,cp,
"no comtrees available to satisfy request");
424 releaseComtreeNum(comt);
425 cph.
errReply(px,cp,
"internal error prevents adding new "
427 logger->
log(
"handleAddComt: addComtree() failed due to program "
437 vector<int> matches(100,0);
int cnt = 0;
442 matches[cnt++] = rtr;
447 releaseComtreeNum(comt);
449 cph.
errReply(px,cp,
"network contains no router with specified "
453 int rootRtr = matches[randint(0,cnt-1)];
458 int reply = cph.
addComtree(rtrAdr,comt,repCp);
459 if (reply == 0 || repCp.
mode != CtlPkt::POS_REPLY) {
460 releaseComtreeNum(comt);
463 "root router never replied" :
464 "root router could not add comtree"));
465 if (reply != 0)
ps->
free(reply);
470 reply = cph.
modComtree(rtrAdr,comt,0,1,repCp);
471 if (reply == 0 || repCp.
mode != CtlPkt::POS_REPLY) {
472 releaseComtreeNum(comt);
475 "root router never replied" :
476 "root router could not modify comtree"));
477 if (reply != 0)
ps->
free(reply);
500 int newComtreeNum() {
502 int comt = comtSet->firstOut();
509 comt += (firstComt - 1);
517 void releaseComtreeNum(
int comt) {
518 comt -= (firstComt - 1);
520 if (comtSet->isIn(comt)) comtSet->swap(comt);
544 cph.
errReply(px,cp,
"missing required attribute");
560 cph.
errReply(px,cp,
"only the owner can drop a comtree");
567 teardownComtNode(ctx,rtr,cph);
575 releaseComtreeNum(comt);
604 cph.
errReply(px,cp,
"no such router");
613 cph.
errReply(px,cp,
"no such comtree");
621 RateSpec pathRates = (autoConfig ? leafDefRates : bbDefRates);
625 cph.
errReply(px,cp,
"cannot find path to comtree");
632 repCp.rspec1 = pathRates; repCp.
rspec2 = leafDefRates;
652 fAdr_t branchRtrAdr = cp.adr2;
653 vector<int>& path = cp.
ivec;
659 cph.
errReply(px,cp,
"no such router");
668 cph.
errReply(px,cp,
"no such comtree");
681 int len = path.size();
682 int top = -1;
int topRtr = 0;
684 if (branchRtrAdr != cliRtrAdr ||
687 cph.
errReply(px,cp,
"specified client and branch router "
688 "not consistent with comtree topology");
695 for (
int i = 0; i < len; i++) {
697 if (radr == branchRtrAdr &&
700 }
else if (i == len-1) {
708 cph.
errReply(px,cp,
"specified branch router not "
719 for (
int i = top; i >= 0; i--) {
759 fAdr_t pruneAdr = cp.adr1;
765 cph.
errReply(px,cp,
"no such router");
774 cph.
errReply(px,cp,
"no such comtree");
782 if (pruneAdr != rtrAdr) {
784 cph.
errReply(px,cp,
"cannot prune a different router");
787 removeSubtree(ctx,rtrAdr);
805 void removeSubtree(
int ctx,
fAdr_t rtrAdr) {
809 vector<fAdr_t> dropVec;
813 dropVec.push_back(ladr);
821 removeSubtree(ctx,cadr);
852 pair<fAdr_t,fAdr_t> leafRange;
854 if (cliAdr >= leafRange.first && cliAdr <= leafRange.second)
861 cph.
errReply(px,cp,
"can't find client's access router");
871 cph.
errReply(px,cp,
"no such comtree");
885 list<LinkMod> modList;
890 RateSpec pathRates = (autoConfig ? leafDefRates : bbDefRates);
891 int tryCount = 1;
int branchRtr = 0;
895 if (branchRtr == 0 || tryCount++ > 3) {
898 cph.
errReply(px,cp,
"cannot find path to comtree");
909 ctx,cliRtrAdr,leafDefRates);
914 cph.
errReply(px,cp,
"cannot add required "
915 "capacity to comtree backbone");
924 if (!setupPath(ctx,path,cph)) {
926 teardownPath(ctx,path,cph);
931 ctx,cliRtrAdr,leafDefRates);
935 }
else if (autoConfig &&
936 !modComtRates(ctx,modList,
false,cph)) {
939 modComtRates(ctx,modList,
true,cph);
942 ctx,cliRtrAdr,leafDefRates);
946 teardownPath(ctx,path,cph);
950 path.clear(); modList.clear();
954 int llnk = setupClientLink(ctx,cliAdr,cliRtr,cph);
959 if (llnk == 0 || !setComtLeafRates(ctx,cliAdr,cph)) {
964 modComtRates(ctx,modList,
true,cph);
967 ctx,cliRtrAdr,leafDefRates);
971 teardownPath(ctx,path,cph);
973 cph.
errReply(px,cp,
"cannot configure leaf node");
1001 if (cliAdr >= leafRange.first && cliAdr <= leafRange.second)
1005 cph.
errReply(px,cp,
"can't find client's access router");
1006 logger->
log(
"handleLeaveComt: cannot find client's access "
1007 "router in network topology\n",2,p);
1016 cph.
errReply(px,cp,
"no such comtree");
1028 teardownClientLink(ctx,cliAdr,cliRtr,cph);
1040 list<LinkMod> modList;
1046 modComtRates(ctx,modList,
true,cph);
1051 fAdr_t rtrAdr = cliRtrAdr;
1056 if (plnk == 0 || (rtrAdr == cliRtrAdr && lnkCnt > 1) ||
1057 (rtrAdr != cliRtrAdr && lnkCnt > 2))
1060 path.push_back(
LinkMod(plnk,rtr,rs));
1069 teardownPath(ctx,path,cph);
1089 bool setupPath(
int ctx, list<LinkMod>& path,
CpHandler& cph) {
1092 if (!setupComtNode(ctx,lm.child,cph)) {
1100 if (!setupComtLink(ctx,lm.lnk,lm.child,cph)) {
1103 if (!setupComtLink(ctx,lm.lnk,parent,cph)) {
1106 if (!setupComtAttrs(ctx,lm.child,cph)) {
1109 if (!setComtLinkRates(ctx,lm.lnk,lm.child,cph)) {
1112 if (!setComtLinkRates(ctx,lm.lnk,parent,cph)) {
1128 bool teardownPath(
int ctx, list<LinkMod>& path,
CpHandler& cph) {
1131 if (!teardownComtNode(ctx,lm.child,cph))
1142 bool setupComtNode(
int ctx,
int rtr,
CpHandler& cph) {
1146 if (reply == 0)
return false;
1148 return repCp.
mode == CtlPkt::POS_REPLY;
1156 bool teardownComtNode(
int ctx,
int rtr,
CpHandler& cph) {
1160 if (reply == 0)
return false;
1162 return repCp.
mode == CtlPkt::POS_REPLY;
1171 bool setupComtLink(
int ctx,
int lnk,
int rtr,
CpHandler& cph) {
1178 if (reply == 0)
return false;
1180 return repCp.
mode == CtlPkt::POS_REPLY;
1190 int setupClientLink(
int ctx,
fAdr_t cliAdr,
int rtr,
CpHandler& cph) {
1195 if (reply == 0)
return 0;
1197 return (repCp.
mode == CtlPkt::POS_REPLY ? repCp.
link : 0);
1206 bool teardownClientLink(
int ctx,
fAdr_t cliAdr,
int rtr,
CpHandler& cph) {
1211 if (reply == 0)
return false;
1213 return repCp.
mode == CtlPkt::POS_REPLY;
1221 bool setupComtAttrs(
int ctx,
int rtr,
CpHandler& cph) {
1227 if (reply == 0)
return false;
1229 return repCp.
mode == CtlPkt::POS_REPLY;
1239 bool setComtLinkRates(
int ctx,
int lnk,
int rtr,
CpHandler& cph) {
1253 if (reply == 0)
return false;
1255 if (repCp.
mode == CtlPkt::POS_REPLY)
return true;
1263 if (reply == 0)
return false;
1265 if (repCp.
mode != CtlPkt::POS_REPLY)
return false;
1266 if (repCp.
rspec2.isSet()) {
1286 if (reply == 0)
return false;
1288 return repCp.
mode == CtlPkt::POS_REPLY;
1300 bool modComtRates(
int ctx, list<LinkMod>& modList,
bool nostop,
CpHandler& cph) {
1302 if (!nostop && !setComtLinkRates(ctx,lm.lnk,lm.child,cph))
1305 if (!nostop && !setComtLinkRates(ctx,lm.lnk,parent,cph))