34 for (
int i = 1; i < argc; i++) {
36 if (s.compare(0,10,
"mode=local") == 0) {
38 }
else if (s.compare(0,11,
"mode=remote") == 0) {
40 }
else if (s.compare(0,6,
"myAdr=") == 0) {
42 }
else if (s.compare(0,7,
"bootIp=") == 0) {
44 }
else if (s.compare(0,6,
"nmAdr=") == 0) {
46 }
else if (s.compare(0,5,
"nmIp=") == 0) {
48 }
else if (s.compare(0,6,
"ccAdr=") == 0) {
50 }
else if (s.compare(0,13,
"firstLeafAdr=") == 0) {
52 }
else if (s.compare(0,12,
"lastLeafAdr=") == 0) {
54 }
else if (s.compare(0,6,
"ifTbl=") == 0) {
55 args.
ifTbl = &argv[i][6];
56 }
else if (s.compare(0,7,
"lnkTbl=") == 0) {
58 }
else if (s.compare(0,8,
"comtTbl=") == 0) {
60 }
else if (s.compare(0,7,
"rteTbl=") == 0) {
62 }
else if (s.compare(0,9,
"statSpec=") == 0) {
64 }
else if (s.compare(0,8,
"finTime=") == 0) {
65 sscanf(&argv[i][8],
"%d",&args.
finTime);
67 cerr <<
"unrecognized argument: " << argv[i] << endl;
71 if (args.
mode.compare(
"local") == 0 &&
74 cerr <<
"processArgs: local configuration requires myAdr, "
75 "firstLeafAdr, lastLeafAdr and that firstLeafAdr "
76 "be no larger than lastLeafAdr\n";
78 }
else if (args.
mode.compare(
"remote") == 0 &&
81 cerr <<
"processArgs: remote configuration requires bootIp, "
82 "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;
96 RouterCore router(booting,args);
98 if (!router.readTables(args))
99 fatal(
"router: could not read specified config files");
102 fatal(
"router: inconsistency in config files");
104 router.run(args.finTime);
116 : booting(booting1) {
117 nIfaces = 50; nLnks = 1000;
118 nComts = 5000; nRts = 100000;
119 nPkts = 200000; nBufs = 100000; nQus = 10000;
121 myAdr = config.myAdr;
122 bootIp = config.bootIp;
123 nmAdr = config.nmAdr;
125 ccAdr = config.ccAdr;
126 firstLeafAdr = config.firstLeafAdr;
128 ps =
new PacketStore(nPkts, nBufs);
129 ift =
new IfaceTable(nIfaces);
130 lt =
new LinkTable(nLnks);
131 ctt =
new ComtreeTable(nComts,10*nComts,lt);
132 rt =
new RouteTable(nRts,
myAdr,ctt);
133 sm =
new StatsModule(1000, nLnks, nQus, ctt);
134 iop =
new IoProcessor(nIfaces, ift, lt,
ps, sm);
135 qm =
new QuManager(nLnks, nPkts, nQus, min(50,5*nPkts/nLnks),
ps, sm);
136 pktLog =
new PacketLog(20000,500,
ps);
139 leafAdr =
new UiSetPair((config.lastLeafAdr - firstLeafAdr)+1);
142 pending =
new map<uint64_t,CpInfo>;
145 RouterCore::~RouterCore() {
146 delete pktLog;
delete qm;
delete iop;
delete sm;
147 delete rt;
delete ctt;
delete lt;
delete ift;
delete ps;
148 if (leafAdr != 0)
delete leafAdr;
157 bool RouterCore::readTables(
const RouterInfo& config) {
158 if (config.ifTbl.compare(
"") != 0) {
159 ifstream fs; fs.open(config.ifTbl.c_str());
160 if (fs.fail() || !ift->read(fs)) {
161 cerr <<
"RouterCore::init: can't read "
162 <<
"interface table\n";
167 if (config.lnkTbl.compare(
"") != 0) {
168 ifstream fs; fs.open(config.lnkTbl.c_str());
169 if (fs.fail() || !lt->read(fs)) {
170 cerr <<
"RouterCore::init: can't read "
176 if (config.comtTbl.compare(
"") != 0) {
177 ifstream fs; fs.open(config.comtTbl.c_str());
178 if (fs.fail() || !ctt->read(fs)) {
179 cerr <<
"RouterCore::init: can't read "
180 <<
"comtree table\n";
185 if (config.rteTbl.compare(
"") != 0) {
186 ifstream fs; fs.open(config.rteTbl.c_str());
187 if (fs.fail() || !rt->read(fs)) {
188 cerr <<
"RouterCore::init: can't read "
189 <<
"routing table\n";
194 if (config.statSpec.compare(
"") != 0) {
195 ifstream fs; fs.open(config.statSpec.c_str());
196 if (fs.fail() || !sm->read(fs)) {
197 cerr <<
"RouterCore::init: can't read "
198 <<
"statistics spec\n";
210 bool RouterCore::setup() {
212 if (!setupIfaces())
return false;
213 if (!setupLeafAddresses())
return false;
214 if (!setupQueues())
return false;
215 if (!checkTables())
return false;
216 if (!setAvailRates())
return false;
226 bool RouterCore::setupIfaces() {
227 for (
int iface = ift->firstIface(); iface != 0;
228 iface = ift->nextIface(iface)) {
229 if (!iop->setup(iface)) {
230 cerr <<
"RouterCore::setupIfaces: could not "
231 "setup interface " << iface << endl;
244 bool RouterCore::setupLeafAddresses() {
245 for (
int lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
246 if (booting || lt->getPeerType(lnk) == ROUTER)
continue;
247 if (!allocLeafAdr(lt->getPeerAdr(lnk)))
259 bool RouterCore::setupQueues() {
261 for (
int lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
262 qm->setLinkRates(lnk,lt->getBitRate(lnk),lt->getPktRate(lnk));
265 for (ctx = ctt->firstComtIndex(); ctx != 0;
266 ctx = ctt->nextComtIndex(ctx)) {
267 set<int>& links = ctt->getLinks(ctx);
268 set<int>::iterator p;
269 for (p = links.begin(); p != links.end(); p++) {
270 int cLnk = *p;
int lnk = ctt->getLink(cLnk);
271 int qid = qm->allocQ(lnk);
272 if (qid == 0)
return false;
273 ctt->setLinkQ(cLnk,qid);
274 qm->setQRates(qid,Forest::MINBITRATE,
276 if (lt->getPeerType(lnk) == ROUTER)
277 qm->setQLimits(qid,100,200000);
279 qm->setQLimits(qid,50,100000);
280 sm->clearQuStats(qid);
292 bool RouterCore::checkTables() {
297 if (!ift->valid(ift->getDefaultIface())) {
298 cerr <<
"RouterCore::checkTables: specified default iface "
299 << ift->getDefaultIface() <<
" is invalid\n";
303 for (iface = ift->firstIface(); iface != 0;
304 iface = ift->nextIface(iface)) {
305 if (ift->getIpAdr(iface) == 0) {
306 cerr <<
"RouterCore::checkTables: interface "
307 << iface <<
" has zero for IP address\n";
317 for (lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
318 iface = lt->getIface(lnk);
319 if (!ift->valid(iface)) {
320 cerr <<
"RouterCore::checkTables: interface " << iface
321 <<
" for link " << lnk <<
" is not valid\n";
324 if (lt->getPeerIpAdr(lnk) == 0) {
325 cerr <<
"RouterCore::checkTables: invalid peer IP "
326 <<
"for link " << lnk << endl;
329 if (!Forest::validUcastAdr(lt->getPeerAdr(lnk))) {
330 cerr <<
"RouterCore::checkTables: invalid peer address "
331 <<
"for link " << lnk << endl;
340 for (ctx = ctt->firstComtIndex(); ctx != 0;
341 ctx = ctt->nextComtIndex(ctx)) {
342 int comt = ctt->getComtree(ctx);
343 int plnk = ctt->getPlink(ctx);
344 int pcLnk = ctt->getPCLink(ctx);
345 if (plnk != ctt->getLink(pcLnk)) {
346 cerr <<
"RouterCore::checkTables: parent link "
347 << plnk <<
" not consistent with pcLnk\n";
350 if (ctt->inCore(ctx) && plnk != 0 && !ctt->isCoreLink(pcLnk)) {
351 cerr <<
"RouterCore::checkTables: parent link "
352 << plnk <<
" of core node does not lead to "
353 <<
"another core node\n";
356 set<int>& links = ctt->getLinks(ctx);
357 set<int>::iterator p;
358 for (p = links.begin(); p != links.end(); p++) {
359 int cLnk = *p;
int lnk = ctt->getLink(cLnk);
360 if (!lt->valid(lnk)) {
361 cerr <<
"RouterCore::checkTables: link "
362 << lnk <<
" in comtree " << comt
363 <<
" not in link table" << endl;
367 fAdr_t dest = ctt->getDest(cLnk);
368 if (dest != 0 && !Forest::validUcastAdr(dest)) {
369 cerr <<
"RouterCore::checkTables: dest addr "
370 <<
"for " << lnk <<
" in comtree " << comt
371 <<
" is not valid" << endl;
374 int qid = ctt->getLinkQ(cLnk);
376 cerr <<
"RouterCore::checkTables: queue id "
377 <<
"for " << lnk <<
" in comtree " << comt
378 <<
" is zero" << endl;
383 set<int>& rtrLinks = ctt->getRtrLinks(ctx);
384 for (p = rtrLinks.begin(); p != rtrLinks.end(); p++) {
385 int cLnk = *p;
int lnk = ctt->getLink(cLnk);
386 if (!ctt->isLink(ctx,lnk)) {
387 cerr <<
"RouterCore::checkTables: router link "
388 << lnk <<
" is not valid in comtree "
392 if (lt->getPeerType(lnk) != ROUTER) {
393 cerr <<
"RouterCore::checkTables: router link "
394 << lnk <<
" in comtree " << comt
395 <<
" connects to non-router peer\n";
399 set<int>& coreLinks = ctt->getCoreLinks(ctx);
400 for (p = coreLinks.begin(); p != coreLinks.end(); p++) {
401 int cLnk = *p;
int lnk = ctt->getLink(cLnk);
402 if (!ctt->isRtrLink(ctx,lnk)) {
403 cerr <<
"RouterCore::checkTables: core link "
404 << lnk <<
" is not a router link "
419 bool RouterCore::setAvailRates() {
422 for (iface = ift->firstIface(); iface != 0;
423 iface = ift->nextIface(iface)) {
424 if (ift->getMaxBitRate(iface) < Forest::MINBITRATE ||
425 ift->getMaxBitRate(iface) > Forest::MAXBITRATE ||
426 ift->getMaxPktRate(iface) < Forest::MINBITRATE ||
427 ift->getMaxPktRate(iface) > Forest::MAXBITRATE) {
428 cerr <<
"RouterCore::setAvailRates: interface rates "
429 "outside allowed range\n";
432 ift->setAvailBitRate(iface, ift->getMaxBitRate(iface));
433 ift->setAvailPktRate(iface, ift->getMaxPktRate(iface));
435 if (!success)
return false;
437 for (lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
438 if (lt->getBitRate(lnk) < Forest::MINBITRATE ||
439 lt->getBitRate(lnk) > Forest::MAXBITRATE ||
440 lt->getPktRate(lnk) < Forest::MINBITRATE ||
441 lt->getPktRate(lnk) > Forest::MAXBITRATE) {
442 cerr <<
"RouterCore::setAvailRates: link rates "
443 "outside allowed range\n";
446 iface = lt->getIface(lnk);
447 if (!ift->addAvailBitRate(iface,-lt->getBitRate(lnk)) ||
448 !ift->addAvailPktRate(iface,-lt->getPktRate(lnk))) {
449 cerr <<
"RouterCore::setAvailRates: oversubscribing "
450 "interface " << iface << endl;
453 lt->setAvailInBitRate(lnk,lt->getBitRate(lnk));
454 lt->setAvailInPktRate(lnk,lt->getPktRate(lnk));
455 lt->setAvailOutBitRate(lnk,lt->getBitRate(lnk));
456 lt->setAvailOutPktRate(lnk,lt->getPktRate(lnk));
457 sm->clearLnkStats(lnk);
459 if (!success)
return false;
461 for (ctx = ctt->firstComtIndex(); ctx != 0;
462 ctx = ctt->nextComtIndex(ctx)) {
463 set<int>& comtLinks = ctt->getLinks(ctx);
464 set<int>::iterator p;
465 for (p = comtLinks.begin(); p != comtLinks.end(); p++) {
466 int cLnk = *p;
int lnk = ctt->getLink(cLnk);
467 int ibr = ctt->getInBitRate(cLnk);
468 int ipr = ctt->getInPktRate(cLnk);
469 int obr = ctt->getOutBitRate(cLnk);
470 int opr = ctt->getOutPktRate(cLnk);
471 if (!lt->addAvailInBitRate(lnk,-ibr) ||
472 !lt->addAvailInPktRate(lnk,-ipr) ||
473 !lt->addAvailOutBitRate(lnk,-obr) ||
474 !lt->addAvailOutPktRate(lnk,-opr)) {
475 cerr <<
"RouterCore::setAvailRates: "
476 "oversubscribing link "
488 void RouterCore::addLocalRoutes() {
489 for (
int ctx = ctt->firstComtIndex(); ctx != 0;
490 ctx = ctt->nextComtIndex(ctx)) {
491 int comt = ctt->getComtree(ctx);
492 set<int>& comtLinks = ctt->getLinks(ctx);
493 set<int>::iterator p;
494 for (p = comtLinks.begin(); p != comtLinks.end(); p++) {
495 int cLnk = *p;
int lnk = ctt->getLink(cLnk);
496 fAdr_t peerAdr = lt->getPeerAdr(lnk);
497 if (lt->getPeerType(lnk) == ROUTER &&
498 Forest::zipCode(peerAdr)
499 == Forest::zipCode(myAdr))
501 if (rt->getRteIndex(comt,peerAdr) != 0)
503 rt->addEntry(comt,peerAdr,cLnk);
511 void RouterCore::dump(ostream& out) {
513 out <<
"Interface Table\n\n" << ift->toString(s) << endl;
514 out <<
"Link Table\n\n" << lt->toString(s) << endl;
515 out <<
"Comtree Table\n\n" << ctt->toString(s) << endl;
516 out <<
"Routing Table\n\n" << rt->toString(s) << endl;
517 out <<
"Statistics\n\n" << sm->toString(s) << endl;
548 void RouterCore::run(uint64_t finishTime) {
549 #ifdef PROFILING // MAH
550 Timer timer_loop(
"RouterCore::run() main loop ");
551 Timer timer_deq(
"RouterCore::run() -> QuManager::deq() ");
554 Timer timer_pktCheck(
"RouterCore::run() -> RouterCore::pktCheck() ");
555 Timer timer_pktLog(
"RouterCore::run() -> PacketLog::log() ");
556 Timer timer_forward(
"RouterCore::run() -> RouterCore::forward() ");
557 Timer timer_receive(
"RouterCore::run() -> IoProcessor::receive() ");
558 Timer timer_send(
"RouterCore::run() -> IoProcessor::send() ");
560 now = Misc::getTimeNs();
562 if (!iop->setupBootSock(bootIp,nmIp))
563 fatal(
"RouterCore:run: could not setup boot socket\n");
565 cout <<
"sending boot request to " << Np4d::ip2string(nmIp,s1)
567 CtlPkt cp(BOOT_REQUEST,REQUEST,0);
568 if (!sendCpReq(cp,nmAdr))
569 fatal(
"RouterCore::run: could not send boot request\n");
573 uint64_t statsTime = 0;
575 int controlCount = 20;
579 now = Misc::getTimeNs();
580 finishTime *= 1000000000;
581 while (finishTime == 0 || now < finishTime) {
585 #ifdef PROFILING // MAH
587 timer_receive.start();
589 int p = iop->receive();
590 #ifdef PROFILING // MAH
591 if (p == 0) { timer_receive.cancel(); }
592 else { timer_receive.stop(); }
596 PacketHeader& h =
ps->getHeader(p);
597 int ptype = h.getPtype();
599 timer_pktLog.start();
600 pktLog->log(p,h.getInLink(),
false,now);
603 pktLog->log(p,h.getInLink(),
false,now);
605 int ctx = ctt->getComtIndex(h.getComtree());
606 #ifdef PROFILING // MAH
607 timer_pktCheck.start();
608 bool pkt_check = pktCheck(p,ctx);
609 timer_pktCheck.stop();
612 if (!pktCheck(p,ctx)) {
615 }
else if (booting) {
617 }
else if (ptype == CLIENT_DATA) {
618 #ifdef PROFILING // MAH
619 timer_forward.start();
622 #ifdef PROFILING // MAH
623 timer_forward.stop();
625 }
else if (ptype == SUB_UNSUB) {
627 }
else if (ptype == RTE_REPLY) {
628 handleRteReply(p,ctx);
629 }
else if (ptype == CONNECT || ptype == DISCONNECT) {
631 }
else if (h.getDstAdr() !=
myAdr) {
632 #ifdef PROFILING // MAH
633 timer_forward.start();
636 #ifdef PROFILING // MAH
637 timer_forward.stop();
644 #ifdef PROFILING // MAH
649 while ((p = qm->deq(lnk, now)) != 0) {
653 timer_pktLog.start();
655 pktLog->log(p,lnk,
true,now);
670 if (!ctlQ.empty() && (didNothing || --controlCount <= 0)) {
671 handleCtlPkt(ctlQ.front());
679 if (now - statsTime > 300000000) {
687 if (didNothing) { usleep(1000); }
690 now = Misc::getTimeNs();
691 #ifdef PROFILING // MAH
699 cout << sm->iPktCnt(0) <<
" packets received, "
700 << sm->oPktCnt(0) <<
" packets sent\n";
701 cout << sm->iPktCnt(-1) <<
" from routers, "
702 << sm->oPktCnt(-1) <<
" to routers\n";
703 cout << sm->iPktCnt(-2) <<
" from clients, "
704 << sm->oPktCnt(-2) <<
" to clients\n";
705 #ifdef PROFILING // MAH
706 cout << timer_loop << endl;
707 cout << timer_deq << endl;
708 cout << timer_pktCheck << endl;
709 cout << timer_forward << endl;
710 cout << timer_receive << endl;
711 cout << timer_send << endl;
720 bool RouterCore::pktCheck(
int p,
int ctx) {
721 PacketHeader& h =
ps->getHeader(p);
723 if (h.getVersion() != Forest::FOREST_VERSION) {
727 if (h.getLength() != h.getIoBytes() || h.getLength()<Forest::HDR_LENG) {
732 return h.getSrcAdr() ==
nmAdr && h.getDstAdr() ==
myAdr &&
733 h.getPtype() == NET_SIG &&
734 h.getComtree() == Forest::NET_SIG_COMT;
737 if (!ctt->validComtIndex(ctx)) {
740 fAdr_t adr = h.getDstAdr();
741 if (!Forest::validUcastAdr(adr) && !Forest::mcastAdr(adr)) {
745 int inLink = h.getInLink();
746 if (inLink == 0)
return false;
747 int cLnk = ctt->getComtLink(ctt->getComtree(ctx),inLink);
753 if (lt->getPeerType(inLink) < TRUSTED) {
755 if (lt->getPeerAdr(inLink) != h.getSrcAdr())
return false;
757 fAdr_t dest = ctt->getDest(cLnk);
758 if (dest!=0 && h.getDstAdr() != dest && h.getDstAdr() !=
myAdr)
761 ptyp_t ptype = h.getPtype();
762 if (ptype != CLIENT_DATA &&
763 ptype != CONNECT && ptype != DISCONNECT &&
764 ptype != SUB_UNSUB && ptype != CLIENT_SIG)
766 int comt = ctt->getComtree(ctx);
767 if ((ptype == CONNECT || ptype == DISCONNECT) &&
768 comt != (
int) Forest::CLIENT_CON_COMT)
770 if (ptype == CLIENT_SIG &&
771 comt != (
int) Forest::CLIENT_SIG_COMT)
786 void RouterCore::forward(
int p,
int ctx) {
787 PacketHeader& h =
ps->getHeader(p);
788 int rtx = rt->getRteIndex(h.getComtree(),h.getDstAdr());
791 if ((h.getFlags() & Forest::RTE_REQ)) {
793 h.setFlags(h.getFlags() & (~Forest::RTE_REQ));
797 if (Forest::validUcastAdr(h.getDstAdr())) {
798 int rcLnk = rt->getLink(rtx);
799 int lnk = ctt->getLink(rcLnk);
800 int qid = ctt->getLinkQ(rcLnk);
801 if (lnk == h.getInLink() || !qm->enq(p,qid,now)) {
807 multiSend(p,ctx,rtx);
812 if (Forest::validUcastAdr(h.getDstAdr())) {
814 h.setFlags(Forest::RTE_REQ);
815 ps->pack(p);
ps->hdrErrUpdate(p);
817 multiSend(p,ctx,rtx);
830 void RouterCore::multiSend(
int p,
int ctx,
int rtx) {
831 int qvec[nLnks];
int n = 0;
832 PacketHeader& h =
ps->getHeader(p);
834 int inLink = h.getInLink();
835 if (Forest::validUcastAdr(h.getDstAdr())) {
837 int myZip = Forest::zipCode(myAdr);
838 int pZip = Forest::zipCode(h.getDstAdr());
839 set<int>& rtrLinks = ctt->getRtrLinks(ctx);
840 set<int>::iterator lp;
841 for (lp = rtrLinks.begin(); lp != rtrLinks.end(); lp++) {
842 int rcLnk = *lp;
int lnk = ctt->getLink(rcLnk);
843 int peerZip = Forest::zipCode(lt->getPeerAdr(lnk));
844 if (pZip == myZip && peerZip != myZip)
continue;
845 if (lnk == inLink)
continue;
846 qvec[n++] = ctt->getLinkQ(rcLnk);
851 int pLink = ctt->getPlink(ctx);
852 set<int>& coreLinks = ctt->getCoreLinks(ctx);
853 set<int>::iterator lp;
854 for (lp = coreLinks.begin(); lp != coreLinks.end(); lp++) {
855 int rcLnk = *lp;
int lnk = ctt->getLink(rcLnk);
856 if (lnk == inLink || lnk == pLink)
continue;
857 qvec[n++] = ctt->getLinkQ(rcLnk);
860 if (pLink != 0 && pLink != inLink) {
861 qvec[n++] = ctt->getLinkQ(ctt->getPCLink(ctx));
865 set<int>& subLinks = rt->getSubLinks(rtx);
866 for (lp = subLinks.begin(); lp !=subLinks.end(); lp++) {
867 int rcLnk = *lp;
int lnk = ctt->getLink(rcLnk);
868 if (lnk == inLink)
continue;
869 qvec[n++] = ctt->getLinkQ(rcLnk);
874 if (n == 0) {
ps->
free(p);
return; }
878 for (
int i = 0; i < n-1; i++) {
879 if (qm->enq(p1,qvec[i],now)) {
884 if (!qm->enq(p1,qvec[n-1],now)) {
895 void RouterCore::sendRteReply(
int p,
int ctx) {
896 PacketHeader& h =
ps->getHeader(p);
899 PacketHeader& h1 =
ps->getHeader(p1);
900 h1.setLength(Forest::HDR_LENG + 8);
901 h1.setPtype(RTE_REPLY);
903 h1.setComtree(h.getComtree());
905 h1.setDstAdr(h.getSrcAdr());
908 ps->getPayload(p1)[0] = htonl(h.getDstAdr());
909 ps->hdrErrUpdate(p1);
ps->payErrUpdate(p1);
911 int cLnk = ctt->getComtLink(ctt->getComtree(ctx),h.getInLink());
912 qm->enq(p1,ctt->getLinkQ(cLnk),now);
923 void RouterCore::handleRteReply(
int p,
int ctx) {
924 PacketHeader& h =
ps->getHeader(p);
925 int rtx = rt->getRteIndex(h.getComtree(), h.getDstAdr());
926 int cLnk = ctt->getComtLink(ctt->getComtree(ctx),h.getInLink());
927 if ((h.getFlags() & Forest::RTE_REQ) && rtx != 0)
929 int adr = ntohl(
ps->getPayload(p)[0]);
930 if (Forest::validUcastAdr(adr) &&
931 rt->getRteIndex(h.getComtree(),adr) == 0) {
932 rt->addEntry(h.getComtree(),adr,cLnk);
936 h.setFlags(Forest::RTE_REQ);
937 ps->pack(p);
ps->hdrErrUpdate(p);
938 multiSend(p,ctx,rtx);
941 int dcLnk = rt->getLink(rtx);
int dLnk = ctt->getLink(dcLnk);
942 if (lt->getPeerType(dLnk) != ROUTER || !qm->enq(p,dLnk,now))
954 void RouterCore::subUnsub(
int p,
int ctx) {
955 PacketHeader& h =
ps->getHeader(p);
956 uint32_t *pp =
ps->getPayload(p);
961 int comt = ctt->getComtree(ctx);
962 int inLink = h.getInLink();
963 int cLnk = ctt->getComtLink(comt,inLink);
965 if (inLink == ctt->getPlink(ctx) || ctt->isCoreLink(cLnk)) {
968 bool propagate =
false;
972 int addcnt = ntohl(pp[0]);
973 if (addcnt < 0 || addcnt > 350 ||
974 Forest::OVERHEAD + (addcnt + 2)*4 > h.getLength()) {
977 for (
int i = 1; i <= addcnt; i++) {
979 if (!Forest::mcastAdr(addr))
continue;
980 rtx = rt->getRteIndex(comt,addr);
982 rtx = rt->addEntry(comt,addr,cLnk);
984 }
else if (!rt->isLink(rtx,cLnk)) {
985 rt->addLink(rtx,cLnk);
990 int dropcnt = ntohl(pp[addcnt+1]);
991 if (dropcnt < 0 || addcnt + dropcnt > 350 ||
992 Forest::OVERHEAD + (addcnt + dropcnt + 2)*4 > h.getLength()) {
995 for (
int i = addcnt + 2; i <= addcnt + dropcnt + 1; i++) {
997 if (!Forest::mcastAdr(addr))
continue;
998 rtx = rt->getRteIndex(comt,addr);
999 if (rtx == 0)
continue;
1000 rt->removeLink(rtx,cLnk);
1001 if (rt->noLinks(rtx)) {
1002 rt->removeEntry(rtx);
1009 if (propagate && !ctt->inCore(ctx) && ctt->getPlink(ctx) != 0) {
1010 ps->payErrUpdate(p);
1011 int qid = ctt->getLinkQ(ctt->getPCLink(ctx));
1012 if (qm->enq(p,qid,now)) {
1022 void RouterCore::handleConnDisc(
int p) {
1023 PacketHeader& h =
ps->getHeader(p);
1024 int inLnk = h.getInLink();
1026 if (!validLeafAdr(h.getSrcAdr())) {
1029 if (h.getPtype() == CONNECT) {
1030 if (lt->getPeerPort(inLnk) == 0) {
1031 lt->setPeerPort(inLnk,h.getTunSrcPort());
1044 if (nmAdr != 0 && lt->getPeerType(inLnk) == CLIENT) {
1045 CtlPkt cp(CLIENT_CONNECT,REQUEST,0);
1046 cp.setAttr(CLIENT_ADR,h.getSrcAdr());
1047 cp.setAttr(RTR_ADR,myAdr);
1048 sendCpReq(cp,nmAdr);
1050 }
else if (h.getPtype() == DISCONNECT) {
1051 if (lt->getPeerPort(inLnk) == h.getTunSrcPort()) {
1054 if (nmAdr != 0 && lt->getPeerType(inLnk) == CLIENT) {
1055 CtlPkt cp(CLIENT_DISCONNECT,REQUEST,0);
1056 cp.setAttr(CLIENT_ADR,h.getSrcAdr());
1057 cp.setAttr(RTR_ADR,myAdr);
1058 sendCpReq(cp,nmAdr);
1075 void RouterCore::handleCtlPkt(
int p) {
1076 PacketHeader& h =
ps->getHeader(p);
1079 int len = h.getLength() - (Forest::HDR_LENG + 4);
1080 if (!cp.unpack(
ps->getPayload(p), len)) {
1082 cerr <<
"RouterCore::handleCtlPkt: misformatted control "
1083 " packet\n" << h.toString(
ps->getBuffer(p),s);
1084 cp.setRrType(NEG_REPLY);
1085 cp.setErrMsg(
"misformatted control packet");
1086 returnToSender(p,cp.pack(
ps->getPayload(p)));
1089 if (h.getPtype() != NET_SIG || h.getComtree() != Forest::NET_SIG_COMT) {
1092 if (cp.getRrType() != REQUEST) {
1093 handleCpReply(p,cp);
return;
1098 reply.setCpType(cp.getCpType());
1099 reply.setRrType(POS_REPLY);
1100 reply.setSeqNum(cp.getSeqNum());
1101 switch (cp.getCpType()) {
1104 case ADD_IFACE: addIface(p,cp,reply);
break;
1105 case DROP_IFACE: dropIface(p,cp,reply);
break;
1106 case GET_IFACE: getIface(p,cp,reply);
break;
1107 case MOD_IFACE: modIface(p,cp,reply);
break;
1110 case ADD_LINK: addLink(p,cp,reply);
break;
1111 case DROP_LINK: dropLink(p,cp,reply);
break;
1112 case GET_LINK: getLink(p,cp,reply);
break;
1113 case MOD_LINK: modLink(p,cp,reply);
break;
1116 case ADD_COMTREE: addComtree(p,cp,reply);
break;
1117 case DROP_COMTREE: dropComtree(p,cp,reply);
break;
1118 case GET_COMTREE: getComtree(p,cp,reply);
break;
1119 case MOD_COMTREE: modComtree(p,cp,reply);
break;
1120 case ADD_COMTREE_LINK: addComtreeLink(p,cp,reply);
break;
1121 case DROP_COMTREE_LINK: dropComtreeLink(p,cp,reply);
break;
1122 case GET_COMTREE_LINK: getComtreeLink(p,cp,reply);
break;
1123 case MOD_COMTREE_LINK: modComtreeLink(p,cp,reply);
break;
1126 case ADD_ROUTE: addRoute(p,cp,reply);
break;
1127 case DROP_ROUTE: dropRoute(p,cp,reply);
break;
1128 case GET_ROUTE: getRoute(p,cp,reply);
break;
1129 case MOD_ROUTE: modRoute(p,cp,reply);
break;
1132 case BOOT_COMPLETE: bootComplete(p,cp,reply);
break;
1135 case BOOT_ABORT: bootAbort(p,cp,reply);
break;
1138 cerr <<
"unrecognized control packet type " << cp.getCpType()
1140 reply.setErrMsg(
"invalid control packet for router");
1141 reply.setRrType(NEG_REPLY);
1145 returnToSender(p,reply.pack(
ps->getPayload(p)));
1147 if (reply.getCpType() == BOOT_COMPLETE) {
1148 iop->closeBootSock();
1166 bool RouterCore::addIface(
int p, CtlPkt& cp, CtlPkt& reply) {
1167 if (!cp.isSet(IFACE_NUM) || !cp.isSet(LOCAL_IP) ||
1168 !cp.isSet(MAX_BIT_RATE) || !cp.isSet(MAX_PKT_RATE)) {
1169 reply.setErrMsg(
"add iface: missing required attribute");
1170 reply.setRrType(NEG_REPLY);
1173 int iface = cp.getAttr(IFACE_NUM);
1174 ipa_t localIp = cp.getAttr(LOCAL_IP);
1175 int bitRate = cp.getAttr(MAX_BIT_RATE);
1176 int pktRate = cp.getAttr(MAX_PKT_RATE);
1177 bitRate = max(bitRate, Forest::MINBITRATE);
1178 pktRate = max(pktRate, Forest::MINPKTRATE);
1179 bitRate = min(bitRate, Forest::MAXBITRATE);
1180 pktRate = min(pktRate, Forest::MAXPKTRATE);
1181 if (ift->valid(iface)) {
1182 if (localIp != ift->getIpAdr(iface) ||
1183 bitRate != ift->getMaxBitRate(iface) ||
1184 pktRate != ift->getMaxPktRate(iface)) {
1185 reply.setErrMsg(
"add iface: requested interface "
1186 "conflicts with existing interface");
1187 reply.setRrType(NEG_REPLY);
1190 }
else if (!ift->addEntry(iface, localIp, bitRate, pktRate)) {
1191 reply.setErrMsg(
"add iface: cannot add interface");
1192 reply.setRrType(NEG_REPLY);
1198 bool RouterCore::dropIface(
int p, CtlPkt& cp, CtlPkt& reply) {
1199 if (!cp.isSet(IFACE_NUM)) {
1200 reply.setErrMsg(
"drop iface: missing required "
1202 reply.setRrType(NEG_REPLY);
1205 int iface = cp.getAttr(IFACE_NUM);
1206 ift->removeEntry(iface);
1210 bool RouterCore::getIface(
int p, CtlPkt& cp, CtlPkt& reply) {
1211 if (!cp.isSet(IFACE_NUM)) {
1212 reply.setErrMsg(
"get iface: missing required "
1214 reply.setRrType(NEG_REPLY);
1217 int iface = cp.getAttr(IFACE_NUM);
1218 if (ift->valid(iface)) {
1219 reply.setAttr(IFACE_NUM,iface);
1220 reply.setAttr(LOCAL_IP,ift->getIpAdr(iface));
1221 reply.setAttr(AVAIL_BIT_RATE,ift->getAvailBitRate(iface));
1222 reply.setAttr(AVAIL_PKT_RATE,ift->getAvailPktRate(iface));
1223 reply.setAttr(MAX_BIT_RATE,ift->getMaxBitRate(iface));
1224 reply.setAttr(MAX_PKT_RATE,ift->getMaxPktRate(iface));
1227 reply.setErrMsg(
"get iface: invalid interface");
1228 reply.setRrType(NEG_REPLY);
1232 bool RouterCore::modIface(
int p, CtlPkt& cp, CtlPkt& reply) {
1233 if (!cp.isSet(IFACE_NUM)) {
1234 reply.setErrMsg(
"add iface: missing required "
1236 reply.setRrType(NEG_REPLY);
1239 int iface = cp.getAttr(IFACE_NUM);
1240 if (ift->valid(iface)) {
1241 if (cp.isSet(MAX_BIT_RATE))
1242 ift->setMaxBitRate(iface,cp.getAttr(MAX_BIT_RATE));
1243 if (cp.isSet(MAX_PKT_RATE))
1244 ift->setMaxPktRate(iface,cp.getAttr(MAX_PKT_RATE));
1247 reply.setErrMsg(
"mod iface: invalid interface");
1248 reply.setRrType(NEG_REPLY);
1252 bool RouterCore::addLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1253 if (!cp.isSet(PEER_IP) || !cp.isSet(PEER_TYPE)) {
1254 reply.setErrMsg(
"add link: missing required attribute");
1255 reply.setRrType(NEG_REPLY);
1258 ntyp_t peerType = (ntyp_t) cp.getAttr(PEER_TYPE);
1259 if (peerType == ROUTER && !cp.isSet(PEER_ADR)) {
1260 reply.setErrMsg(
"add link: adding link to router, but no peer "
1261 "address supplied");
1262 reply.setRrType(NEG_REPLY);
1265 ipa_t pipa = cp.getAttr(PEER_IP);
1266 int lnk = (cp.isSet(LINK_NUM) ? cp.getAttr(LINK_NUM) : 0);
1267 int iface = (cp.isSet(IFACE_NUM) ? cp.getAttr(IFACE_NUM) :
1268 ift->getDefaultIface());
1269 ipp_t pipp = (cp.isSet(PEER_PORT) ? cp.getAttr(PEER_PORT) :
1270 (peerType == ROUTER ? Forest::ROUTER_PORT : 0));
1271 fAdr_t padr = (cp.isSet(PEER_ADR) ? cp.getAttr(PEER_ADR): 0);
1272 int xlnk = lt->lookup(pipa,pipp);
1274 if ((lnk != 0 && lnk != xlnk) ||
1275 (peerType != lt->getPeerType(xlnk)) ||
1276 (cp.isSet(IFACE_NUM) &&
1277 cp.getAttr(IFACE_NUM) != lt->getIface(xlnk)) ||
1278 (padr != 0 && padr != lt->getPeerAdr(xlnk))) {
1279 reply.setErrMsg(
"add link: new link conflicts "
1280 "with existing link");
1281 reply.setRrType(NEG_REPLY);
1284 lnk = xlnk; padr = lt->getPeerAdr(xlnk);
1288 int br = Forest::MINBITRATE;
1289 int pr = Forest::MINPKTRATE;
1290 if (!ift->addAvailBitRate(iface,-br)) {
1291 reply.setErrMsg(
"add link: requested link "
1292 "exceeds interface capacity");
1293 reply.setRrType(NEG_REPLY);
1296 if (!ift->addAvailPktRate(iface,-pr)) {
1297 reply.setErrMsg(
"add link: requested link "
1298 "exceeds interface capacity");
1299 reply.setRrType(NEG_REPLY);
1302 if ((peerType == ROUTER && pipp != Forest::ROUTER_PORT) ||
1303 (peerType != ROUTER && pipp == Forest::ROUTER_PORT) ||
1304 (lnk = lt->addEntry(lnk,pipa,pipp)) == 0) {
1305 ift->addAvailBitRate(iface,br);
1306 ift->addAvailPktRate(iface,pr);
1307 reply.setErrMsg(
"add link: cannot add "
1309 reply.setRrType(NEG_REPLY);
1314 if (peerType != ROUTER && padr != 0 && !allocLeafAdr(padr)) {
1315 ift->addAvailBitRate(iface,br);
1316 ift->addAvailPktRate(iface,pr);
1317 lt->removeEntry(lnk);
1318 reply.setErrMsg(
"add link: specified peer "
1319 "address is in use");
1320 reply.setRrType(NEG_REPLY);
1323 if (padr == 0) padr = allocLeafAdr();
1325 ift->addAvailBitRate(iface,br);
1326 ift->addAvailPktRate(iface,pr);
1327 lt->removeEntry(lnk);
1328 reply.setErrMsg(
"add link: no available "
1330 reply.setRrType(NEG_REPLY);
1333 lt->setIface(lnk,iface);
1334 lt->setPeerType(lnk,peerType);
1335 lt->setPeerAdr(lnk,padr);
1336 sm->clearLnkStats(lnk);
1338 reply.setAttr(LINK_NUM,lnk);
1339 reply.setAttr(PEER_ADR,padr);
1340 reply.setAttr(RTR_IP,ift->getIpAdr(iface));
1344 bool RouterCore::dropLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1345 if (!cp.isSet(LINK_NUM)) {
1346 reply.setErrMsg(
"drop link: missing required "
1348 reply.setRrType(NEG_REPLY);
1351 dropLink(cp.getAttr(LINK_NUM));
1355 void RouterCore::dropLink(
int lnk) {
1356 set<int>&
comtSet = lt->getComtSet(lnk);
1357 set<int>::iterator cp;
1358 int *comtVec =
new int[comtSet.size()];
int i = 0;
1359 for (cp = comtSet.begin(); cp != comtSet.end(); cp++) {
1363 int ctx = comtVec[i];
1364 int cLnk = ctt->getComtLink(ctt->getComtree(ctx),lnk);
1365 dropComtreeLink(ctx,lnk,cLnk);
1367 int iface = lt->getIface(lnk);
1368 ift->addAvailBitRate(iface,lt->getBitRate(lnk));
1369 ift->addAvailPktRate(iface,lt->getPktRate(lnk));
1370 lt->removeEntry(lnk);
1371 freeLeafAdr(lt->getPeerAdr(lnk));
1374 bool RouterCore::getLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1375 if (!cp.isSet(LINK_NUM)) {
1376 reply.setErrMsg(
"get link: missing required attribute");
1377 reply.setRrType(NEG_REPLY);
1380 int link = cp.getAttr(LINK_NUM);
1381 if (lt->valid(link)) {
1382 reply.setAttr(LINK_NUM, link);
1383 reply.setAttr(IFACE_NUM, lt->getIface(link));
1384 reply.setAttr(PEER_IP, lt->getPeerIpAdr(link));
1385 reply.setAttr(PEER_TYPE, lt->getPeerType(link));
1386 reply.setAttr(PEER_PORT, lt->getPeerPort(link));
1387 reply.setAttr(PEER_ADR, lt->getPeerAdr(link));
1388 reply.setAttr(AVAIL_BIT_RATE_IN,
1389 lt->getAvailInBitRate(link));
1390 reply.setAttr(AVAIL_PKT_RATE_IN,
1391 lt->getAvailInPktRate(link));
1392 reply.setAttr(AVAIL_BIT_RATE_OUT,
1393 lt->getAvailOutBitRate(link));
1394 reply.setAttr(AVAIL_PKT_RATE_OUT,
1395 lt->getAvailOutPktRate(link));
1396 reply.setAttr(BIT_RATE, lt->getBitRate(link));
1397 reply.setAttr(PKT_RATE, lt->getPktRate(link));
1400 reply.setErrMsg(
"get link: invalid link number");
1401 reply.setRrType(NEG_REPLY);
1405 bool RouterCore::modLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1406 if (!cp.isSet(LINK_NUM)) {
1407 reply.setErrMsg(
"modify link: missing required "
1409 reply.setRrType(NEG_REPLY);
1412 int link = cp.getAttr(LINK_NUM);
1413 if (lt->valid(link)) {
1414 reply.setAttr(LINK_NUM,link);
1415 int iface = lt->getIface(link);
1416 int br, dbr; br = dbr = 0;
1417 if (cp.isSet(BIT_RATE)) {
1418 br = cp.getAttr(BIT_RATE);
1419 dbr = br - lt->getBitRate(link);
1420 if (!ift->addAvailBitRate(iface,-dbr)) {
1421 reply.setErrMsg(
"mod link: request "
1422 "exceeds interface capacity");
1423 reply.setRrType(NEG_REPLY);
1426 lt->setBitRate(link, br);
1427 lt->addAvailInBitRate(link, dbr);
1428 lt->addAvailOutBitRate(link, dbr);
1429 qm->setLinkRates(link,br,lt->getPktRate(link));
1431 if (cp.isSet(PKT_RATE)) {
1432 int pr = cp.getAttr(PKT_RATE);
1433 int dpr = pr - lt->getPktRate(link);
1434 if (!ift->addAvailPktRate(iface,-dpr)) {
1435 if (cp.isSet(BIT_RATE)) {
1436 ift->addAvailBitRate(iface,dbr);
1437 lt->setBitRate(link,br-dbr);
1438 lt->addAvailInBitRate(link, -dbr);
1439 lt->addAvailOutBitRate(link, -dbr);
1440 qm->setLinkRates(link,br-dbr,
1441 lt->getPktRate(link));
1443 reply.setErrMsg(
"mod link: request "
1444 "exceeds interface capacity");
1445 reply.setRrType(NEG_REPLY);
1448 lt->setPktRate(link, pr);
1449 lt->addAvailInPktRate(link, dpr);
1450 lt->addAvailOutPktRate(link, dpr);
1451 qm->setLinkRates(link,lt->getBitRate(link),pr);
1455 reply.setErrMsg(
"get link: invalid link number");
1456 reply.setRrType(NEG_REPLY);
1460 bool RouterCore::addComtree(
int p, CtlPkt& cp, CtlPkt& reply) {
1461 if (!cp.isSet(COMTREE_NUM)) {
1462 reply.setErrMsg(
"add comtree: missing required "
1464 reply.setRrType(NEG_REPLY);
1467 int comt = cp.getAttr(COMTREE_NUM);
1468 if(ctt->validComtree(comt) || ctt->addEntry(comt) != 0)
1470 reply.setErrMsg(
"add comtree: cannot add comtree");
1471 reply.setRrType(NEG_REPLY);
1475 bool RouterCore::dropComtree(
int p, CtlPkt& cp, CtlPkt& reply) {
1476 if (!cp.isSet(COMTREE_NUM)) {
1477 reply.setErrMsg(
"drop comtree: missing required "
1479 reply.setRrType(NEG_REPLY);
1482 int comt = cp.getAttr(COMTREE_NUM);
1483 int ctx = ctt->getComtIndex(comt);
1484 if (!ctt->validComtIndex(ctx))
1489 rt->purgeRoutes(comt);
1494 set<int>& linkSet = ctt->getLinks(ctx);
1495 set<int>::iterator pp;
1496 int *clnks =
new int[linkSet.size()];
int i = 0;
1497 for (pp = linkSet.begin(); pp != linkSet.end(); pp++) clnks[i++] = *pp;
1499 dropComtreeLink(ctx,ctt->getLink(clnks[i]),clnks[i]);
1503 ctt->removeEntry(ctx);
1507 bool RouterCore::getComtree(
int p, CtlPkt& cp, CtlPkt& reply) {
1508 if (!cp.isSet(COMTREE_NUM)) {
1509 reply.setErrMsg(
"get comtree: missing required "
1511 reply.setRrType(NEG_REPLY);
1514 comt_t comt = cp.getAttr(COMTREE_NUM);
1515 int ctx = ctt->getComtIndex(comt);
1517 reply.setErrMsg(
"get comtree: invalid comtree");
1518 reply.setRrType(NEG_REPLY);
1521 reply.setAttr(COMTREE_NUM,comt);
1522 reply.setAttr(CORE_FLAG,ctt->inCore(ctx));
1523 reply.setAttr(PARENT_LINK,ctt->getPlink(ctx));
1524 reply.setAttr(LINK_COUNT,ctt->getLinkCount(ctx));
1528 bool RouterCore::modComtree(
int p, CtlPkt& cp, CtlPkt& reply) {
1529 if (!cp.isSet(COMTREE_NUM)) {
1530 reply.setErrMsg(
"modify comtree: missing required "
1532 reply.setRrType(NEG_REPLY);
1535 comt_t comt = cp.getAttr(COMTREE_NUM);
1536 int ctx = ctt->getComtIndex(comt);
1538 if (cp.isSet(CORE_FLAG))
1539 ctt->setCoreFlag(ctx,cp.getAttr(CORE_FLAG));
1540 if (cp.isSet(PARENT_LINK)) {
1541 int plnk = cp.getAttr(PARENT_LINK);
1542 if (plnk != 0 && !ctt->isLink(ctx,plnk)) {
1543 reply.setErrMsg(
"specified link does "
1544 "not belong to comtree");
1545 reply.setRrType(NEG_REPLY);
1548 if (plnk != 0 && !ctt->isRtrLink(ctx,plnk)) {
1549 reply.setErrMsg(
"specified link does "
1550 "not connect to a router");
1551 reply.setRrType(NEG_REPLY);
1554 ctt->setPlink(ctx,plnk);
1558 reply.setErrMsg(
"modify comtree: invalid comtree");
1559 reply.setRrType(NEG_REPLY);
1563 bool RouterCore::addComtreeLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1566 if (!(cp.isSet(COMTREE_NUM) &&
1567 (cp.isSet(LINK_NUM) ||
1568 (cp.isSet(PEER_IP) && cp.isSet(PEER_PORT))))) {
1569 reply.setErrMsg(
"add comtree link: missing required "
1571 reply.setRrType(NEG_REPLY);
1574 comt_t comt = cp.getAttr(COMTREE_NUM);
1575 int ctx = ctt->getComtIndex(comt);
1577 reply.setErrMsg(
"add comtree link: invalid comtree");
1578 reply.setRrType(NEG_REPLY);
1582 if (cp.isSet(LINK_NUM)) {
1583 lnk = cp.getAttr(LINK_NUM);
1584 }
else if (cp.isSet(PEER_IP) && cp.isSet(PEER_PORT)) {
1585 lnk = lt->lookup(cp.getAttr(PEER_IP),
1586 cp.getAttr(PEER_PORT));
1588 if (!lt->valid(lnk)) {
1589 reply.setErrMsg(
"add comtree link: invalid link or "
1590 "peer IP and port");
1591 reply.setRrType(NEG_REPLY);
1594 bool isRtr = (lt->getPeerType(lnk) == ROUTER);
1595 bool isCore =
false;
1597 if(!cp.isSet(PEER_CORE_FLAG)) {
1598 reply.setErrMsg(
"add comtree link: must "
1599 "specify core flag on links to routers");
1600 reply.setRrType(NEG_REPLY);
1603 isCore = cp.getAttr(PEER_CORE_FLAG);
1605 int cLnk = ctt->getComtLink(comt,lnk);
1607 if (ctt->isRtrLink(cLnk) == isRtr &&
1608 ctt->isCoreLink(cLnk) == isCore) {
1609 reply.setAttr(LINK_NUM,lnk);
1612 reply.setErrMsg(
"add comtree link: specified "
1613 "link already in comtree");
1614 reply.setRrType(NEG_REPLY);
1619 if (!ctt->addLink(ctx,lnk,isRtr,isCore)) {
1620 reply.setErrMsg(
"add comtree link: cannot add "
1621 "requested comtree link");
1622 reply.setRrType(NEG_REPLY);
1625 cLnk = ctt->getComtLink(comt,lnk);
1629 fAdr_t peerAdr = lt->getPeerAdr(lnk);
1630 if (lt->getPeerType(lnk) != ROUTER) {
1631 int rtx = rt->getRteIndex(comt,peerAdr);
1632 if (rtx == 0) rt->addEntry(comt,peerAdr,cLnk);
1634 int zipPeer = Forest::zipCode(peerAdr);
1635 if (zipPeer != Forest::zipCode(myAdr)) {
1636 fAdr_t dest = Forest::forestAdr(zipPeer,0);
1637 int rtx = rt->getRteIndex(comt,dest);
1638 if (rtx == 0) rt->addEntry(comt,dest,cLnk);
1643 int qid = qm->allocQ(lnk);
1645 ctt->removeLink(ctx,cLnk);
1646 reply.setErrMsg(
"add comtree link: no queues "
1647 "available for link");
1648 reply.setRrType(NEG_REPLY);
1651 ctt->setLinkQ(cLnk,qid);
1654 int br = Forest::MINBITRATE;
1655 int pr = Forest::MINPKTRATE;
1656 if (!(lt->addAvailInBitRate(lnk, -br) &&
1657 lt->addAvailInPktRate(lnk, -pr) &&
1658 lt->addAvailOutBitRate(lnk, -br) &&
1659 lt->addAvailOutPktRate(lnk, -pr))) {
1660 reply.setErrMsg(
"add comtree link: request "
1661 "exceeds link capacity");
1662 reply.setRrType(NEG_REPLY);
1665 ctt->setInBitRate(cLnk,br);
1666 ctt->setInPktRate(cLnk,pr);
1667 ctt->setOutBitRate(cLnk,br);
1668 ctt->setOutPktRate(cLnk,pr);
1670 qm->setQRates(qid,br,pr);
1671 if (isRtr) qm->setQLimits(qid,500,1000000);
1672 else qm->setQLimits(qid,500,1000000);
1673 sm->clearQuStats(qid);
1674 reply.setAttr(LINK_NUM,lnk);
1678 bool RouterCore::dropComtreeLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1681 if (!(cp.isSet(COMTREE_NUM) &&
1682 (cp.isSet(LINK_NUM) ||
1683 (cp.isSet(PEER_IP) && cp.isSet(PEER_PORT))))) {
1684 reply.setErrMsg(
"add comtree link: missing required "
1686 reply.setRrType(NEG_REPLY);
1689 comt_t comt = cp.getAttr(COMTREE_NUM);
1690 int ctx = ctt->getComtIndex(comt);
1692 reply.setErrMsg(
"drop comtree link: invalid comtree");
1693 reply.setRrType(NEG_REPLY);
1697 if (cp.isSet(LINK_NUM)) lnk = cp.getAttr(LINK_NUM);
1698 else lnk = lt->lookup(cp.getAttr(PEER_IP),cp.getAttr(PEER_PORT));
1699 if (!lt->valid(lnk)) {
1700 reply.setErrMsg(
"drop comtree link: invalid link "
1701 "or peer IP and port");
1702 reply.setRrType(NEG_REPLY);
1705 int cLnk = ctt->getComtLink(comt,lnk);
1707 dropComtreeLink(ctx,lnk,cLnk);
1712 void RouterCore::dropComtreeLink(
int ctx,
int lnk,
int cLnk) {
1714 lt->addAvailInBitRate(lnk,ctt->getInBitRate(cLnk));
1715 lt->addAvailInPktRate(lnk,ctt->getInPktRate(cLnk));
1716 lt->addAvailOutBitRate(lnk,ctt->getOutBitRate(cLnk));
1717 lt->addAvailOutPktRate(lnk,ctt->getOutPktRate(cLnk));
1720 fAdr_t peerAdr = lt->getPeerAdr(lnk);
1721 int comt = ctt->getComtree(ctx);
1722 if (lt->getPeerType(lnk) != ROUTER) {
1723 int rtx = rt->getRteIndex(comt,peerAdr);
1724 if (rtx != 0) rt->removeEntry(rtx);
1726 int zipPeer = Forest::zipCode(peerAdr);
1727 if (zipPeer != Forest::zipCode(myAdr)) {
1728 fAdr_t dest = Forest::forestAdr(zipPeer,0);
1729 int rtx = rt->getRteIndex(comt,dest);
1730 if (rtx != 0) rt->removeEntry(rtx);
1739 set<int>& rteSet = ctt->getRteSet(cLnk);
1740 set<int>::iterator rp;
1741 int *routes =
new int[rteSet.size()];
1743 for (rp = rteSet.begin(); rp != rteSet.end(); rp++) routes[i++] = *rp;
1744 while (--i >= 0) rt->removeLink(routes[i],cLnk);
1749 int qid = ctt->getLinkQ(cLnk);
1751 if (!ctt->removeLink(ctx,cLnk)) {
1752 cerr <<
"dropComtreeLink: internal error detected "
1753 "final removeLink failed\n";
1757 bool RouterCore::modComtreeLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1758 if (!(cp.isSet(COMTREE_NUM) && cp.isSet(LINK_NUM))) {
1759 reply.setErrMsg(
"modify comtree link: missing required "
1761 reply.setRrType(NEG_REPLY);
1764 comt_t comt = cp.getAttr(COMTREE_NUM);
1765 int ctx = ctt->getComtIndex(comt);
1767 reply.setErrMsg(
"modify comtree link: invalid comtree");
1768 reply.setRrType(NEG_REPLY);
1771 int lnk = cp.getAttr(LINK_NUM);
1772 if (!lt->valid(lnk)) {
1773 reply.setErrMsg(
"modify comtree link: invalid link "
1775 reply.setRrType(NEG_REPLY);
1778 int cLnk = ctt->getComtLink(comt,lnk);
1780 reply.setErrMsg(
"modify comtree link: specified link "
1781 "not defined in specified comtree");
1782 reply.setRrType(NEG_REPLY);
1786 int ibr = ctt->getInBitRate(cLnk);
1787 int ipr = ctt->getInPktRate(cLnk);
1788 int obr = ctt->getOutBitRate(cLnk);
1789 int opr = ctt->getOutPktRate(cLnk);
1791 if (cp.isSet(BIT_RATE_IN)) ibr = cp.getAttr(BIT_RATE_IN);
1792 if (cp.isSet(PKT_RATE_IN)) ipr = cp.getAttr(PKT_RATE_IN);
1793 if (cp.isSet(BIT_RATE_OUT)) obr = cp.getAttr(BIT_RATE_OUT);
1794 if (cp.isSet(PKT_RATE_OUT)) opr = cp.getAttr(PKT_RATE_OUT);
1796 int dibr = ibr - ctt->getInBitRate(cLnk);
1797 int dipr = ipr - ctt->getInPktRate(cLnk);
1798 int dobr = obr - ctt->getOutBitRate(cLnk);
1799 int dopr = opr - ctt->getOutPktRate(cLnk);
1801 bool success =
true;
1802 if (lt->getAvailInBitRate(lnk) < dibr) {
1803 reply.setErrMsg(
"modify comtree link: increase in "
1804 "input bit rate exceeds link capacity");
1807 if (lt->getAvailInPktRate(lnk) < dipr) {
1808 reply.setErrMsg(
"modify comtree link: increase in "
1809 "input packet rate exceeds link capacity");
1812 if (lt->getAvailOutBitRate(lnk) < dobr) {
1813 reply.setErrMsg(
"modify comtree link: increase in "
1814 "output bit rate exceeds link capacity");
1817 if (lt->getAvailOutPktRate(lnk) < dopr) {
1818 reply.setErrMsg(
"modify comtree link: increase in "
1819 "output packet rate exceeds link capacity");
1822 if (!success) { reply.setRrType(NEG_REPLY);
return false; }
1825 lt->addAvailInBitRate(lnk,-dibr); ctt->setInBitRate(cLnk,ibr);
1828 lt->addAvailInPktRate(lnk,-dipr); ctt->setInPktRate(cLnk,ipr);
1831 lt->addAvailOutBitRate(lnk,-dobr); ctt->setOutBitRate(cLnk,obr);
1834 lt->addAvailOutPktRate(lnk,-dopr); ctt->setOutPktRate(cLnk,opr);
1839 bool RouterCore::getComtreeLink(
int p, CtlPkt& cp, CtlPkt& reply) {
1840 if (!(cp.isSet(COMTREE_NUM) && cp.isSet(LINK_NUM))) {
1841 reply.setErrMsg(
"get comtree link: missing required "
1843 reply.setRrType(NEG_REPLY);
1846 comt_t comt = cp.getAttr(COMTREE_NUM);
1847 int ctx = ctt->getComtIndex(comt);
1849 reply.setErrMsg(
"get comtree link: invalid comtree");
1850 reply.setRrType(NEG_REPLY);
1853 int lnk = cp.getAttr(LINK_NUM);
1854 if (!lt->valid(lnk)) {
1855 reply.setErrMsg(
"get comtree link: invalid link "
1857 reply.setRrType(NEG_REPLY);
1860 int cLnk = ctt->getComtLink(comt,lnk);
1862 reply.setErrMsg(
"get comtree link: specified link "
1863 "not defined in specified comtree");
1864 reply.setRrType(NEG_REPLY);
1867 reply.setAttr(COMTREE_NUM,comt);
1868 reply.setAttr(LINK_NUM,lnk);
1869 reply.setAttr(QUEUE_NUM,ctt->getLinkQ(cLnk));
1870 reply.setAttr(PEER_DEST,ctt->getDest(cLnk));
1871 reply.setAttr(BIT_RATE_IN,ctt->getInBitRate(cLnk));
1872 reply.setAttr(PKT_RATE_IN,ctt->getInPktRate(cLnk));
1873 reply.setAttr(BIT_RATE_OUT,ctt->getOutBitRate(cLnk));
1874 reply.setAttr(PKT_RATE_OUT,ctt->getOutPktRate(cLnk));
1879 bool RouterCore::addRoute(
int p, CtlPkt& cp, CtlPkt& reply) {
1880 if (!(cp.isSet(COMTREE_NUM) && cp.isSet(DEST_ADR) &&
1881 cp.isSet(LINK_NUM))) {
1882 reply.setErrMsg(
"add route: missing required "
1884 reply.setRrType(NEG_REPLY);
1887 comt_t comt = cp.getAttr(COMTREE_NUM);
1888 if (!ctt->validComtree(comt)) {
1889 reply.setErrMsg(
"comtree not defined at this router\n");
1890 reply.setRrType(NEG_REPLY);
1893 fAdr_t dest = cp.getAttr(DEST_ADR);
1894 if (!Forest::validUcastAdr(dest) && !Forest::mcastAdr(dest)) {
1895 reply.setErrMsg(
"invalid address\n");
1896 reply.setRrType(NEG_REPLY);
1899 int lnk = cp.getAttr(LINK_NUM);
1900 int cLnk = ctt->getComtLink(comt,lnk);
1901 int rtx = rt->getRteIndex(comt,dest);
1903 if ((Forest::validUcastAdr(dest) && rt->getLink(rtx) == cLnk) ||
1904 (Forest::mcastAdr(dest) && rt->isLink(rtx,cLnk))) {
1907 reply.setErrMsg(
"add route: requested route "
1908 "conflicts with existing route");
1909 reply.setRrType(NEG_REPLY);
1912 }
else if (rt->addEntry(comt, dest, lnk)) {
1915 reply.setErrMsg(
"add route: cannot add route");
1916 reply.setRrType(NEG_REPLY);
1920 bool RouterCore::dropRoute(
int p, CtlPkt& cp, CtlPkt& reply) {
1921 if (!(cp.isSet(COMTREE_NUM) && cp.isSet(DEST_ADR))) {
1922 reply.setErrMsg(
"drop route: missing required "
1924 reply.setRrType(NEG_REPLY);
1927 comt_t comt = cp.getAttr(COMTREE_NUM);
1928 if (!ctt->validComtree(comt)) {
1929 reply.setErrMsg(
"comtree not defined at this router\n");
1930 reply.setRrType(NEG_REPLY);
1933 fAdr_t dest = cp.getAttr(DEST_ADR);
1934 if (!Forest::validUcastAdr(dest) && !Forest::mcastAdr(dest)) {
1935 reply.setErrMsg(
"invalid address\n");
1936 reply.setRrType(NEG_REPLY);
1939 int rtx = rt->getRteIndex(comt,dest);
1940 rt->removeEntry(rtx);
1944 bool RouterCore::getRoute(
int p, CtlPkt& cp, CtlPkt& reply) {
1945 if (!(cp.isSet(COMTREE_NUM) && cp.isSet(DEST_ADR))) {
1946 reply.setErrMsg(
"get route: missing required "
1948 reply.setRrType(NEG_REPLY);
1951 comt_t comt = cp.getAttr(COMTREE_NUM);
1952 if (!ctt->validComtree(comt)) {
1953 reply.setErrMsg(
"comtree not defined at this router\n");
1954 reply.setRrType(NEG_REPLY);
1957 fAdr_t dest = cp.getAttr(DEST_ADR);
1958 if (!Forest::validUcastAdr(dest) && !Forest::mcastAdr(dest)) {
1959 reply.setErrMsg(
"invalid address\n");
1960 reply.setRrType(NEG_REPLY);
1963 int rtx = rt->getRteIndex(comt,dest);
1965 reply.setAttr(COMTREE_NUM,comt);
1966 reply.setAttr(DEST_ADR,dest);
1967 if (Forest::validUcastAdr(dest)) {
1968 int lnk = ctt->getLink(rt->getLink(rtx));
1969 reply.setAttr(LINK_NUM,lnk);
1971 reply.setAttr(LINK_NUM,0);
1975 reply.setErrMsg(
"get route: no route for specified address");
1976 reply.setRrType(NEG_REPLY);
1980 bool RouterCore::modRoute(
int p, CtlPkt& cp, CtlPkt& reply) {
1981 if (!(cp.isSet(COMTREE_NUM) && cp.isSet(DEST_ADR))) {
1982 reply.setErrMsg(
"mod route: missing required "
1984 reply.setRrType(NEG_REPLY);
1987 comt_t comt = cp.getAttr(COMTREE_NUM);
1988 if (!ctt->validComtree(comt)) {
1989 reply.setErrMsg(
"comtree not defined at this router\n");
1990 reply.setRrType(NEG_REPLY);
1993 fAdr_t dest = cp.getAttr(DEST_ADR);
1994 if (!Forest::validUcastAdr(dest) && !Forest::mcastAdr(dest)) {
1995 reply.setErrMsg(
"invalid address\n");
1996 reply.setRrType(NEG_REPLY);
1999 int rtx = rt->getRteIndex(comt,dest);
2001 if (cp.isSet(LINK_NUM)) {
2002 if (Forest::mcastAdr(dest)) {
2003 reply.setErrMsg(
"modify route: cannot "
2004 "set link in multicast route");
2005 reply.setRrType(NEG_REPLY);
2008 rt->setLink(rtx,cp.getAttr(LINK_NUM));
2012 reply.setErrMsg(
"modify route: invalid route");
2013 reply.setRrType(NEG_REPLY);
2029 bool RouterCore::bootComplete(
int p, CtlPkt& cp, CtlPkt& reply) {
2030 if (booting && !setup()) {
2031 cerr <<
"RouterCore::bootComplete: setup failed after "
2032 "completion of boot phase\n";
2034 reply.setErrMsg(
"configured tables are not consistent\n");
2035 reply.setRrType(NEG_REPLY);
2036 returnToSender(p,reply.pack(
ps->getPayload(p)));
2037 pktLog->write(cout);
2043 bool RouterCore::bootAbort(
int p, CtlPkt& cp, CtlPkt& reply) {
2044 cerr <<
"RouterCore::bootAbort: received boot abort message "
2045 "from netMgr; exiting\n";
2046 reply.setRrType(POS_REPLY);
2047 returnToSender(p,reply.pack(
ps->getPayload(p)));
2048 pktLog->write(cout);
2060 bool RouterCore::sendCpReq(CtlPkt& cp,
fAdr_t dest) {
2063 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
2067 PacketHeader& h =
ps->getHeader(p);
2070 cp.setRrType(REQUEST);
2071 cp.setSeqNum(seqNum);
2072 int paylen = cp.pack(
ps->getPayload(p));
2074 cerr <<
"RouterCore::sendCpReq: control packet packing error\n";
2077 h.setLength(Forest::OVERHEAD + paylen);
2078 h.setPtype(NET_SIG); h.setFlags(0);
2079 h.setComtree(Forest::NET_SIG_COMT);
2080 h.setSrcAdr(myAdr); h.setDstAdr(dest);
2085 pair<uint64_t,CpInfo> cpp;
2087 cpp.second.p = p; cpp.second.nSent = 1; cpp.second.timestamp = now;
2088 pending->insert(cpp);
2094 cerr <<
"RouterCore::sendCpReq: no packets left in packet "
2100 pktLog->log(copy,0,
true,now);
2102 forward(copy,ctt->getComtIndex(h.getComtree()));
2114 void RouterCore::resendCpReq() {
2115 map<uint64_t,CpInfo>::iterator pp;
2116 for (pp = pending->begin(); pp != pending->end(); pp++) {
2117 if (now < pp->second.timestamp + 1000000000)
continue;
2118 int p = pp->second.p;
2119 PacketHeader h =
ps->getHeader(p);
2120 if (pp->second.nSent >= 3) {
2122 cerr <<
"RouterCore::resendCpReq: received no reply to "
2123 "control packet after three attempts\n"
2124 << h.toString(
ps->getBuffer(p),s);
2126 pending->erase(pp->first);
2130 cout <<
"resending control packet\n"
2131 << h.toString(
ps->getBuffer(p),s1);
2133 pp->second.timestamp = now;
2137 cerr <<
"RouterCore::resendCpReq: no packets left in "
2142 pktLog->log(copy,0,
true,now);
2145 forward(copy,ctt->getComtIndex(h.getComtree()));
2158 void RouterCore::handleCpReply(
int reply, CtlPkt& cpr) {
2159 PacketHeader hr =
ps->getHeader(reply);
2160 map<uint64_t,CpInfo>::iterator pp = pending->find(cpr.getSeqNum());
2161 if (pp == pending->end()) {
2172 switch (cpr.getCpType()) {
2173 case CLIENT_CONNECT:
case CLIENT_DISCONNECT:
2174 if (cpr.getRrType() == NEG_REPLY) {
2175 cerr <<
"RouterCore::handleCpReply: got negative reply "
2176 "to a connect or disconnect request: "
2177 << cpr.getErrMsg() << endl;
2182 case BOOT_REQUEST: {
2183 if (cpr.getRrType() == NEG_REPLY) {
2184 cerr <<
"RouterCore::handleCpReply: got "
2185 "negative reply to a boot request: "
2186 << cpr.getErrMsg() << endl;
2190 if (!(cpr.isSet(FIRST_LEAF_ADR) && cpr.isSet(LAST_LEAF_ADR))) {
2191 cerr <<
"RouterCore::handleCpReply: reply to boot "
2192 "request did not include leaf address range\n";
2195 firstLeafAdr = cpr.getAttr(FIRST_LEAF_ADR);
2196 fAdr_t lastLeafAdr = cpr.getAttr(LAST_LEAF_ADR);
2197 if (firstLeafAdr > lastLeafAdr) {
2198 cerr <<
"RouterCore::handleCpReply: reply to boot "
2199 "request contained empty leaf address range\n";
2202 leafAdr =
new UiSetPair((lastLeafAdr - firstLeafAdr)+1);
2206 cerr <<
"RouterCore::handleCpReply: unexpected control packet "
2218 void RouterCore::returnToSender(packet p,
int paylen) {
2219 PacketHeader& h =
ps->getHeader(p);
2221 cerr <<
"RouterCore::returnToSender: control packet formatting "
2222 "error, zero payload length\n";
2225 h.setLength(Forest::OVERHEAD + paylen);
2227 h.setDstAdr(h.getSrcAdr());
2233 pktLog->log(p,0,
true,now);
2238 int cLnk = ctt->getComtLink(h.getComtree(),h.getInLink());
2239 int qn = ctt->getLinkQ(cLnk);
2240 if (!qm->enq(p,qn,now)) {
ps->
free(p); }