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");
559 uint64_t statsTime = 0;
561 int controlCount = 20;
566 finishTime *= 1000000000;
567 while (finishTime == 0 ||
now < finishTime) {
571 pktx px =
iop->receive();
580 }
else if (booting) {
600 while ((px =
qm->
deq(lnk,
now)) != 0) {
607 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);
951 uint32_t *pp = p.payload();
960 uint64_t seq = ntohl(pp[0]);
961 seq <<= 32; seq |= ntohl(pp[1]);
964 map<uint64_t,CpInfo>::iterator it =
pending->find(seq);
982 bool propagate =
false;
986 int addcnt = ntohl(pp[2]);
987 if (addcnt < 0 || addcnt > 350 ||
991 for (
int i = 3; i <= addcnt + 2; i++) {
994 rtx =
rt->getRteIndex(comt,addr);
996 rtx =
rt->addEntry(comt,addr,cLnk);
1004 int dropcnt = ntohl(pp[addcnt+3]);
1005 if (dropcnt < 0 || addcnt + dropcnt > 350 ||
1009 for (
int i = addcnt + 4; i <= addcnt + dropcnt + 3; i++) {
1010 addr = ntohl(pp[i]);
1012 rtx =
rt->getRteIndex(comt,addr);
1013 if (rtx == 0)
continue;
1016 rt->removeEntry(rtx);
1024 pair<uint64_t,CpInfo> cpp;
1026 pp[0] = htonl((uint32_t) (
seqNum >> 32));
1027 pp[1] = htonl((uint32_t) (
seqNum & 0xffffffff));
1033 cpp.second.px = px; cpp.second.nSent = 1;
1034 cpp.second.timestamp =
now;
1061 if (p.
srcAdr !=
lt->getPeerAdr(inLnk) ||
1065 uint64_t nonce = ntohl(p.payload()[0]);
1067 nonce |= ntohl(p.payload()[1]);
1068 if (nonce !=
lt->getNonce(inLnk)) {
ps->
free(px);
return; }
1070 uint64_t x = 1; x <<= 63; x |= nonce;
1080 lt->setConnectStatus(inLnk,
true);
1082 CtlPkt cp(CtlPkt::CLIENT_CONNECT,CtlPkt::REQUEST,0);
1087 lt->setConnectStatus(inLnk,
false);
1091 CtlPkt cp(CtlPkt::CLIENT_DISCONNECT,CtlPkt::REQUEST,0);
1100 iop->send(px,inLnk);
1117 cerr <<
"RouterCore::handleCtlPkt: misformatted control "
1119 cp.reset(cp.type,CtlPkt::NEG_REPLY,cp.seqNum);
1120 cp.mode = CtlPkt::NEG_REPLY;
1121 cp.errMsg =
"misformatted control packet";
1125 if (cp.mode != CtlPkt::REQUEST) {
1130 CtlPkt reply(cp.type,CtlPkt::POS_REPLY,cp.seqNum);
1135 case CtlPkt::ADD_IFACE:
addIface(cp,reply);
break;
1136 case CtlPkt::DROP_IFACE: dropIface(cp,reply);
break;
1137 case CtlPkt::GET_IFACE: getIface(cp,reply);
break;
1138 case CtlPkt::MOD_IFACE: modIface(cp,reply);
break;
1139 case CtlPkt::GET_IFACE_SET:
getIfaceSet(cp,reply);
break;
1142 case CtlPkt::ADD_LINK: addLink(cp,reply);
break;
1143 case CtlPkt::DROP_LINK: dropLink(cp,reply);
break;
1144 case CtlPkt::GET_LINK: getLink(cp,reply);
break;
1145 case CtlPkt::MOD_LINK: modLink(cp,reply);
break;
1146 case CtlPkt::GET_LINK_SET:
getLinkSet(cp,reply);
break;
1149 case CtlPkt::ADD_COMTREE: addComtree(cp,reply);
break;
1150 case CtlPkt::DROP_COMTREE: dropComtree(cp,reply);
break;
1151 case CtlPkt::GET_COMTREE: getComtree(cp,reply);
break;
1152 case CtlPkt::MOD_COMTREE: modComtree(cp,reply);
break;
1153 case CtlPkt::GET_COMTREE_SET:
getComtreeSet(cp,reply);
break;
1156 case CtlPkt::ADD_COMTREE_LINK: addComtreeLink(cp,reply);
break;
1157 case CtlPkt::DROP_COMTREE_LINK: dropComtreeLink(cp,reply);
break;
1158 case CtlPkt::GET_COMTREE_LINK: getComtreeLink(cp,reply);
break;
1159 case CtlPkt::MOD_COMTREE_LINK: modComtreeLink(cp,reply);
break;
1162 case CtlPkt::ADD_ROUTE: addRoute(cp,reply);
break;
1163 case CtlPkt::DROP_ROUTE: dropRoute(cp,reply);
break;
1164 case CtlPkt::GET_ROUTE: getRoute(cp,reply);
break;
1165 case CtlPkt::MOD_ROUTE: modRoute(cp,reply);
break;
1166 case CtlPkt::GET_ROUTE_SET:
getRouteSet(cp,reply);
break;
1169 case CtlPkt::ADD_FILTER:
addFilter(cp,reply);
break;
1170 case CtlPkt::DROP_FILTER: dropFilter(cp,reply);
break;
1171 case CtlPkt::GET_FILTER: getFilter(cp,reply);
break;
1172 case CtlPkt::MOD_FILTER: modFilter(cp,reply);
break;
1173 case CtlPkt::GET_FILTER_SET:
getFilterSet(cp,reply);
break;
1177 case CtlPkt::SET_LEAF_RANGE:
setLeafRange(cp,reply);
break;
1180 cerr <<
"unrecognized control packet type " << cp.type
1182 reply.
errMsg =
"invalid control packet for router";
1183 reply.
mode = CtlPkt::NEG_REPLY;
1204 int iface = cp.
iface;
1214 if (cp.
iface !=
ift->getIpAdr(iface) ||
1216 reply.
errMsg =
"add iface: requested interface "
1217 "conflicts with existing interface";
1218 reply.
mode = CtlPkt::NEG_REPLY;
1222 reply.ip1 =
ift->getIpAdr(iface);
1223 reply.port1 =
ift->getPort(iface);
1225 }
else if (!
ift->
addEntry(iface, cp.ip1, 0, rs)) {
1226 reply.
errMsg =
"add iface: cannot add interface";
1227 reply.
mode = CtlPkt::NEG_REPLY;
1230 reply.
errMsg =
"add iface: could not setup interface";
1231 reply.
mode = CtlPkt::NEG_REPLY;
1234 reply.ip1 =
ift->getIpAdr(iface);
1235 reply.port1 =
ift->getPort(iface);
1239 bool RouterCore::dropIface(
CtlPkt& cp,
CtlPkt& reply) {
1245 int iface = cp.
iface;
1247 reply.
iface = iface;
1248 reply.ip1 =
ift->getIpAdr(iface);
1249 reply.port1 =
ift->getPort(iface);
1250 reply.rspec1 =
ift->getRates(iface);
1251 reply.
rspec2 =
ift->getAvailRates(iface);
1254 reply.
errMsg =
"get iface: invalid interface";
1255 reply.
mode = CtlPkt::NEG_REPLY;
1260 int iface = cp.
iface;
1262 ift->getRates(iface) = cp.rspec1;
1265 reply.
errMsg =
"mod iface: invalid interface";
1266 reply.
mode = CtlPkt::NEG_REPLY;
1281 int ifIndex = cp.index1;
1285 reply.
errMsg =
"get iface set: invalid iface number";
1286 reply.
mode = CtlPkt::NEG_REPLY;
1289 reply.index1 = ifIndex;
1290 int count = min(10,cp.
count);
1292 while (i < count && ifIndex != 0) {
1296 reply.
errMsg =
"get iface set: error while formatting "
1298 reply.
mode = CtlPkt::NEG_REPLY;
1310 reply.
errMsg =
"add link: adding link to router, but no peer "
1312 reply.
mode = CtlPkt::NEG_REPLY;
1315 int iface = cp.
iface;
1317 int xlnk =
lt->
lookup(cp.ip1,cp.port1);
1319 if (cp.
link != xlnk ||
1320 (peerType !=
lt->getPeerType(xlnk)) ||
1321 (cp.
iface !=
lt->getIface(xlnk)) ||
1322 (cp.adr1 != 0 && cp.adr1 !=
lt->getPeerAdr(xlnk)) ||
1323 (cp.ip1 != 0 && cp.ip1 !=
ift->getIpAdr(iface)) ||
1324 (cp.port1 != 0 && cp.port1 !=
ift->getPort(iface))) {
1325 reply.
errMsg =
"add link: new link conflicts "
1326 "with existing link";
1327 reply.
mode = CtlPkt::NEG_REPLY;
1332 reply.adr1 =
lt->getPeerAdr(xlnk);
1333 reply.ip1 =
lt->getPeerIpAdr(xlnk);
1342 if (!rs.leq(availRates)) {
1343 reply.
errMsg =
"add link: requested link "
1344 "exceeds interface capacity";
1345 reply.
mode = CtlPkt::NEG_REPLY;
1364 reply.
errMsg =
"add link: cannot add requested link";
1365 reply.
mode = CtlPkt::NEG_REPLY;
1377 reply.
errMsg =
"add link: cannot add link using "
1378 "specified address";
1379 reply.
mode = CtlPkt::NEG_REPLY;
1386 lt->setIface(lnk,iface);
1387 lt->setPeerType(lnk,peerType);
1388 lt->setConnectStatus(lnk,
false);
1389 sm->clearLnkStats(lnk);
1390 if (peerType ==
Forest::ROUTER && cp.ip1 != 0 && cp.port1 != 0) {
1396 reply.adr1 =
lt->getPeerAdr(lnk);
1401 dropLink(cp.
link, cp.adr1);
1413 void RouterCore::dropLink(
int lnk,
fAdr_t peerAdr) {
1414 if (lnk == 0) lnk =
lt->
lookup(peerAdr);
1415 int *comtVec =
new int[
lt->getComtSet(lnk).size()];
1417 for (
int comt :
lt->getComtSet(lnk)) comtVec[i++] = comt;
1419 int ctx = comtVec[i];
1421 dropComtreeLink(ctx,lnk,cLnk);
1423 int iface =
lt->getIface(lnk);
1424 ift->getAvailRates(iface).add(
lt->getRates(lnk));
1433 reply.
iface =
lt->getIface(link);
1434 reply.ip1 =
lt->getPeerIpAdr(link);
1436 reply.port1 =
lt->getPeerPort(link);
1437 reply.adr1 =
lt->getPeerAdr(link);
1438 reply.rspec1 =
lt->getRates(link);
1439 reply.
rspec2 =
lt->getAvailRates(link);
1440 reply.
count =
lt->getComtCount(link);
1443 reply.
errMsg =
"get link: invalid link number";
1444 reply.
mode = CtlPkt::NEG_REPLY;
1459 int lnk = cp.index1;
1463 reply.
errMsg =
"get link set: invalid link number";
1464 reply.
mode = CtlPkt::NEG_REPLY;
1468 int count = min(10,cp.
count);
1470 while (i < count && lnk != 0) {
1474 reply.
errMsg =
"get link set: error while formatting "
1476 reply.
mode = CtlPkt::NEG_REPLY;
1488 reply.
errMsg =
"get link: invalid link number";
1489 reply.
mode = CtlPkt::NEG_REPLY;
1493 int iface =
lt->getIface(link);
1494 if (cp.rspec1.isSet()) {
1499 if (!delta.
leq(ifAvail)) {
1501 reply.
errMsg =
"mod link: request "
1503 "exceeds interface capacity";
1504 reply.
mode = CtlPkt::NEG_REPLY;
1508 linkRates = cp.rspec1;
1509 qm->setLinkRates(link,cp.rspec1);
1510 cp.rspec1.
scale(.9);
1511 lt->getAvailRates(link) = cp.rspec1;
1516 bool RouterCore::addComtree(
CtlPkt& cp,
CtlPkt& reply) {
1520 reply.
errMsg =
"add comtree: cannot add comtree";
1521 reply.
mode = CtlPkt::NEG_REPLY;
1525 bool RouterCore::dropComtree(
CtlPkt& cp,
CtlPkt& reply) {
1533 rt->purgeRoutes(comt);
1539 set<int>::iterator pp;
1540 int *clnks =
new int[linkSet.size()];
int i = 0;
1541 for (pp = linkSet.begin(); pp != linkSet.end(); pp++) clnks[i++] = *pp;
1543 dropComtreeLink(ctx,
ctt->
getLink(clnks[i]),clnks[i]);
1551 bool RouterCore::getComtree(
CtlPkt& cp,
CtlPkt& reply) {
1555 reply.
errMsg =
"get comtree: invalid comtree";
1556 reply.
mode = CtlPkt::NEG_REPLY;
1577 int comtIndex = cp.index1;
1578 if (comtIndex == 0) {
1581 reply.
errMsg =
"get comtree set: invalid comtree number";
1582 reply.
mode = CtlPkt::NEG_REPLY;
1585 reply.index1 = comtIndex;
1586 int count = min(10,cp.
count);
1588 while (i < count && comtIndex != 0) {
1592 reply.
errMsg =
"get comtee set: error while "
1594 reply.
mode = CtlPkt::NEG_REPLY;
1603 bool RouterCore::modComtree(
CtlPkt& cp,
CtlPkt& reply) {
1611 if (plnk != 0 && !
ctt->
isLink(ctx,plnk)) {
1612 reply.
errMsg =
"specified link does "
1613 "not belong to comtree";
1614 reply.
mode = CtlPkt::NEG_REPLY;
1618 reply.
errMsg =
"specified link does "
1619 "not connect to a router";
1620 reply.
mode = CtlPkt::NEG_REPLY;
1627 reply.
errMsg =
"modify comtree: invalid comtree";
1628 reply.
mode = CtlPkt::NEG_REPLY;
1632 bool RouterCore::addComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1636 reply.
errMsg =
"add comtree link: invalid comtree";
1637 reply.
mode = CtlPkt::NEG_REPLY;
1643 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1644 lnk =
lt->
lookup(cp.ip1, cp.port1);
1645 }
else if (cp.adr1 != 0) {
1649 reply.
errMsg =
"add comtree link: invalid link or "
1651 reply.
mode = CtlPkt::NEG_REPLY;
1655 bool isCore =
false;
1658 reply.
errMsg =
"add comtree link: must specify "
1659 "core flag on links to routers";
1660 reply.
mode = CtlPkt::NEG_REPLY;
1672 reply.
errMsg =
"add comtree link: specified "
1673 "link already in comtree";
1674 reply.
mode = CtlPkt::NEG_REPLY;
1680 reply.
errMsg =
"add comtree link: cannot add "
1681 "requested comtree link";
1682 reply.
mode = CtlPkt::NEG_REPLY;
1689 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1691 int rtx =
rt->getRteIndex(comt,peerAdr);
1692 if (rtx == 0)
rt->addEntry(comt,peerAdr,cLnk);
1697 int rtx =
rt->getRteIndex(comt,dest);
1698 if (rtx == 0)
rt->addEntry(comt,dest,cLnk);
1706 reply.
errMsg =
"add comtree link: no queues "
1707 "available for link";
1708 reply.
mode = CtlPkt::NEG_REPLY;
1716 if (!minRates.leq(
lt->getAvailRates(lnk))) {
1717 reply.
errMsg =
"add comtree link: request "
1718 "exceeds link capacity";
1719 reply.
mode = CtlPkt::NEG_REPLY;
1722 lt->getAvailRates(lnk).subtract(minRates);
1725 qm->setQRates(qid,minRates);
1726 if (isRtr)
qm->setQLimits(qid,500,1000000);
1727 else qm->setQLimits(qid,500,1000000);
1728 sm->clearQuStats(qid);
1733 bool RouterCore::dropComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1737 reply.
errMsg =
"drop comtree link: invalid comtree";
1738 reply.
mode = CtlPkt::NEG_REPLY;
1744 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1745 lnk =
lt->
lookup(cp.ip1, cp.port1);
1746 }
else if (cp.adr1 != 0) {
1750 reply.
errMsg =
"drop comtree link: invalid link "
1751 "or peer IP and port";
1752 reply.
mode = CtlPkt::NEG_REPLY;
1757 dropComtreeLink(ctx,lnk,cLnk);
1762 void RouterCore::dropComtreeLink(
int ctx,
int lnk,
int cLnk) {
1767 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1770 int rtx =
rt->getRteIndex(comt,peerAdr);
1771 if (rtx != 0)
rt->removeEntry(rtx);
1776 int rtx =
rt->getRteIndex(comt,dest);
1777 if (rtx != 0)
rt->removeEntry(rtx);
1787 set<int>::iterator rp;
1788 int *routes =
new int[rteSet.size()];
1790 for (rp = rteSet.begin(); rp != rteSet.end(); rp++) routes[i++] = *rp;
1799 cerr <<
"dropComtreeLink: internal error detected "
1800 "final removeLink failed\n";
1804 bool RouterCore::modComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1808 reply.
errMsg =
"modify comtree link: invalid comtree";
1809 reply.
mode = CtlPkt::NEG_REPLY;
1814 reply.
errMsg =
"modify comtree link: invalid link number";
1815 reply.
mode = CtlPkt::NEG_REPLY;
1820 reply.
errMsg =
"modify comtree link: specified link "
1821 "not defined in specified comtree";
1822 reply.
mode = CtlPkt::NEG_REPLY;
1827 if (!rs.isSet())
return true;
1829 if (!diff.
leq(
lt->getAvailRates(lnk))) {
1830 reply.
errMsg =
"modify comtree link: new rate spec "
1831 "exceeds available link capacity";
1834 lt->getAvailRates(lnk).subtract(diff);
1839 bool RouterCore::getComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1843 reply.
errMsg =
"get comtree link: invalid comtree";
1844 reply.
mode = CtlPkt::NEG_REPLY;
1849 reply.
errMsg =
"get comtree link: invalid link number";
1850 reply.
mode = CtlPkt::NEG_REPLY;
1855 reply.
errMsg =
"get comtree link: specified link "
1856 "not defined in specified comtree";
1857 reply.
mode = CtlPkt::NEG_REPLY;
1872 reply.
errMsg =
"comtree not defined at this router\n";
1873 reply.
mode = CtlPkt::NEG_REPLY;
1878 reply.
errMsg =
"invalid address\n";
1879 reply.
mode = CtlPkt::NEG_REPLY;
1884 int rtx =
rt->getRteIndex(comt,dest);
1890 reply.
errMsg =
"add route: requested route "
1891 "conflicts with existing route";
1892 reply.
mode = CtlPkt::NEG_REPLY;
1895 }
else if (
rt->addEntry(comt, dest, lnk)) {
1898 reply.
errMsg =
"add route: cannot add route";
1899 reply.
mode = CtlPkt::NEG_REPLY;
1903 bool RouterCore::dropRoute(
CtlPkt& cp,
CtlPkt& reply) {
1906 reply.
errMsg =
"comtree not defined at this router\n";
1907 reply.
mode = CtlPkt::NEG_REPLY;
1912 reply.
errMsg =
"invalid address\n";
1913 reply.
mode = CtlPkt::NEG_REPLY;
1916 int rtx =
rt->getRteIndex(comt,dest);
1917 rt->removeEntry(rtx);
1924 reply.
errMsg =
"comtree not defined at this router\n";
1925 reply.
mode = CtlPkt::NEG_REPLY;
1930 reply.
errMsg =
"invalid address\n";
1931 reply.
mode = CtlPkt::NEG_REPLY;
1934 int rtx =
rt->getRteIndex(comt,dest);
1946 reply.
errMsg =
"get route: no route for specified address";
1947 reply.
mode = CtlPkt::NEG_REPLY;
1954 reply.
errMsg =
"comtree not defined at this router\n";
1955 reply.
mode = CtlPkt::NEG_REPLY;
1960 reply.
errMsg =
"invalid address\n";
1961 reply.
mode = CtlPkt::NEG_REPLY;
1964 int rtx =
rt->getRteIndex(comt,dest);
1968 reply.
errMsg =
"modify route: cannot "
1969 "set link in multicast route";
1970 reply.
mode = CtlPkt::NEG_REPLY;
1977 reply.
errMsg =
"modify route: invalid route";
1978 reply.
mode = CtlPkt::NEG_REPLY;
1993 int rIndex = cp.index1;
1995 rIndex =
rt->firstRteIndex();
1996 }
else if (!
rt->validRteIndex(rIndex)) {
1997 reply.
errMsg =
"get route set: invalid route number";
1998 reply.
mode = CtlPkt::NEG_REPLY;
2001 reply.index1 = rIndex;
2002 int count = min(10,cp.
count);
2004 while (i < count && rIndex != 0) {
2008 reply.
errMsg =
"get route set: error while formatting "
2010 reply.
mode = CtlPkt::NEG_REPLY;
2013 i++; rIndex =
rt->nextRteIndex(rIndex);
2032 reply.
errMsg =
"add filter: cannot add filter";
2033 reply.
mode = CtlPkt::NEG_REPLY;
2040 bool RouterCore::dropFilter(
CtlPkt& cp,
CtlPkt& reply) {
2045 bool RouterCore::getFilter(
CtlPkt& cp,
CtlPkt& reply) {
2046 fltx fx = cp.index1;
2047 if (!
pktLog->validFilter(fx)) {
2048 reply.
errMsg =
"get filter: invalid filter index";
2049 reply.
mode = CtlPkt::NEG_REPLY;
2057 bool RouterCore::modFilter(
CtlPkt& cp,
CtlPkt& reply) {
2058 fltx fx = cp.index1;
2059 if (!
pktLog->validFilter(fx)) {
2060 reply.
errMsg =
"mod filter: invalid filter index";
2061 reply.
mode = CtlPkt::NEG_REPLY;
2080 fltx fx = cp.index1;
2082 fx =
pktLog->firstFilter();
2083 }
else if (!
pktLog->validFilter(fx)) {
2084 reply.
errMsg =
"get filter set: invalid filter index";
2085 reply.
mode = CtlPkt::NEG_REPLY;
2089 int count = min(10,cp.
count);
2091 while (i < count && fx != 0) {
2098 reply.
errMsg =
"get filter set: error while "
2100 reply.
mode = CtlPkt::NEG_REPLY;
2103 i++; fx =
pktLog->nextFilter(fx);
2130 reply.
errMsg =
"attempting to set leaf address range when "
2132 reply.
mode = CtlPkt::NEG_REPLY;
2136 fAdr_t lastLeafAdr = cp.adr2;
2138 reply.
errMsg =
"request contained empty leaf address range";
2139 reply.
mode = CtlPkt::NEG_REPLY;
2153 uint64_t nonce =
lt->getNonce(lnk);
2155 p.
comtree = Forest::CONNECT_COMT;
2157 p.payload()[0] = htonl((
int) (nonce >> 32));
2158 p.payload()[1] = htonl((
int) (nonce & 0xffffffff));
2163 pair<uint64_t,CpInfo> cpp;
2164 cpp.first = 1; cpp.first <<= 63; cpp.first |= nonce;
2165 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
2171 cerr <<
"RouterCore::sendConnect: no packets left in packet "
2176 iop->send(copy,lnk);
2190 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
2197 cp.
mode = CtlPkt::REQUEST;
2200 if (cp.
pack() == 0) {
2201 cerr <<
"RouterCore::sendCpReq: control packet packing error\n";
2212 pair<uint64_t,CpInfo> cpp;
2214 cpp.second.px = px; cpp.second.nSent = 1; cpp.second.timestamp =
now;
2221 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
2241 map<uint64_t,CpInfo>::iterator pp;
2243 if (now < pp->second.timestamp + 1000000000)
continue;
2244 pktx px = pp->second.px;
2246 if (pp->second.nSent >= 3) {
2248 cerr <<
"RouterCore::resendCpReq: received no reply to "
2249 "control packet after three attempts\n"
2256 cout <<
"resending control packet\n" << p.
toString(s1);
2258 pp->second.timestamp =
now;
2262 cerr <<
"RouterCore::resendCpReq: no packets left in "
2269 }
else if (booting) {
2288 map<uint64_t,CpInfo>::iterator pp =
pending->find(cpr.
seqNum);
2301 case CtlPkt::CLIENT_CONNECT:
case CtlPkt::CLIENT_DISCONNECT:
2302 if (cpr.
mode == CtlPkt::NEG_REPLY) {
2303 cerr <<
"RouterCore::handleCpReply: got negative reply "
2304 "to a connect or disconnect request: "
2310 case CtlPkt::BOOT_ROUTER: {
2311 if (cpr.
mode == CtlPkt::NEG_REPLY) {
2312 cerr <<
"RouterCore::handleCpReply: got "
2313 "negative reply to a boot request: "
2317 if (booting && !
setup()) {
2318 cerr <<
"RouterCore::handleCpReply: setup failed after "
2319 "completion of boot phase\n";
2324 iop->closeBootSock();
2329 cerr <<
"RouterCore::handleCpReply: unexpected control packet "
2344 int paylen = cp.
pack();
2346 cerr <<
"RouterCore::returnToSender: control packet formatting "
2347 "error, zero payload length\n";
2350 p.
length = (Packet::OVERHEAD + paylen);