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;
99 fatal(
"router: could not read specified config files");
102 fatal(
"router: inconsistency in config files");
118 : booting(booting1) {
119 nIfaces = 50; nLnks = 1000;
120 nComts = 5000; nRts = 100000;
121 nPkts = 100000; nBufs = 50000; nQus = 10000;
127 ccAdr = config.
ccAdr;
137 qm =
new QuManager(nLnks, nPkts, nQus, min(50,5*nPkts/nLnks), ps, sm);
141 leafAdr =
new UiSetPair((config.
lastLeafAdr - firstLeafAdr)+1);
144 pending =
new map<uint64_t,ControlInfo>();
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();
601 while ((px =
qm->
deq(lnk,
now)) != 0) {
608 if (!ctlQ.empty() && (didNothing || --controlCount <= 0)) {
618 if (
now - statsTime > 300000000) {
633 cout <<
sm->iPktCnt(0) <<
" packets received, "
634 <<
sm->oPktCnt(0) <<
" packets sent\n";
635 cout <<
sm->iPktCnt(-1) <<
" from routers, "
636 <<
sm->oPktCnt(-1) <<
" to routers\n";
637 cout <<
sm->iPktCnt(-2) <<
" from clients, "
638 <<
sm->oPktCnt(-2) <<
" to clients\n";
671 if (inLink == 0)
return false;
680 if (
lt->getPeerAdr(inLink) != p.
srcAdr)
return false;
693 comt != (
int) Forest::CONNECT_COMT)
723 int rcLnk =
rt->getLink(rtx);
756 int qvec[
nLnks];
int n = 0;
765 set<int>::iterator lp;
766 for (lp = rtrLinks.begin(); lp != rtrLinks.end(); lp++) {
767 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
769 if (pZip == myZip && peerZip != myZip)
continue;
770 if (lnk == inLink)
continue;
778 set<int>::iterator lp;
779 for (lp = coreLinks.begin(); lp != coreLinks.end(); lp++) {
780 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
781 if (lnk == inLink || lnk == pLink)
continue;
785 if (pLink != 0 && pLink != inLink) {
790 set<int>& subLinks =
rt->getSubLinks(rtx);
791 for (lp = subLinks.begin(); lp !=subLinks.end(); lp++) {
792 int rcLnk = *lp;
int lnk =
ctt->
getLink(rcLnk);
793 if (lnk == inLink)
continue;
799 if (n == 0) {
ps->
free(px);
return; }
803 for (
int i = 0; i < n-1; i++) {
833 (p1.payload())[0] = htonl(p.
dstAdr);
854 int adr = ntohl((p.payload())[0]);
866 int dcLnk =
rt->getLink(rtx);
int dLnk =
ctt->
getLink(dcLnk);
881 uint32_t *pp = p.payload();
903 bool propagate =
false;
907 int addcnt = ntohl(pp[2]);
908 if (addcnt < 0 || addcnt > 350 ||
912 for (
int i = 3; i <= addcnt + 2; i++) {
915 rtx =
rt->getRteIndex(comt,addr);
917 rtx =
rt->addEntry(comt,addr,cLnk);
925 int dropcnt = ntohl(pp[addcnt+3]);
926 if (dropcnt < 0 || addcnt + dropcnt > 350 ||
930 for (
int i = addcnt + 4; i <= addcnt + dropcnt + 3; i++) {
933 rtx =
rt->getRteIndex(comt,addr);
934 if (rtx == 0)
continue;
937 rt->removeEntry(rtx);
945 pp[0] = htonl((uint32_t) (
seqNum >> 32));
946 pp[1] = htonl((uint32_t) (
seqNum & 0xffffffff));
971 if (p.
srcAdr !=
lt->getPeerAdr(inLnk) ||
976 uint64_t nonce = ntohl(p.payload()[0]);
977 nonce <<= 32; nonce |= ntohl(p.payload()[1]);
978 if (nonce !=
lt->getNonce(inLnk)) {
ps->
free(px);
return; }
989 lt->setConnectStatus(inLnk,
true);
991 CtlPkt cp(CtlPkt::CLIENT_CONNECT,CtlPkt::REQUEST,0);
996 lt->setConnectStatus(inLnk,
false);
1000 CtlPkt cp(CtlPkt::CLIENT_DISCONNECT,CtlPkt::REQUEST,0);
1025 cerr <<
"RouterCore::handleCtlPkt: misformatted control "
1027 cp.reset(cp.type,CtlPkt::NEG_REPLY,cp.seqNum);
1028 cp.mode = CtlPkt::NEG_REPLY;
1029 cp.errMsg =
"misformatted control packet";
1033 if (cp.mode != CtlPkt::REQUEST) {
1038 CtlPkt reply(cp.type,CtlPkt::POS_REPLY,cp.seqNum);
1043 case CtlPkt::ADD_IFACE:
addIface(cp,reply);
break;
1044 case CtlPkt::DROP_IFACE: dropIface(cp,reply);
break;
1045 case CtlPkt::GET_IFACE: getIface(cp,reply);
break;
1046 case CtlPkt::MOD_IFACE: modIface(cp,reply);
break;
1047 case CtlPkt::GET_IFACE_SET:
getIfaceSet(cp,reply);
break;
1050 case CtlPkt::ADD_LINK: addLink(cp,reply);
break;
1051 case CtlPkt::DROP_LINK: dropLink(cp,reply);
break;
1052 case CtlPkt::GET_LINK: getLink(cp,reply);
break;
1053 case CtlPkt::MOD_LINK: modLink(cp,reply);
break;
1054 case CtlPkt::GET_LINK_SET:
getLinkSet(cp,reply);
break;
1057 case CtlPkt::ADD_COMTREE: addComtree(cp,reply);
break;
1058 case CtlPkt::DROP_COMTREE: dropComtree(cp,reply);
break;
1059 case CtlPkt::GET_COMTREE: getComtree(cp,reply);
break;
1060 case CtlPkt::MOD_COMTREE: modComtree(cp,reply);
break;
1061 case CtlPkt::GET_COMTREE_SET:
getComtreeSet(cp,reply);
break;
1063 case CtlPkt::ADD_COMTREE_LINK: addComtreeLink(cp,reply);
break;
1064 case CtlPkt::DROP_COMTREE_LINK: dropComtreeLink(cp,reply);
break;
1065 case CtlPkt::GET_COMTREE_LINK: getComtreeLink(cp,reply);
break;
1066 case CtlPkt::MOD_COMTREE_LINK: modComtreeLink(cp,reply);
break;
1069 case CtlPkt::ADD_ROUTE: addRoute(cp,reply);
break;
1070 case CtlPkt::DROP_ROUTE: dropRoute(cp,reply);
break;
1071 case CtlPkt::GET_ROUTE: getRoute(cp,reply);
break;
1072 case CtlPkt::MOD_ROUTE: modRoute(cp,reply);
break;
1073 case CtlPkt::GET_ROUTE_SET:
getRouteSet(cp,reply);
break;
1076 case CtlPkt::ADD_FILTER:
addFilter(cp,reply);
break;
1077 case CtlPkt::DROP_FILTER: dropFilter(cp,reply);
break;
1078 case CtlPkt::GET_FILTER: getFilter(cp,reply);
break;
1079 case CtlPkt::MOD_FILTER: modFilter(cp,reply);
break;
1080 case CtlPkt::GET_FILTER_SET:
getFilterSet(cp,reply);
break;
1085 case CtlPkt::SET_LEAF_RANGE:
setLeafRange(cp,reply);
break;
1088 cerr <<
"unrecognized control packet type " << cp.type
1090 reply.errMsg =
"invalid control packet for router";
1091 reply.mode = CtlPkt::NEG_REPLY;
1112 int iface = cp.
iface;
1122 if (cp.
iface !=
ift->getIpAdr(iface) ||
1123 !rs.equals(
ift->getRates(iface))) {
1124 reply.
errMsg =
"add iface: requested interface "
1125 "conflicts with existing interface";
1126 reply.
mode = CtlPkt::NEG_REPLY;
1130 reply.ip1 =
ift->getIpAdr(iface);
1131 reply.port1 =
ift->getPort(iface);
1133 }
else if (!
ift->
addEntry(iface, cp.ip1, 0, rs)) {
1134 reply.
errMsg =
"add iface: cannot add interface";
1135 reply.
mode = CtlPkt::NEG_REPLY;
1138 reply.
errMsg =
"add iface: could not setup interface";
1139 reply.
mode = CtlPkt::NEG_REPLY;
1142 reply.ip1 =
ift->getIpAdr(iface);
1143 reply.port1 =
ift->getPort(iface);
1147 bool RouterCore::dropIface(
CtlPkt& cp,
CtlPkt& reply) {
1153 int iface = cp.
iface;
1155 reply.
iface = iface;
1156 reply.ip1 =
ift->getIpAdr(iface);
1157 reply.port1 =
ift->getPort(iface);
1158 reply.rspec1 =
ift->getRates(iface);
1159 reply.
rspec2 =
ift->getAvailRates(iface);
1162 reply.
errMsg =
"get iface: invalid interface";
1163 reply.
mode = CtlPkt::NEG_REPLY;
1168 int iface = cp.
iface;
1170 ift->getRates(iface) = cp.rspec1;
1173 reply.
errMsg =
"mod iface: invalid interface";
1174 reply.
mode = CtlPkt::NEG_REPLY;
1189 int ifIndex = cp.index1;
1192 reply.
errMsg =
"get iface set: invalid iface number";
1193 reply.
mode = CtlPkt::NEG_REPLY;
1196 reply.index1 = ifIndex;
1197 int count = min(10,cp.
count);
1199 string s; stringstream ss;
1200 while (i < count && ifIndex != 0) {
1201 ss.str(
""); ss.clear(); ss << ifIndex <<
" ";
1206 reply.
errMsg =
"get iface set: error while formatting "
1208 reply.
mode = CtlPkt::NEG_REPLY;
1220 reply.
errMsg =
"add link: adding link to router, but no peer "
1222 reply.
mode = CtlPkt::NEG_REPLY;
1225 int iface = cp.
iface;
1227 int xlnk =
lt->
lookup(cp.ip1,cp.port1);
1229 if (cp.
link != xlnk ||
1230 (peerType !=
lt->getPeerType(xlnk)) ||
1231 (cp.
iface !=
lt->getIface(xlnk)) ||
1232 (cp.adr1 != 0 && cp.adr1 !=
lt->getPeerAdr(xlnk)) ||
1233 (cp.ip1 != 0 && cp.ip1 !=
ift->getIpAdr(iface)) ||
1234 (cp.port1 != 0 && cp.port1 !=
ift->getPort(iface))) {
1235 reply.
errMsg =
"add link: new link conflicts "
1236 "with existing link";
1237 reply.
mode = CtlPkt::NEG_REPLY;
1242 reply.adr1 =
lt->getPeerAdr(xlnk);
1243 reply.ip1 =
lt->getPeerIpAdr(xlnk);
1252 if (!rs.leq(availRates)) {
1253 reply.
errMsg =
"add link: requested link "
1254 "exceeds interface capacity";
1255 reply.
mode = CtlPkt::NEG_REPLY;
1274 reply.
errMsg =
"add link: cannot add requested link";
1275 reply.
mode = CtlPkt::NEG_REPLY;
1287 reply.
errMsg =
"add link: cannot add link using "
1288 "specified address";
1289 reply.
mode = CtlPkt::NEG_REPLY;
1296 lt->setIface(lnk,iface);
1297 lt->setPeerType(lnk,peerType);
1298 lt->setConnectStatus(lnk,
false);
1299 sm->clearLnkStats(lnk);
1300 if (peerType ==
Forest::ROUTER && cp.ip1 != 0 && cp.port1 != 0) {
1306 reply.adr1 =
lt->getPeerAdr(lnk);
1311 dropLink(cp.
link, cp.adr1);
1323 void RouterCore::dropLink(
int lnk,
fAdr_t peerAdr) {
1324 if (lnk == 0) lnk =
lt->
lookup(peerAdr);
1325 int *comtVec =
new int[
lt->getComtSet(lnk).size()];
1327 for (
int comt :
lt->getComtSet(lnk)) comtVec[i++] = comt;
1329 int ctx = comtVec[i];
1331 dropComtreeLink(ctx,lnk,cLnk);
1333 int iface =
lt->getIface(lnk);
1334 ift->getAvailRates(iface).add(
lt->getRates(lnk));
1343 reply.
iface =
lt->getIface(link);
1344 reply.ip1 =
lt->getPeerIpAdr(link);
1346 reply.port1 =
lt->getPeerPort(link);
1347 reply.adr1 =
lt->getPeerAdr(link);
1348 reply.rspec1 =
lt->getRates(link);
1349 reply.
rspec2 =
lt->getAvailRates(link);
1350 reply.
count =
lt->getComtCount(link);
1353 reply.
errMsg =
"get link: invalid link number";
1354 reply.
mode = CtlPkt::NEG_REPLY;
1369 int lnk = cp.index1;
1372 reply.
errMsg =
"get link set: invalid link number";
1373 reply.
mode = CtlPkt::NEG_REPLY;
1377 int count = min(10,cp.
count);
1379 string s; stringstream ss;
1380 while (i < count && lnk != 0) {
1381 ss.str(
""); ss.clear(); ss << lnk <<
" ";
1386 reply.
errMsg =
"get link set: error while formatting "
1388 reply.
mode = CtlPkt::NEG_REPLY;
1401 reply.
errMsg =
"get link: invalid link number";
1402 reply.
mode = CtlPkt::NEG_REPLY;
1406 int iface =
lt->getIface(link);
1407 if (cp.rspec1.isSet()) {
1412 if (!delta.
leq(ifAvail)) {
1414 reply.
errMsg =
"mod link: request "
1416 "exceeds interface capacity";
1417 reply.
mode = CtlPkt::NEG_REPLY;
1421 linkRates = cp.rspec1;
1422 lt->getAvailRates(link).add(delta);
1423 qm->setLinkRates(link,cp.rspec1);
1428 bool RouterCore::addComtree(
CtlPkt& cp,
CtlPkt& reply) {
1432 reply.
errMsg =
"add comtree: cannot add comtree";
1433 reply.
mode = CtlPkt::NEG_REPLY;
1437 bool RouterCore::dropComtree(
CtlPkt& cp,
CtlPkt& reply) {
1446 rt->purgeRoutes(comt);
1452 set<int>::iterator pp;
1453 int *clnks =
new int[linkSet.size()];
int i = 0;
1454 for (pp = linkSet.begin(); pp != linkSet.end(); pp++) clnks[i++] = *pp;
1456 dropComtreeLink(ctx,
ctt->
getLink(clnks[i]),clnks[i]);
1461 if (plink != 0) reply.rspec1 =
lt->getAvailRates(plink);
1462 else reply.rspec1.
set(0);
1466 bool RouterCore::getComtree(
CtlPkt& cp,
CtlPkt& reply) {
1470 reply.
errMsg =
"get comtree: invalid comtree";
1471 reply.
mode = CtlPkt::NEG_REPLY;
1481 bool RouterCore::modComtree(
CtlPkt& cp,
CtlPkt& reply) {
1489 if (plnk != 0 && !
ctt->
isLink(ctx,plnk)) {
1490 reply.
errMsg =
"specified link does "
1491 "not belong to comtree";
1492 reply.
mode = CtlPkt::NEG_REPLY;
1496 reply.
errMsg =
"specified link does "
1497 "not connect to a router";
1498 reply.
mode = CtlPkt::NEG_REPLY;
1505 reply.
errMsg =
"modify comtree: invalid comtree";
1506 reply.
mode = CtlPkt::NEG_REPLY;
1521 int comtIndex = cp.index1;
1524 reply.
errMsg =
"get comtree set: invalid comtree number";
1525 reply.
mode = CtlPkt::NEG_REPLY;
1528 reply.index1 = comtIndex;
1529 int count = min(10,cp.
count);
1531 while (i < count && comtIndex != 0) {
1535 reply.
errMsg =
"get comtee set: error while formatting "
1537 reply.
mode = CtlPkt::NEG_REPLY;
1546 bool RouterCore::addComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1550 reply.
errMsg =
"add comtree link: invalid comtree";
1551 reply.
mode = CtlPkt::NEG_REPLY;
1557 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1558 lnk =
lt->
lookup(cp.ip1, cp.port1);
1559 }
else if (cp.adr1 != 0) {
1563 reply.
errMsg =
"add comtree link: invalid link or "
1565 reply.
mode = CtlPkt::NEG_REPLY;
1569 bool isCore =
false;
1572 reply.
errMsg =
"add comtree link: must specify "
1573 "core flag on links to routers";
1574 reply.
mode = CtlPkt::NEG_REPLY;
1586 reply.
errMsg =
"add comtree link: specified "
1587 "link already in comtree";
1588 reply.
mode = CtlPkt::NEG_REPLY;
1594 reply.
errMsg =
"add comtree link: cannot add "
1595 "requested comtree link";
1596 reply.
mode = CtlPkt::NEG_REPLY;
1603 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1605 int rtx =
rt->getRteIndex(comt,peerAdr);
1606 if (rtx == 0)
rt->addEntry(comt,peerAdr,cLnk);
1611 int rtx =
rt->getRteIndex(comt,dest);
1612 if (rtx == 0)
rt->addEntry(comt,dest,cLnk);
1620 reply.
errMsg =
"add comtree link: no queues "
1621 "available for link";
1622 reply.
mode = CtlPkt::NEG_REPLY;
1630 if (!minRates.leq(
lt->getAvailRates(lnk))) {
1631 reply.
errMsg =
"add comtree link: request "
1632 "exceeds link capacity";
1633 reply.
mode = CtlPkt::NEG_REPLY;
1636 lt->getAvailRates(lnk).subtract(minRates);
1639 qm->setQRates(qid,minRates);
1640 if (isRtr)
qm->setQLimits(qid,500,1000000);
1641 else qm->setQLimits(qid,500,1000000);
1642 sm->clearQuStats(qid);
1644 reply.rspec1 =
lt->getAvailRates(lnk);
1648 bool RouterCore::dropComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1652 reply.
errMsg =
"drop comtree link: invalid comtree";
1653 reply.
mode = CtlPkt::NEG_REPLY;
1659 }
else if (cp.ip1 != 0 && cp.port1 != 0) {
1660 lnk =
lt->
lookup(cp.ip1, cp.port1);
1661 }
else if (cp.adr1 != 0) {
1665 reply.
errMsg =
"drop comtree link: invalid link "
1666 "or peer IP and port";
1667 reply.
mode = CtlPkt::NEG_REPLY;
1672 dropComtreeLink(ctx,lnk,cLnk);
1674 reply.rspec1 =
lt->getAvailRates(lnk);
1678 void RouterCore::dropComtreeLink(
int ctx,
int lnk,
int cLnk) {
1683 fAdr_t peerAdr =
lt->getPeerAdr(lnk);
1686 int rtx =
rt->getRteIndex(comt,peerAdr);
1687 if (rtx != 0)
rt->removeEntry(rtx);
1692 int rtx =
rt->getRteIndex(comt,dest);
1693 if (rtx != 0)
rt->removeEntry(rtx);
1703 set<int>::iterator rp;
1704 int *routes =
new int[rteSet.size()];
1706 for (rp = rteSet.begin(); rp != rteSet.end(); rp++) routes[i++] = *rp;
1715 cerr <<
"dropComtreeLink: internal error detected "
1716 "final removeLink failed\n";
1720 bool RouterCore::modComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1724 reply.
errMsg =
"modify comtree link: invalid comtree";
1725 reply.
mode = CtlPkt::NEG_REPLY;
1730 reply.
errMsg =
"modify comtree link: invalid link number";
1731 reply.
mode = CtlPkt::NEG_REPLY;
1736 reply.
errMsg =
"modify comtree link: specified link "
1737 "not defined in specified comtree";
1738 reply.
mode = CtlPkt::NEG_REPLY;
1743 if (!rs.isSet())
return true;
1745 if (!diff.
leq(
lt->getAvailRates(lnk))) {
1746 reply.
errMsg =
"modify comtree link: new rate spec "
1747 "exceeds available link capacity";
1748 reply.
mode = CtlPkt::NEG_REPLY;
1751 cerr <<
"mod comtree link exceeding link capacity on link " << lnk <<
1753 cerr <<
" only " <<
lt->getAvailRates(lnk).
toString(s) <<
"available\n";
1757 lt->getAvailRates(lnk).subtract(diff);
1759 reply.rspec1 =
lt->getAvailRates(lnk);
1763 bool RouterCore::getComtreeLink(
CtlPkt& cp,
CtlPkt& reply) {
1767 reply.
errMsg =
"get comtree link: invalid comtree";
1768 reply.
mode = CtlPkt::NEG_REPLY;
1773 reply.
errMsg =
"get comtree link: invalid link number";
1774 reply.
mode = CtlPkt::NEG_REPLY;
1779 reply.
errMsg =
"get comtree link: specified link "
1780 "not defined in specified comtree";
1781 reply.
mode = CtlPkt::NEG_REPLY;
1796 reply.
errMsg =
"comtree not defined at this router\n";
1797 reply.
mode = CtlPkt::NEG_REPLY;
1802 reply.
errMsg =
"invalid address\n";
1803 reply.
mode = CtlPkt::NEG_REPLY;
1808 int rtx =
rt->getRteIndex(comt,dest);
1814 reply.
errMsg =
"add route: requested route "
1815 "conflicts with existing route";
1816 reply.
mode = CtlPkt::NEG_REPLY;
1819 }
else if (
rt->addEntry(comt, dest, lnk)) {
1822 reply.
errMsg =
"add route: cannot add route";
1823 reply.
mode = CtlPkt::NEG_REPLY;
1827 bool RouterCore::dropRoute(
CtlPkt& cp,
CtlPkt& reply) {
1830 reply.
errMsg =
"comtree not defined at this router\n";
1831 reply.
mode = CtlPkt::NEG_REPLY;
1836 reply.
errMsg =
"invalid address\n";
1837 reply.
mode = CtlPkt::NEG_REPLY;
1840 int rtx =
rt->getRteIndex(comt,dest);
1841 rt->removeEntry(rtx);
1848 reply.
errMsg =
"comtree not defined at this router\n";
1849 reply.
mode = CtlPkt::NEG_REPLY;
1854 reply.
errMsg =
"invalid address\n";
1855 reply.
mode = CtlPkt::NEG_REPLY;
1858 int rtx =
rt->getRteIndex(comt,dest);
1870 reply.
errMsg =
"get route: no route for specified address";
1871 reply.
mode = CtlPkt::NEG_REPLY;
1878 reply.
errMsg =
"comtree not defined at this router\n";
1879 reply.
mode = CtlPkt::NEG_REPLY;
1884 reply.
errMsg =
"invalid address\n";
1885 reply.
mode = CtlPkt::NEG_REPLY;
1888 int rtx =
rt->getRteIndex(comt,dest);
1892 reply.
errMsg =
"modify route: cannot "
1893 "set link in multicast route";
1894 reply.
mode = CtlPkt::NEG_REPLY;
1901 reply.
errMsg =
"modify route: invalid route";
1902 reply.
mode = CtlPkt::NEG_REPLY;
1917 int rIndex = cp.index1;
1919 rIndex =
rt->firstRteIndex();
1920 else if (!
rt->validRteIndex(rIndex)) {
1921 reply.
errMsg =
"get route set: invalid route number";
1922 reply.
mode = CtlPkt::NEG_REPLY;
1925 reply.index1 = rIndex;
1926 int count = min(10,cp.
count);
1928 while (i < count && rIndex != 0) {
1932 reply.
errMsg =
"get route set: error while formatting "
1934 reply.
mode = CtlPkt::NEG_REPLY;
1937 i++; rIndex =
rt->nextRteIndex(rIndex);
1956 reply.
errMsg =
"add filter: cannot add filter";
1957 reply.
mode = CtlPkt::NEG_REPLY;
1964 bool RouterCore::dropFilter(
CtlPkt& cp,
CtlPkt& reply) {
1969 bool RouterCore::getFilter(
CtlPkt& cp,
CtlPkt& reply) {
1970 fltx fx = cp.index1;
1971 if (!
pktLog->validFilter(fx)) {
1972 reply.
errMsg =
"get filter: invalid filter index";
1973 reply.
mode = CtlPkt::NEG_REPLY;
1981 bool RouterCore::modFilter(
CtlPkt& cp,
CtlPkt& reply) {
1982 fltx fx = cp.index1;
1983 if (!
pktLog->validFilter(fx)) {
1984 reply.
errMsg =
"mod filter: invalid filter index";
1985 reply.
mode = CtlPkt::NEG_REPLY;
2004 fltx fx = cp.index1;
2006 fx =
pktLog->firstFilter();
2007 }
else if (!
pktLog->validFilter(fx)) {
2008 reply.
errMsg =
"get filter set: invalid filter index";
2009 reply.
mode = CtlPkt::NEG_REPLY;
2013 int count = min(10,cp.
count);
2015 string s; stringstream ss;
2016 while (i < count && fx != 0) {
2018 ss.str(
""); ss.clear(); ss << fx <<
" ";
2024 reply.
errMsg =
"get filter set: error while "
2026 reply.
mode = CtlPkt::NEG_REPLY;
2029 i++; fx =
pktLog->nextFilter(fx);
2068 reply.
errMsg =
"attempting to set leaf address range when "
2070 reply.
mode = CtlPkt::NEG_REPLY;
2074 fAdr_t lastLeafAdr = cp.adr2;
2076 reply.
errMsg =
"request contained empty leaf address range";
2077 reply.
mode = CtlPkt::NEG_REPLY;
2092 uint64_t nonce =
lt->getNonce(lnk);
2094 p.
comtree = Forest::CONNECT_COMT;
2096 p.payload()[0] = htonl((
int) (nonce >> 32));
2097 p.payload()[1] = htonl((
int) (nonce & 0xffffffff));
2113 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
2120 cp.
mode = CtlPkt::REQUEST;
2123 if (cp.
pack() == 0) {
2124 cerr <<
"RouterCore::sendCpReq: control packet packing error\n";
2145 cerr <<
"RouterCore::sendControl: no packets left in packet "
2151 pair<uint64_t,ControlInfo> cpp;
2153 cpp.second.px = cx; cpp.second.nSent = 1; cpp.second.timestamp =
now;
2154 cpp.second.lnk = lnk;
2161 }
else if (lnk != 0) {
2162 int ctx;
int clnk;
int qid;
2184 map<uint64_t,ControlInfo>::iterator pp;
2185 list<uint64_t> dropList;
2187 if (now < pp->second.timestamp + 1000000000)
continue;
2188 pktx px = pp->second.px;
2191 if (pp->second.nSent >= 3) {
2192 cerr <<
"RouterCore::resendControl: received no reply "
2193 "to control packet after three attempts\n"
2195 ps->
free(px); dropList.push_front(pp->first);
continue;
2198 pp->second.timestamp =
now;
2202 cerr <<
"RouterCore::resendControl: no packets left in "
2209 }
else if (lnk != 0) {
2210 int ctx;
int clnk;
int qid;
2221 for (uint64_t pid : dropList)
pending->erase(pid);
2239 pid = ntohl(reply.payload()[0]); pid <<= 32;
2240 pid |= ntohl(reply.payload()[1]);
2245 cerr <<
"RouterCore::handleControlReply: unexpected reply "
2250 map<uint64_t,ControlInfo>::iterator pp =
pending->find(pid);
2255 cerr <<
"RouterCore::handleControlReply: unexpected reply "
2261 if (cpr.
mode == CtlPkt::NEG_REPLY) {
2263 cerr <<
"RouterCore::handleControlReply: got negative "
2266 cerr <<
"reply=" << reply.
toString(s);
2267 }
else if (cpr.
type == CtlPkt::BOOT_ROUTER) {
2269 cerr <<
"RouterCore::handleControlReply: "
2270 "setup failed after completion of boot "
2276 iop->closeBootSock();
2293 int paylen = cp.
pack();
2295 cerr <<
"RouterCore::returnToSender: control packet formatting "
2296 "error, zero payload length\n";
2299 p.
length = (Packet::OVERHEAD + paylen);