11 using namespace forest;
33 for (
int i = 1; i < argc; i++) {
35 if (s.compare(0,10,
"mode=local") == 0) {
37 }
else if (s.compare(0,11,
"mode=remote") == 0) {
39 }
else if (s.compare(0,6,
"myAdr=") == 0) {
41 }
else if (s.compare(0,7,
"bootIp=") == 0) {
43 }
else if (s.compare(0,6,
"nmAdr=") == 0) {
45 }
else if (s.compare(0,5,
"nmIp=") == 0) {
47 }
else if (s.compare(0,6,
"ccAdr=") == 0) {
49 }
else if (s.compare(0,13,
"firstLeafAdr=") == 0) {
51 }
else if (s.compare(0,12,
"lastLeafAdr=") == 0) {
53 }
else if (s.compare(0,6,
"ifTbl=") == 0) {
54 args.
ifTbl = &argv[i][6];
55 }
else if (s.compare(0,7,
"lnkTbl=") == 0) {
57 }
else if (s.compare(0,8,
"comtTbl=") == 0) {
59 }
else if (s.compare(0,7,
"rteTbl=") == 0) {
61 }
else if (s.compare(0,9,
"statSpec=") == 0) {
63 }
else if (s.compare(0,8,
"portNum=") == 0) {
64 sscanf(&argv[i][8],
"%hd",&args.
portNum);
65 }
else if (s.compare(0,8,
"finTime=") == 0) {
66 sscanf(&argv[i][8],
"%d",&args.
finTime);
68 cerr <<
"unrecognized argument: " << argv[i] << endl;
72 if (args.
mode.compare(
"local") == 0 &&
75 cerr <<
"processArgs: local configuration requires myAdr, "
76 "firstLeafAdr, lastLeafAdr and that firstLeafAdr "
77 "be no larger than lastLeafAdr\n";
79 }
else if (args.
mode.compare(
"remote") == 0 &&
82 cerr <<
"processArgs: remote configuration requires bootIp, "
83 "myAdr, netMgrIp and netMgrAdr\n";
91 int main(
int argc,
char *argv[]) {
94 fatal(
"fRouter: error processing command line arguments");
95 bool booting = args.
mode.compare(
"remote") == 0;
98 if (!router.readTables(args))
99 fatal(
"router: could not read specified config files");
102 fatal(
"router: inconsistency in config files");
118 : booting(booting1) {
144 pending =
new map<uint64_t,CpInfo>;
147 RouterCore::~RouterCore() {
149 delete rt;
delete ctt;
delete lt;
delete ift;
delete ps;
160 if (config.
ifTbl.compare(
"") != 0) {
161 ifstream fs; fs.open(config.
ifTbl.c_str());
162 if (fs.fail() || !
ift->
read(fs)) {
163 cerr <<
"RouterCore::init: can't read "
164 <<
"interface table\n";
169 if (config.
lnkTbl.compare(
"") != 0) {
170 ifstream fs; fs.open(config.
lnkTbl.c_str());
171 if (fs.fail() || !
lt->
read(fs)) {
172 cerr <<
"RouterCore::init: can't read "
178 if (config.
comtTbl.compare(
"") != 0) {
179 ifstream fs; fs.open(config.
comtTbl.c_str());
180 if (fs.fail() || !
ctt->
read(fs)) {
181 cerr <<
"RouterCore::init: can't read "
182 <<
"comtree table\n";
187 if (config.
rteTbl.compare(
"") != 0) {
188 ifstream fs; fs.open(config.
rteTbl.c_str());
189 if (fs.fail() || !
rt->
read(fs)) {
190 cerr <<
"RouterCore::init: can't read "
191 <<
"routing table\n";
196 if (config.
statSpec.compare(
"") != 0) {
197 ifstream fs; fs.open(config.
statSpec.c_str());
198 if (fs.fail() || !
sm->read(fs)) {
199 cerr <<
"RouterCore::init: can't read "
200 <<
"statistics spec\n";
231 if (
iop->ready(iface))
continue;
233 cerr <<
"RouterCore::setupIfaces: could not "
234 "setup interface " << iface << endl;
265 qm->setLinkRates(lnk,
lt->getRates(lnk));
273 set<int>::iterator p;
274 for (p = links.begin(); p != links.end(); p++) {
277 if (qid == 0)
return false;
279 qm->setQRates(qid,rs);
281 qm->setQLimits(qid,100,200000);
283 qm->setQLimits(qid,50,100000);
284 sm->clearQuStats(qid);
302 cerr <<
"RouterCore::checkTables: specified default iface "
309 if (
ift->getIpAdr(iface) == 0) {
310 cerr <<
"RouterCore::checkTables: interface "
311 << iface <<
" has zero for IP address\n";
322 iface =
lt->getIface(lnk);
324 cerr <<
"RouterCore::checkTables: interface " << iface
325 <<
" for link " << lnk <<
" is not valid\n";
328 if (
lt->getPeerIpAdr(lnk) == 0 &&
330 cerr <<
"RouterCore::checkTables: invalid peer IP "
331 <<
"for link " << lnk << endl;
335 cerr <<
"RouterCore::checkTables: invalid peer address "
336 <<
"for link " << lnk << endl;
351 cerr <<
"RouterCore::checkTables: parent link "
352 << plnk <<
" not consistent with pcLnk\n";
356 cerr <<
"RouterCore::checkTables: parent link "
357 << plnk <<
" of core node does not lead to "
358 <<
"another core node\n";
362 set<int>::iterator p;
363 for (p = links.begin(); p != links.end(); p++) {
366 cerr <<
"RouterCore::checkTables: link "
367 << lnk <<
" in comtree " << comt
368 <<
" not in link table" << endl;
374 cerr <<
"RouterCore::checkTables: dest addr "
375 <<
"for " << lnk <<
" in comtree " << comt
376 <<
" is not valid" << endl;
381 cerr <<
"RouterCore::checkTables: queue id "
382 <<
"for " << lnk <<
" in comtree " << comt
383 <<
" is zero" << endl;
389 for (p = rtrLinks.begin(); p != rtrLinks.end(); p++) {
392 cerr <<
"RouterCore::checkTables: router link "
393 << lnk <<
" is not valid in comtree "
398 cerr <<
"RouterCore::checkTables: router link "
399 << lnk <<
" in comtree " << comt
400 <<
" connects to non-router peer\n";
405 for (p = coreLinks.begin(); p != coreLinks.end(); p++) {
408 cerr <<
"RouterCore::checkTables: core link "
409 << lnk <<
" is not a router link "
434 if (!minRates.leq(ifRates) || !ifRates.
leq(maxRates)) {
435 cerr <<
"RouterCore::setAvailRates: interface rates "
436 "outside allowed range\n";
439 ift->getAvailRates(iface) = ifRates;
441 if (!success)
return false;
445 if (!minRates.leq(lnkRates) || !lnkRates.
leq(maxRates)) {
446 cerr <<
"RouterCore::setAvailRates: link rates "
447 "outside allowed range\n";
450 iface =
lt->getIface(lnk);
452 if (!lnkRates.
leq(ifAvail)) {
453 cerr <<
"RouterCore::setAvailRates: oversubscribing "
454 "interface " << iface << endl;
457 ift->getAvailRates(iface).subtract(lnkRates);
459 lt->getAvailRates(lnk) = lnkRates;
460 sm->clearLnkStats(lnk);
462 if (!success)
return false;
467 set<int>::iterator p;
468 for (p = comtLinks.begin(); p != comtLinks.end(); p++) {
471 if (!comtRates.
leq(
lt->getAvailRates(lnk))) {
472 cerr <<
"RouterCore::setAvailRates: "
473 "oversubscribing link "
477 lt->getAvailRates(lnk).subtract(comtRates);
491 set<int>::iterator p;
492 for (p = comtLinks.begin(); p != comtLinks.end(); p++) {
494 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
499 if (
rt->getRteIndex(comt,peerAdr) != 0)
501 rt->addEntry(comt,peerAdr,cLnk);
511 out <<
"Interface Table\n\n" <<
ift->
toString(s) << endl;
512 out <<
"Link Table\n\n" <<
lt->
toString(s) << endl;
513 out <<
"Comtree Table\n\n" <<
ctt->
toString(s) << endl;
514 out <<
"Routing Table\n\n" <<
rt->
toString(s) << endl;
515 out <<
"Statistics\n\n" <<
sm->
toString(s) << endl;
550 fatal(
"RouterCore:run: could not setup boot socket\n");
554 CtlPkt cp(CtlPkt::BOOT_ROUTER,CtlPkt::REQUEST,0);
556 fatal(
"RouterCore::run: could not send boot request\n");
560 uint64_t statsTime = 0;
562 int controlCount = 20;
567 finishTime *= 1000000000;
568 while (finishTime == 0 ||
now < finishTime) {
572 pktx px =
iop->receive();
581 }
else if (booting) {
601 while ((px =
qm->
deq(lnk,
now)) != 0) {
608 if (!ctlQ.empty() && (didNothing || --controlCount <= 0)) {
617 if (
now - statsTime > 300000000) {
625 if (didNothing) { usleep(1000); }
634 cout <<
sm->iPktCnt(0) <<
" packets received, "
635 <<
sm->oPktCnt(0) <<
" packets sent\n";
636 cout <<
sm->iPktCnt(-1) <<
" from routers, "
637 <<
sm->oPktCnt(-1) <<
" to routers\n";
638 cout <<
sm->iPktCnt(-2) <<
" from clients, "
639 <<
sm->oPktCnt(-2) <<
" to clients\n";
672 if (inLink == 0)
return false;
681 if (
lt->getPeerAdr(inLink) != p.
srcAdr)
return false;
694 comt != (
int) Forest::CONNECT_COMT)
724 int rcLnk =
rt->getLink(rtx);
757 int qvec[
nLnks];
int n = 0;
766 set<int>::iterator lp;
767 for (lp = rtrLinks.begin(); lp != rtrLinks.end(); lp++) {
768 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
770 if (pZip == myZip && peerZip != myZip)
continue;
771 if (lnk == inLink)
continue;
779 set<int>::iterator lp;
780 for (lp = coreLinks.begin(); lp != coreLinks.end(); lp++) {
781 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
782 if (lnk == inLink || lnk == pLink)
continue;
786 if (pLink != 0 && pLink != inLink) {
791 set<int>& subLinks =
rt->getSubLinks(rtx);
792 for (lp = subLinks.begin(); lp !=subLinks.end(); lp++) {
793 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
794 if (lnk == inLink)
continue;
800 if (n == 0) {
ps->
free(px);
return; }
804 for (
int i = 0; i < n-1; i++) {
834 (p1.payload())[0] = htonl(p.
dstAdr);
855 int adr = ntohl((p.payload())[0]);
867 int dcLnk =
rt->getLink(rtx);
int dLnk =
ctt->
getLink(dcLnk);
882 uint32_t *pp = p.payload();
894 bool propagate =
false;
898 int addcnt = ntohl(pp[0]);
899 if (addcnt < 0 || addcnt > 350 ||
903 for (
int i = 1; i <= addcnt; i++) {
906 rtx =
rt->getRteIndex(comt,addr);
908 rtx =
rt->addEntry(comt,addr,cLnk);
916 int dropcnt = ntohl(pp[addcnt+1]);
917 if (dropcnt < 0 || addcnt + dropcnt > 350 ||
921 for (
int i = addcnt + 2; i <= addcnt + dropcnt + 1; i++) {
924 rtx =
rt->getRteIndex(comt,addr);
925 if (rtx == 0)
continue;
928 rt->removeEntry(rtx);
952 if (p.
srcAdr !=
lt->getPeerAdr(inLnk) ||
956 uint64_t nonce = ntohl(p.payload()[0]);
958 nonce |= ntohl(p.payload()[1]);
959 if (nonce !=
lt->getNonce(inLnk)) {
ps->
free(px);
return; }
961 uint64_t x = 1; x <<= 63; x |= nonce;
971 lt->setConnectStatus(inLnk,
true);
973 CtlPkt cp(CtlPkt::CLIENT_CONNECT,CtlPkt::REQUEST,0);
978 lt->setConnectStatus(inLnk,
false);
982 CtlPkt cp(CtlPkt::CLIENT_DISCONNECT,CtlPkt::REQUEST,0);
1007 cerr <<
"RouterCore::handleCtlPkt: misformatted control "
1009 cp.reset(cp.type,CtlPkt::NEG_REPLY,cp.seqNum);
1010 cp.mode = CtlPkt::NEG_REPLY;
1011 cp.errMsg =
"misformatted control packet";
1015 if (cp.mode != CtlPkt::REQUEST) {
1020 CtlPkt reply(cp.type,CtlPkt::POS_REPLY,cp.seqNum);
1025 case CtlPkt::ADD_IFACE:
addIface(cp,reply);
break;
1026 case CtlPkt::DROP_IFACE: dropIface(cp,reply);
break;
1027 case CtlPkt::GET_IFACE: getIface(cp,reply);
break;
1028 case CtlPkt::MOD_IFACE: modIface(cp,reply);
break;
1031 case CtlPkt::ADD_LINK: addLink(cp,reply);
break;
1032 case CtlPkt::DROP_LINK: dropLink(cp,reply);
break;
1033 case CtlPkt::GET_LINK: getLink(cp,reply);
break;
1034 case CtlPkt::MOD_LINK: modLink(cp,reply);
break;
1037 case CtlPkt::ADD_COMTREE: addComtree(cp,reply);
break;
1038 case CtlPkt::DROP_COMTREE: dropComtree(cp,reply);
break;
1039 case CtlPkt::GET_COMTREE: getComtree(cp,reply);
break;
1040 case CtlPkt::MOD_COMTREE: modComtree(cp,reply);
break;
1041 case CtlPkt::ADD_COMTREE_LINK: addComtreeLink(cp,reply);
break;
1042 case CtlPkt::DROP_COMTREE_LINK: dropComtreeLink(cp,reply);
break;
1043 case CtlPkt::GET_COMTREE_LINK: getComtreeLink(cp,reply);
break;
1044 case CtlPkt::MOD_COMTREE_LINK: modComtreeLink(cp,reply);
break;
1047 case CtlPkt::ADD_ROUTE: addRoute(cp,reply);
break;
1048 case CtlPkt::DROP_ROUTE: dropRoute(cp,reply);
break;
1049 case CtlPkt::GET_ROUTE: getRoute(cp,reply);
break;
1050 case CtlPkt::MOD_ROUTE: modRoute(cp,reply);
break;
1053 case CtlPkt::SET_LEAF_RANGE:
setLeafRange(cp,reply);
break;
1055 case CtlPkt::GET_LINK_SET:
getLinkSet(cp,reply);
break;
1057 cerr <<
"unrecognized control packet type " << cp.type
1059 reply.errMsg =
"invalid control packet for router";
1060 reply.mode = CtlPkt::NEG_REPLY;
1083 int iface = cp.
iface;
1093 if (cp.
iface !=
ift->getIpAdr(iface) ||
1094 !rs.equals(
ift->getRates(iface))) {
1095 reply.
errMsg =
"add iface: requested interface "
1096 "conflicts with existing interface";
1097 reply.
mode = CtlPkt::NEG_REPLY;
1101 reply.ip1 =
ift->getIpAdr(iface);
1102 reply.port1 =
ift->getPort(iface);
1104 }
else if (!
ift->
addEntry(iface, cp.ip1, 0, rs)) {
1105 reply.
errMsg =
"add iface: cannot add interface";
1106 reply.
mode = CtlPkt::NEG_REPLY;
1109 reply.
errMsg =
"add iface: could not setup interface";
1110 reply.
mode = CtlPkt::NEG_REPLY;
1113 reply.ip1 =
ift->getIpAdr(iface);
1114 reply.port1 =
ift->getPort(iface);
1118 bool RouterCore::dropIface(
CtlPkt& cp,
CtlPkt& reply) {
1124 int iface = cp.
iface;
1126 reply.
iface = iface;
1127 reply.ip1 =
ift->getIpAdr(iface);
1128 reply.port1 =
ift->getPort(iface);
1129 reply.rspec1 =
ift->getRates(iface);
1130 reply.
rspec2 =
ift->getAvailRates(iface);
1133 reply.
errMsg =
"get iface: invalid interface";
1134 reply.
mode = CtlPkt::NEG_REPLY;
1139 int iface = cp.
iface;
1141 ift->getRates(iface) = cp.rspec1;
1144 reply.
errMsg =
"mod iface: invalid interface";
1145 reply.
mode = CtlPkt::NEG_REPLY;
1152 reply.
errMsg =
"add link: adding link to router, but no peer "
1154 reply.
mode = CtlPkt::NEG_REPLY;
1157 int iface = cp.
iface;
1159 int xlnk =
lt->
lookup(cp.ip1,cp.port1);
1161 if (cp.
link != xlnk ||
1162 (peerType !=
lt->getPeerType(xlnk)) ||
1163 (cp.
iface !=
lt->getIface(xlnk)) ||
1164 (cp.adr1 != 0 && cp.adr1 !=
lt->getPeerAdr(xlnk)) ||
1165 (cp.ip1 != 0 && cp.ip1 !=
ift->getIpAdr(iface)) ||
1166 (cp.port1 != 0 && cp.port1 !=
ift->getPort(iface))) {
1167 reply.
errMsg =
"add link: new link conflicts "
1168 "with existing link";
1169 reply.
mode = CtlPkt::NEG_REPLY;
1174 reply.adr1 =
lt->getPeerAdr(xlnk);
1175 reply.ip1 =
lt->getPeerIpAdr(xlnk);
1184 if (!rs.leq(availRates)) {
1185 reply.
errMsg =
"add link: requested link "
1186 "exceeds interface capacity";
1187 reply.
mode = CtlPkt::NEG_REPLY;
1206 reply.
errMsg =
"add link: cannot add requested link";
1207 reply.
mode = CtlPkt::NEG_REPLY;
1219 reply.
errMsg =
"add link: cannot add link using "
1220 "specified address";
1221 reply.
mode = CtlPkt::NEG_REPLY;
1228 lt->setIface(lnk,iface);
1229 lt->setPeerType(lnk,peerType);
1230 lt->setConnectStatus(lnk,
false);
1231 sm->clearLnkStats(lnk);
1232 if (peerType ==
Forest::ROUTER && cp.ip1 != 0 && cp.port1 != 0) {
1238 reply.adr1 =
lt->getPeerAdr(lnk);
1243 dropLink(cp.
link, cp.adr1);
1255 void RouterCore::dropLink(
int lnk,
fAdr_t peerAdr) {
1256 if (lnk == 0) lnk =
lt->
lookup(peerAdr);
1257 int *comtVec =
new int[
lt->getComtSet(lnk).size()];
1259 for (
int comt :
lt->getComtSet(lnk)) comtVec[i++] = comt;
1261 int ctx = comtVec[i];
1263 dropComtreeLink(ctx,lnk,cLnk);
1265 int iface =
lt->getIface(lnk);
1266 ift->getAvailRates(iface).add(
lt->getRates(lnk));
1275 reply.
iface =
lt->getIface(link);
1276 reply.ip1 =
lt->getPeerIpAdr(link);
1278 reply.port1 =
lt->getPeerPort(link);
1279 reply.adr1 =
lt->getPeerAdr(link);
1280 reply.rspec1 =
lt->getRates(link);
1281 reply.
rspec2 =
lt->getAvailRates(link);
1284 reply.
errMsg =
"get link: invalid link number";
1285 reply.
mode = CtlPkt::NEG_REPLY;
1292 reply.
errMsg =
"get link: invalid link number";
1293 reply.
mode = CtlPkt::NEG_REPLY;
1297 int iface =
lt->getIface(link);
1298 if (cp.rspec1.isSet()) {
1303 if (!delta.
leq(ifAvail)) {
1305 reply.
errMsg =
"mod link: request "
1307 "exceeds interface capacity";
1308 reply.
mode = CtlPkt::NEG_REPLY;
1312 linkRates = cp.rspec1;
1313 qm->setLinkRates(link,cp.rspec1);
1314 cp.rspec1.
scale(.9);
1315 lt->getAvailRates(link) = cp.rspec1;
1320 bool RouterCore::addComtree(
CtlPkt& cp,
CtlPkt& reply) {
1324 reply.
errMsg =
"add comtree: cannot add comtree";
1325 reply.
mode = CtlPkt::NEG_REPLY;
1329 bool RouterCore::dropComtree(
CtlPkt& cp,
CtlPkt& reply) {
1337 rt->purgeRoutes(comt);
1343 set<int>::iterator pp;
1344 int *clnks =
new int[linkSet.size()];
int i = 0;
1345 for (pp = linkSet.begin(); pp != linkSet.end(); pp++) clnks[i++] = *pp;
1347 dropComtreeLink(ctx,
ctt->
getLink(clnks[i]),clnks[i]);
1355 bool RouterCore::getComtree(
CtlPkt& cp,
CtlPkt& reply) {
1359 reply.
errMsg =
"get comtree: invalid comtree";
1360 reply.
mode = CtlPkt::NEG_REPLY;
1370 bool RouterCore::modComtree(
CtlPkt& cp,
CtlPkt& reply) {
1378 if (plnk != 0 && !
ctt->
isLink(ctx,plnk)) {
1379 reply.
errMsg =
"specified link does "
1380 "not belong to comtree";
1381 reply.
mode = CtlPkt::NEG_REPLY;
1385 reply.
errMsg =
"specified link does "
1386 "not connect to a router";
1387 reply.
mode = CtlPkt::NEG_REPLY;
1394 reply.
errMsg =
"modify comtree: invalid comtree";
1395 reply.
mode = CtlPkt::NEG_REPLY;
1399 bool RouterCore::addComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1403 reply.
errMsg =
"add comtree link: invalid comtree";
1404 reply.
mode = CtlPkt::NEG_REPLY;
1410 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1411 lnk =
lt->
lookup(cp.ip1, cp.port1);
1412 }
else if (cp.adr1 != 0) {
1416 reply.
errMsg =
"add comtree link: invalid link or "
1418 reply.
mode = CtlPkt::NEG_REPLY;
1422 bool isCore =
false;
1425 reply.
errMsg =
"add comtree link: must specify "
1426 "core flag on links to routers";
1427 reply.
mode = CtlPkt::NEG_REPLY;
1439 reply.
errMsg =
"add comtree link: specified "
1440 "link already in comtree";
1441 reply.
mode = CtlPkt::NEG_REPLY;
1447 reply.
errMsg =
"add comtree link: cannot add "
1448 "requested comtree link";
1449 reply.
mode = CtlPkt::NEG_REPLY;
1456 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1458 int rtx =
rt->getRteIndex(comt,peerAdr);
1459 if (rtx == 0)
rt->addEntry(comt,peerAdr,cLnk);
1464 int rtx =
rt->getRteIndex(comt,dest);
1465 if (rtx == 0)
rt->addEntry(comt,dest,cLnk);
1473 reply.
errMsg =
"add comtree link: no queues "
1474 "available for link";
1475 reply.
mode = CtlPkt::NEG_REPLY;
1483 if (!minRates.leq(
lt->getAvailRates(lnk))) {
1484 reply.
errMsg =
"add comtree link: request "
1485 "exceeds link capacity";
1486 reply.
mode = CtlPkt::NEG_REPLY;
1489 lt->getAvailRates(lnk).subtract(minRates);
1492 qm->setQRates(qid,minRates);
1493 if (isRtr)
qm->setQLimits(qid,500,1000000);
1494 else qm->setQLimits(qid,500,1000000);
1495 sm->clearQuStats(qid);
1500 bool RouterCore::dropComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1504 reply.
errMsg =
"drop comtree link: invalid comtree";
1505 reply.
mode = CtlPkt::NEG_REPLY;
1511 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1512 lnk =
lt->
lookup(cp.ip1, cp.port1);
1513 }
else if (cp.adr1 != 0) {
1517 reply.
errMsg =
"drop comtree link: invalid link "
1518 "or peer IP and port";
1519 reply.
mode = CtlPkt::NEG_REPLY;
1524 dropComtreeLink(ctx,lnk,cLnk);
1529 void RouterCore::dropComtreeLink(
int ctx,
int lnk,
int cLnk) {
1534 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1537 int rtx =
rt->getRteIndex(comt,peerAdr);
1538 if (rtx != 0)
rt->removeEntry(rtx);
1543 int rtx =
rt->getRteIndex(comt,dest);
1544 if (rtx != 0)
rt->removeEntry(rtx);
1554 set<int>::iterator rp;
1555 int *routes =
new int[rteSet.size()];
1557 for (rp = rteSet.begin(); rp != rteSet.end(); rp++) routes[i++] = *rp;
1566 cerr <<
"dropComtreeLink: internal error detected "
1567 "final removeLink failed\n";
1571 bool RouterCore::modComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1575 reply.
errMsg =
"modify comtree link: invalid comtree";
1576 reply.
mode = CtlPkt::NEG_REPLY;
1581 reply.
errMsg =
"modify comtree link: invalid link number";
1582 reply.
mode = CtlPkt::NEG_REPLY;
1587 reply.
errMsg =
"modify comtree link: specified link "
1588 "not defined in specified comtree";
1589 reply.
mode = CtlPkt::NEG_REPLY;
1594 if (!rs.isSet())
return true;
1596 if (!diff.
leq(
lt->getAvailRates(lnk))) {
1597 reply.
errMsg =
"modify comtree link: new rate spec "
1598 "exceeds available link capacity";
1601 lt->getAvailRates(lnk).subtract(diff);
1606 bool RouterCore::getComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1610 reply.
errMsg =
"get comtree link: invalid comtree";
1611 reply.
mode = CtlPkt::NEG_REPLY;
1616 reply.
errMsg =
"get comtree link: invalid link number";
1617 reply.
mode = CtlPkt::NEG_REPLY;
1622 reply.
errMsg =
"get comtree link: specified link "
1623 "not defined in specified comtree";
1624 reply.
mode = CtlPkt::NEG_REPLY;
1639 reply.
errMsg =
"comtree not defined at this router\n";
1640 reply.
mode = CtlPkt::NEG_REPLY;
1645 reply.
errMsg =
"invalid address\n";
1646 reply.
mode = CtlPkt::NEG_REPLY;
1651 int rtx =
rt->getRteIndex(comt,dest);
1657 reply.
errMsg =
"add route: requested route "
1658 "conflicts with existing route";
1659 reply.
mode = CtlPkt::NEG_REPLY;
1662 }
else if (
rt->addEntry(comt, dest, lnk)) {
1665 reply.
errMsg =
"add route: cannot add route";
1666 reply.
mode = CtlPkt::NEG_REPLY;
1670 bool RouterCore::dropRoute(
CtlPkt& cp,
CtlPkt& reply) {
1673 reply.
errMsg =
"comtree not defined at this router\n";
1674 reply.
mode = CtlPkt::NEG_REPLY;
1679 reply.
errMsg =
"invalid address\n";
1680 reply.
mode = CtlPkt::NEG_REPLY;
1683 int rtx =
rt->getRteIndex(comt,dest);
1684 rt->removeEntry(rtx);
1691 reply.
errMsg =
"comtree not defined at this router\n";
1692 reply.
mode = CtlPkt::NEG_REPLY;
1697 reply.
errMsg =
"invalid address\n";
1698 reply.
mode = CtlPkt::NEG_REPLY;
1701 int rtx =
rt->getRteIndex(comt,dest);
1713 reply.
errMsg =
"get route: no route for specified address";
1714 reply.
mode = CtlPkt::NEG_REPLY;
1723 reply.firstLinkNum = cp.firstLinkNum;
1724 reply.numOfLinks = cp.numOfLinks;
1725 cout <<
"RouterCore " << __FUNCTION__ << endl;
1732 reply.
errMsg =
"comtree not defined at this router\n";
1733 reply.
mode = CtlPkt::NEG_REPLY;
1738 reply.
errMsg =
"invalid address\n";
1739 reply.
mode = CtlPkt::NEG_REPLY;
1742 int rtx =
rt->getRteIndex(comt,dest);
1746 reply.
errMsg =
"modify route: cannot "
1747 "set link in multicast route";
1748 reply.
mode = CtlPkt::NEG_REPLY;
1755 reply.
errMsg =
"modify route: invalid route";
1756 reply.
mode = CtlPkt::NEG_REPLY;
1770 reply.
errMsg =
"attempting to set leaf address range when "
1772 reply.
mode = CtlPkt::NEG_REPLY;
1776 fAdr_t lastLeafAdr = cp.adr2;
1778 reply.
errMsg =
"request contained empty leaf address range";
1779 reply.
mode = CtlPkt::NEG_REPLY;
1793 uint64_t nonce =
lt->getNonce(lnk);
1795 p.
comtree = Forest::CONNECT_COMT;
1797 p.payload()[0] = htonl((
int) (nonce >> 32));
1798 p.payload()[1] = htonl((
int) (nonce & 0xffffffff));
1803 pair<uint64_t,CpInfo> cpp;
1804 cpp.first = 1; cpp.first <<= 63; cpp.first |= nonce;
1805 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
1811 cerr <<
"RouterCore::sendConnect: no packets left in packet "
1815 iop->send(copy,lnk);
1829 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
1836 cp.
mode = CtlPkt::REQUEST;
1839 if (cp.
pack() == 0) {
1840 cerr <<
"RouterCore::sendCpReq: control packet packing error\n";
1851 pair<uint64_t,CpInfo> cpp;
1853 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
1860 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
1880 map<uint64_t,CpInfo>::iterator pp;
1882 if (now < pp->second.timestamp + 1000000000)
continue;
1883 pktx px = pp->second.px;
1885 if (pp->second.nSent >= 3) {
1887 cerr <<
"RouterCore::resendCpReq: received no reply to "
1888 "control packet after three attempts\n"
1895 cout <<
"resending control packet\n" << p.
toString(s1);
1897 pp->second.timestamp =
now;
1901 cerr <<
"RouterCore::resendCpReq: no packets left in "
1907 }
else if (booting) {
1926 map<uint64_t,CpInfo>::iterator pp =
pending->find(cpr.
seqNum);
1939 case CtlPkt::CLIENT_CONNECT:
case CtlPkt::CLIENT_DISCONNECT:
1940 if (cpr.
mode == CtlPkt::NEG_REPLY) {
1941 cerr <<
"RouterCore::handleCpReply: got negative reply "
1942 "to a connect or disconnect request: "
1948 case CtlPkt::BOOT_ROUTER: {
1949 if (cpr.
mode == CtlPkt::NEG_REPLY) {
1950 cerr <<
"RouterCore::handleCpReply: got "
1951 "negative reply to a boot request: "
1955 if (booting && !
setup()) {
1956 cerr <<
"RouterCore::handleCpReply: setup failed after "
1957 "completion of boot phase\n";
1962 iop->closeBootSock();
1967 cerr <<
"RouterCore::handleCpReply: unexpected control packet "
1982 int paylen = cp.
pack();
1984 cerr <<
"RouterCore::returnToSender: control packet formatting "
1985 "error, zero payload length\n";
1988 p.
length = (Packet::OVERHEAD + paylen);