⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 click-align.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * click-align.cc -- alignment enforcer for Click configurations * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2007 Regents of the University of California * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/pathvars.h>#include <click/error.hh>#include <click/confparse.hh>#include <click/straccum.hh>#include <click/driver.hh>#include "lexert.hh"#include "routert.hh"#include "alignment.hh"#include "alignclass.hh"#include "elementmap.hh"#include "toolutils.hh"#include <click/clp.h>#include <stdio.h>#include <ctype.h>#include <algorithm>static ElementMap element_map;struct RouterAlign {    RouterT *_router;    Vector<int> _icount;    Vector<int> _ocount;    Vector<int> _ioffset;    Vector<int> _ooffset;    Vector<Alignment> _ialign;    Vector<Alignment> _oalign;    Vector<Aligner *> _aligners;    RouterAlign(RouterT *, ErrorHandler *);  int iindex_eindex(int) const;  int iindex_port(int) const;  int oindex_eindex(int) const;  int oindex_port(int) const;  bool have_input();  void have_output();  void want_input();  bool want_output();  void adjust();  void print(FILE *);};RouterAlign::RouterAlign(RouterT *r, ErrorHandler *errh)    : _router(r){  int ne = r->nelements();  int id = 0, od = 0;  for (int i = 0; i < ne; i++) {    _ioffset.push_back(id);    _ooffset.push_back(od);    ElementT *e = r->element(i);    _icount.push_back(e->ninputs());    _ocount.push_back(e->noutputs());    id += e->ninputs();    od += e->noutputs();  }  _ioffset.push_back(id);  _ooffset.push_back(od);  // set alignments  _ialign.assign(id, Alignment());  _oalign.assign(od, Alignment());  // find aligners  _aligners.assign(_router->nelements(), default_aligner());  for (RouterT::iterator x = _router->begin_elements(); x; x++) {    AlignClass *eclass = (AlignClass *)x->type()->cast("AlignClass");    if (eclass)      _aligners[x->eindex()] = eclass->create_aligner(x, _router, errh);  }}intRouterAlign::iindex_eindex(int ii) const{  int ne = _icount.size();  for (int i = 0; i < ne; i++)    if (ii < _ioffset[i+1])      return i;  return -1;}intRouterAlign::iindex_port(int ii) const{  int ne = _icount.size();  for (int i = 0; i < ne; i++)    if (ii < _ioffset[i+1])      return ii - _ioffset[i];  return -1;}intRouterAlign::oindex_eindex(int oi) const{  int ne = _icount.size();  for (int i = 0; i < ne; i++)    if (oi < _ooffset[i+1])      return i;  return -1;}intRouterAlign::oindex_port(int oi) const{  int ne = _icount.size();  for (int i = 0; i < ne; i++)    if (oi < _ooffset[i+1])      return oi - _ooffset[i];  return -1;}voidRouterAlign::have_output(){  int ne = _icount.size();  for (int i = 0; i < ne; i++) {      Traits t = element_map.traits(_router->etype_name(i));      _aligners[i]->have_flow(_ialign.begin() + _ioffset[i], _icount[i],			      _oalign.begin() + _ooffset[i], _ocount[i],			      _router->element(i)->flow_code());  }}boolRouterAlign::have_input(){  const Vector<ConnectionT> &conn = _router->connections();  int nh = conn.size();  int nialign = _ialign.size();  Vector<Alignment> new_ialign(nialign, Alignment());  for (int i = 0; i < nh; i++)    if (conn[i].live()) {      int ioff = _ioffset[conn[i].to_eindex()] + conn[i].to_port();      int ooff = _ooffset[conn[i].from_eindex()] + conn[i].from_port();      new_ialign[ioff] |= _oalign[ooff];    }  // see if anything happened  bool changed = false;  for (int i = 0; i < nialign && !changed; i++)    if (new_ialign[i] != _ialign[i])      changed = true;  _ialign.swap(new_ialign);  return changed;}voidRouterAlign::want_input(){  int ne = _icount.size();  for (int i = 0; i < ne; i++) {      Traits t = element_map.traits(_router->etype_name(i));      _aligners[i]->want_flow(_ialign.begin() + _ioffset[i], _icount[i],			      _oalign.begin() + _ooffset[i], _ocount[i],			      _router->element(i)->flow_code());  }}boolRouterAlign::want_output(){  const Vector<ConnectionT> &conn = _router->connections();  int nh = conn.size();  int noalign = _oalign.size();  Vector<Alignment> new_oalign(noalign, Alignment());  for (int i = 0; i < nh; i++)    if (conn[i].live()) {      int ioff = _ioffset[conn[i].to_eindex()] + conn[i].to_port();      int ooff = _ooffset[conn[i].from_eindex()] + conn[i].from_port();      new_oalign[ooff] &= _ialign[ioff];    }  /* for (int i = 0; i < noalign; i++)    if (new_oalign[i].bad())      new_oalign[i] = Alignment(); */  // see if anything happened  bool changed = false;  for (int i = 0; i < noalign && !changed; i++)    if (new_oalign[i] != _oalign[i]) {      /* fprintf(stderr, "%s[%d] %s <- %s\n", _router->ename(oindex_eindex(i)).c_str(), oindex_port(i), new_oalign[i].s().c_str(), _oalign[i].s().c_str()); */      changed = true;    }  _oalign.swap(new_oalign);  return changed;}voidRouterAlign::adjust(){  int ne = _icount.size();  for (int i = 0; i < ne; i++)      _aligners[i]->adjust_flow(_ialign.begin() + _ioffset[i], _icount[i],				_oalign.begin() + _ooffset[i], _ocount[i]);}voidRouterAlign::print(FILE *f){  for (RouterT::iterator x = _router->begin_elements(); x; x++) {    int i = x->eindex();    fprintf(f, "%s :", x->name_c_str());    for (int j = 0; j < _icount[i]; j++) {      const Alignment &a = _ialign[ _ioffset[i] + j ];      fprintf(f, " %d/%d", a.modulus(), a.offset());    }    fprintf(f, " -");    for (int j = 0; j < _ocount[i]; j++) {      const Alignment &a = _oalign[ _ooffset[i] + j ];      fprintf(f, " %d/%d", a.modulus(), a.offset());    }    fprintf(f, "\n");  }  fprintf(f, "\n");}static ElementClassT *class_factory(const String &name){    if (name == "Align")	return new AlignAlignClass;    if (name == "Strip" || name == "Unstrip")	return new StripAlignClass(name, name == "Strip");    if (name == "CheckIPHeader" || name == "CheckIPHeader2"	|| name == "MarkIPHeader")	return new CheckIPHeaderAlignClass(name);    if (name == "Classifier")	return new AlignClass(name, new ClassifierAligner);    if (name == "EtherEncap")	return new AlignClass(name, new ShifterAligner(-14));    if (name == "FromDevice" || name == "PollDevice" || name == "FromHost"	|| name == "SR2SetChecksum" || name == "SR2CheckHeader"	|| name == "SetSRChecksum" || name == "CheckSRHeader")	return new AlignClass(name, new GeneratorAligner(Alignment(4, 2)));    if (name == "InfiniteSource" || name == "RatedSource"	|| name == "ICMPError")	return new AlignClass(name, new GeneratorAligner(Alignment(4, 0)));    if (name == "ToHost")	return new AlignClass(name, new WantAligner(Alignment(4, 2)));    if (name == "IPEncap" || name == "UDPIPEncap" || name == "ICMPPingEncap"	|| name == "RandomUDPIPEncap" || name == "RoundRobinUDPIPEncap"	|| name == "RoundRobinTCPIPEncap")	return new AlignClass(name, new WantAligner(Alignment(4, 0)));    if (name == "ARPResponder" || name == "ARPQuerier")	return new AlignClass(name, new WantAligner(Alignment(2, 0)));    if (name == "IPInputCombo")	return new AlignClass(name, new CombinedAligner(new ShifterAligner(14),							new WantAligner(Alignment(4, 2))));    if (name == "GridEncap")	return new AlignClass(name, new CombinedAligner(new ShifterAligner(98),							new WantAligner(Alignment(4, 0))));    if (name == "Idle" || name == "Discard")	return new AlignClass(name, new NullAligner);    return new AlignClass(name, default_aligner());}#define HELP_OPT		300#define VERSION_OPT		301#define ROUTER_OPT		303#define EXPRESSION_OPT		304#define OUTPUT_OPT		305#define FIRST_DRIVER_OPT	1000#define USERLEVEL_OPT		(1000 + Driver::USERLEVEL)#define LINUXMODULE_OPT		(1000 + Driver::LINUXMODULE)#define BSDMODULE_OPT		(1000 + Driver::BSDMODULE)static const Clp_Option options[] = {  { "bsdmodule", 'b', BSDMODULE_OPT, 0, 0 },  { "expression", 'e', EXPRESSION_OPT, Clp_ValString, 0 },  { "file", 'f', ROUTER_OPT, Clp_ValString, 0 },  { "help", 0, HELP_OPT, 0, 0 },  { "linuxmodule", 'l', LINUXMODULE_OPT, 0, 0 },  { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 },  { "userlevel", 'u', USERLEVEL_OPT, 0, 0 },  { "version", 'v', VERSION_OPT, 0, 0 },};static const char *program_name;static int specified_driver = -1;voidshort_usage(){  fprintf(stderr, "Usage: %s [OPTION]... [ROUTERFILE]\n\Try '%s --help' for more information.\n",	  program_name, program_name);}voidusage(){  printf("\'Click-align' adds any required 'Align' elements to a Click router\n\configuration. The resulting router will work on machines that don't allow\n\unaligned accesses. Its configuration is written to the standard output.\n\\n\Usage: %s [OPTION]... [ROUTERFILE]\n\\n\Options:\n\  -f, --file FILE               Read router configuration from FILE.\n\  -e, --expression EXPR         Use EXPR as router configuration.\n\  -o, --output FILE             Write output to FILE.\n\      --help                    Print this message and exit.\n\  -v, --version                 Print version number and exit.\n\\n\Report bugs to <click@pdos.lcs.mit.edu>.\n", program_name);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -