📄 click-align.cc
字号:
/* * click-align.cc -- alignment enforcer for Click configurations * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * * 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/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 "toolutils.hh"#include <click/clp.h>#include <stdio.h>#include <ctype.h>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++) _aligners[i]->have_flow(_ialign, _ioffset[i], _icount[i], _oalign, _ooffset[i], _ocount[i]);}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++) _aligners[i]->want_flow(_ialign, _ioffset[i], _icount[i], _oalign, _ooffset[i], _ocount[i]);}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)).cc(), oindex_port(i), new_oalign[i].s().cc(), _oalign[i].s().cc()); */ 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, _ioffset[i], _icount[i], _oalign, _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.chunk(), a.offset()); } fprintf(f, " -"); for (int j = 0; j < _ocount[i]; j++) { const Alignment &a = _oalign[ _ooffset[i] + j ]; fprintf(f, " %d/%d", a.chunk(), a.offset()); } fprintf(f, "\n"); } fprintf(f, "\n");}voidprepare_classes(){ // specialized classes ElementClassT::set_base_type(new AlignAlignClass); ElementClassT::set_base_type(new StripAlignClass); ElementClassT::set_base_type(new CheckIPHeaderAlignClass("CheckIPHeader", 1)); ElementClassT::set_base_type(new CheckIPHeaderAlignClass("CheckIPHeader2", 1)); ElementClassT::set_base_type(new CheckIPHeaderAlignClass("MarkIPHeader", 0)); ElementClassT::set_base_type(new AlignClass("Classifier", new ClassifierAligner)); ElementClassT::set_base_type(new AlignClass("EtherEncap", new ShifterAligner(-14))); ElementClassT::set_base_type(new AlignClass("IPInputCombo", new CombinedAligner(new ShifterAligner(14), new WantAligner(Alignment(4, 2))))); ElementClassT::set_base_type(new AlignClass("GridEncap", new CombinedAligner(new ShifterAligner(98), new WantAligner(Alignment(4, 0))))); // no alignment requirements, and do not transmit packets between input and // output Aligner *a = new NullAligner; ElementClassT::set_base_type(new AlignClass("Idle", a)); ElementClassT::set_base_type(new AlignClass("Discard", a)); // generate alignment 4/2 a = new GeneratorAligner(Alignment(4, 2)); ElementClassT::set_base_type(new AlignClass("FromDevice", a)); ElementClassT::set_base_type(new AlignClass("PollDevice", a)); ElementClassT::set_base_type(new AlignClass("FromLinux", a)); // generate alignment 4/0 a = new GeneratorAligner(Alignment(4, 0)); ElementClassT::set_base_type(new AlignClass("RatedSource", a)); ElementClassT::set_base_type(new AlignClass("ICMPError", a)); // want alignment 4/2 a = new WantAligner(Alignment(4, 2)); ElementClassT::set_base_type(new AlignClass("ToLinux", a)); // want alignment 4/0 a = new WantAligner(Alignment(4, 0)); ElementClassT::set_base_type(new AlignClass("IPEncap", a)); ElementClassT::set_base_type(new AlignClass("UDPIPEncap", a)); ElementClassT::set_base_type(new AlignClass("ICMPPingEncap", a)); ElementClassT::set_base_type(new AlignClass("RandomUDPIPEncap", a)); ElementClassT::set_base_type(new AlignClass("RoundRobinUDPIPEncap", a)); ElementClassT::set_base_type(new AlignClass("RoundRobinTCPIPEncap", a)); // want alignment 2/0 a = new WantAligner(Alignment(2, 0)); ElementClassT::set_base_type(new AlignClass("ARPResponder", a)); ElementClassT::set_base_type(new AlignClass("ARPQuerier", a));}#define HELP_OPT 300#define VERSION_OPT 301#define ROUTER_OPT 303#define EXPRESSION_OPT 304#define OUTPUT_OPT 305static Clp_Option options[] = { { "expression", 'e', EXPRESSION_OPT, Clp_ArgString, 0 }, { "file", 'f', ROUTER_OPT, Clp_ArgString, 0 }, { "help", 0, HELP_OPT, 0, 0 }, { "output", 'o', OUTPUT_OPT, Clp_ArgString, 0 }, { "version", 'v', VERSION_OPT, 0, 0 },};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -