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) {
67 sscanf(&argv[i][8],
"%d",&runtime);
70 cerr <<
"unrecognized argument: " << argv[i] << endl;
74 if (args.
mode.compare(
"local") == 0 &&
77 cerr <<
"processArgs: local configuration requires myAdr, "
78 "firstLeafAdr, lastLeafAdr and that firstLeafAdr "
79 "be no larger than lastLeafAdr\n";
81 }
else if (args.
mode.compare(
"remote") == 0 &&
84 cerr <<
"processArgs: remote configuration requires bootIp, "
85 "myAdr, netMgrIp and netMgrAdr\n";
93 int main(
int argc,
char *argv[]) {
96 Util::fatal(
"Router:: error processing command line arguments");
99 if (args.
mode.compare(
"local") == 0) {
101 Util::fatal(
"Router::main: could not complete local "
115 int nIfaces = 50;
int nLnks = 1000;
116 int nComts = 5000;
int nRts = 100000;
117 int nPkts = 100000;
int nBufs = 50000;
124 ccAdr = config.
ccAdr;
137 qm =
new QuManager(nLnks, nPkts, nQus, min(50,5*nPkts/nLnks),
139 sock =
new int[nIfaces+1];
145 leafAdr =
new ListPair((lastLeafAdr - firstLeafAdr)+1);
146 }
catch (std::bad_alloc e) {
147 Util::fatal(
"Router: unable to allocate space for Router");
150 if (config.
mode.compare(
"local") == 0) {
151 if (!readTables(config) || !setup())
152 Util::fatal(
"Router: could not complete local "
158 tZero = high_resolution_clock::now();
163 delete rip;
delete rop;
delete rop;
164 delete pktLog;
delete qm;
delete sm;
165 delete rt;
delete ctt;
delete lt;
delete ift;
delete ps;
166 delete leafAdr;
delete [] sock;
171 unique_lock<mutex> lck(snLock);
172 uint64_t sn = ++seqNum;
183 if (config.
ifTbl.compare(
"") != 0) {
184 ifstream fs; fs.open(config.
ifTbl.c_str());
185 if (fs.fail() || !ift->read(fs)) {
186 cerr <<
"Router::readTables: can't read "
187 <<
"interface table\n";
192 if (config.
lnkTbl.compare(
"") != 0) {
193 ifstream fs; fs.open(config.
lnkTbl.c_str());
194 if (fs.fail() || !lt->read(fs)) {
195 cerr <<
"Router::readTables: can't read "
201 if (config.
comtTbl.compare(
"") != 0) {
202 ifstream fs; fs.open(config.
comtTbl.c_str());
203 if (fs.fail() || !ctt->read(fs)) {
204 cerr <<
"Router::readTables: can't read "
205 <<
"comtree table\n";
210 if (config.
rteTbl.compare(
"") != 0) {
211 ifstream fs; fs.open(config.
rteTbl.c_str());
212 if (fs.fail() || !rt->read(fs)) {
213 cerr <<
"Router::readTables: can't read "
214 <<
"routing table\n";
219 if (config.
statSpec.compare(
"") != 0) {
220 ifstream fs; fs.open(config.
statSpec.c_str());
221 if (fs.fail() || !sm->read(fs)) {
222 cerr <<
"Router::readTables: can't read "
223 <<
"statistics spec\n";
237 if (!setupAllIfaces())
return false;
238 if (!setupLeafAddresses())
return false;
239 if (!setupQueues())
return false;
240 if (!checkTables())
return false;
241 if (!setAvailRates())
return false;
252 for (
int iface = ift->firstIface(); iface != 0;
253 iface = ift->nextIface(iface)) {
254 if (sock[iface] > 0)
continue;
255 if (setupIface(iface)) {
256 cerr <<
"Router::setupIfaces: could not "
257 "setup interface " << iface << endl;
273 cerr <<
"Router::setup: socket call failed\n";
276 maxSockNum = max(maxSockNum, sock[i]);
282 cerr <<
"Router::setup: bind call failed for ("
284 <<
", " << ifte.
port <<
") check interface's IP "
285 <<
"address and port\n";
299 for (
int lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
302 if (!allocLeafAdr(lte.
peerAdr))
316 for (
int lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
318 qm->setLinkRates(lnk,lte.
rates);
323 for (ctx = ctt->firstComt(); ctx != 0; ctx = ctt->nextComt(ctx)) {
324 for (
int cLnk = ctt->firstComtLink(ctx); cLnk != 0;
325 cLnk = ctt->nextComtLink(ctx,cLnk)) {
326 int lnk = ctt->getLink(ctx,cLnk);
327 int qid = qm->allocQ(lnk);
328 if (qid == 0)
return false;
329 ctt->setLinkQ(ctx,cLnk,qid);
330 qm->setQRates(qid,rs);
332 qm->setQLimits(qid,100,200000);
334 qm->setQLimits(qid,50,100000);
335 sm->clearQuStats(qid);
352 if (!ift->valid(ift->getDefaultIface())) {
353 cerr <<
"Router::checkTables: specified default iface "
354 << ift->getDefaultIface() <<
" is invalid\n";
358 for (iface = ift->firstIface(); iface != 0;
359 iface = ift->nextIface(iface)) {
360 if (ift->getEntry(iface).ipa == 0) {
361 cerr <<
"Router::checkTables: interface "
362 << iface <<
" has zero for IP address\n";
372 for (lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
374 if (!ift->valid(lte.
iface)) {
375 cerr <<
"Router::checkTables: interface " << iface
376 <<
" for link " << lnk <<
" is not valid\n";
380 cerr <<
"Router::checkTables: invalid peer IP "
381 <<
"for link " << lnk << endl;
385 cerr <<
"Router::checkTables: invalid peer address "
386 <<
"for link " << lnk << endl;
395 for (ctx = ctt->firstComt(); ctx != 0;
396 ctx = ctt->nextComt(ctx)) {
397 int comt = ctt->getComtree(ctx);
398 int plnk = ctt->getPlink(ctx);
399 int pcLnk = ctt->getPClink(ctx);
400 if (plnk != ctt->getLink(ctx,pcLnk)) {
401 cerr <<
"Router::checkTables: parent link "
402 << plnk <<
" not consistent with pcLnk\n";
405 if (ctt->inCore(ctx) && plnk != 0 &&
406 !ctt->isCoreLink(ctx,pcLnk)) {
407 cerr <<
"Router::checkTables: parent link "
408 << plnk <<
" of core node does not lead to "
409 <<
"another core node\n";
412 for (
int cLnk = ctt->firstComtLink(ctx); cLnk != 0;
413 cLnk = ctt->nextComtLink(ctx,cLnk)) {
414 int lnk = ctt->getLink(ctx,cLnk);
415 if (!lt->valid(lnk)) {
416 cerr <<
"Router::checkTables: link "
417 << lnk <<
" in comtree " << comt
418 <<
" not in link table" << endl;
422 fAdr_t dest = ctt->getDest(ctx,cLnk);
424 cerr <<
"Router::checkTables: dest addr "
425 <<
"for " << lnk <<
" in comtree " << comt
426 <<
" is not valid" << endl;
429 int qid = ctt->getLinkQ(ctx,cLnk);
431 cerr <<
"Router::checkTables: queue id "
432 <<
"for " << lnk <<
" in comtree " << comt
433 <<
" is zero" << endl;
438 for (
int cLnk = ctt->firstRtrLink(ctx); cLnk != 0;
439 cLnk = ctt->nextRtrLink(ctx,cLnk)) {
440 int lnk = ctt->getLink(ctx,cLnk);
441 if (!ctt->isLink(ctx,lnk)) {
442 cerr <<
"Router::checkTables: router link "
443 << lnk <<
" is not valid in comtree "
448 cerr <<
"Router::checkTables: router link "
449 << lnk <<
" in comtree " << comt
450 <<
" connects to non-router peer\n";
454 for (
int cLnk = ctt->firstCoreLink(ctx); cLnk != 0;
455 cLnk = ctt->nextCoreLink(ctx,cLnk)) {
456 int lnk = ctt->getLink(ctx,cLnk);
457 if (!ctt->isRtrLink(ctx,lnk)) {
458 cerr <<
"Router::checkTables: core link "
459 << lnk <<
" is not a router link "
481 for (iface = ift->firstIface(); iface != 0;
482 iface = ift->nextIface(iface)) {
485 cerr <<
"Router::setAvailRates: interface rates "
486 "outside allowed range\n";
491 if (!success)
return false;
493 for (lnk = lt->firstLink(); lnk != 0; lnk = lt->nextLink(lnk)) {
496 cerr <<
"Router::setAvailRates: link rates "
497 "outside allowed range\n";
503 cerr <<
"Router::setAvailRates: oversubscribing "
504 "interface " << iface << endl;
510 sm->clearLnkStats(lnk);
512 if (!success)
return false;
514 for (ctx = ctt->firstComt(); ctx != 0;
515 ctx = ctt->nextComt(ctx)) {
516 for (
int cLnk = ctt->firstComtLink(ctx); cLnk != 0;
517 cLnk = ctt->nextComtLink(ctx,cLnk)) {
518 int lnk = ctt->getLink(ctx,cLnk);
520 RateSpec comtRates = ctt->getRates(ctx, cLnk);
522 cerr <<
"Router::setAvailRates: "
523 "oversubscribing link "
537 for (
int ctx = ctt->firstComt(); ctx != 0; ctx = ctt->nextComt(ctx)) {
538 int comt = ctt->getComtree(ctx);
539 for (
int cLnk = ctt->firstComtLink(ctx); cLnk != 0;
540 cLnk = ctt->nextComtLink(ctx,cLnk)) {
541 int lnk = ctt->getLink(ctx,cLnk);
547 if (rt->getRtx(comt,lte.
peerAdr) != 0)
549 rt->addRoute(comt,lte.
peerAdr,cLnk);
558 out <<
"Interface Table\n\n" << ift->toString() << endl;
559 out <<
"Link Table\n\n" << lt->toString() << endl;
560 out <<
"Comtree Table\n\n" << ctt->toString() << endl;
561 out <<
"Routing Table\n\n" << rt->toString() << endl;
562 out <<
"Statistics\n\n" << sm->toString() << endl;
568 thread outThred(RouterOutProc::start,rop);