📄 click-align.cc
字号:
inline Stringaligner_name(int anonymizer){ return String("Align@click_align@") + String(anonymizer);}intmain(int argc, char **argv){ click_static_initialize(); CLICK_DEFAULT_PROVIDES; ErrorHandler *errh = ErrorHandler::default_handler(); PrefixErrorHandler p_errh(errh, "click-align: "); // read command line arguments Clp_Parser *clp = Clp_NewParser(argc, argv, sizeof(options) / sizeof(options[0]), options); Clp_SetOptionChar(clp, '+', Clp_ShortNegated); program_name = Clp_ProgramName(clp); const char *router_file = 0; bool file_is_expr = false; const char *output_file = 0; while (1) { int opt = Clp_Next(clp); switch (opt) { case HELP_OPT: usage(); exit(0); break; case VERSION_OPT: printf("click-align (Click) %s\n", CLICK_VERSION); printf("Copyright (C) 1999-2000 Massachusetts Institute of Technology\n\Copyright (C) 2007 Regents of the University of California\n\This is free software; see the source for copying conditions.\n\There is NO warranty, not even for merchantability or fitness for a\n\particular purpose.\n"); exit(0); break; case ROUTER_OPT: case EXPRESSION_OPT: router_file: if (router_file) { errh->error("router configuration specified twice"); goto bad_option; } router_file = clp->vstr; file_is_expr = (opt == EXPRESSION_OPT); break; case USERLEVEL_OPT: case LINUXMODULE_OPT: case BSDMODULE_OPT: if (specified_driver >= 0) { errh->error("driver specified twice"); goto bad_option; } specified_driver = opt - FIRST_DRIVER_OPT; break; case Clp_NotOption: if (!click_maybe_define(clp->vstr, errh)) goto router_file; break; case OUTPUT_OPT: if (output_file) { errh->error("output file specified twice"); goto bad_option; } output_file = clp->vstr; break; bad_option: case Clp_BadOption: short_usage(); exit(1); break; case Clp_Done: goto done; } } done: // read router ElementClassT::set_base_type_factory(class_factory); RouterT *router = read_router(router_file, file_is_expr, errh); if (router) router->flatten(errh); if (!router || errh->nerrors() > 0) exit(1); // get element map and processing element_map.parse_all_files(router, CLICK_DATADIR, &p_errh); // we know that Classifier requires alignment. If the element map does // not, complain loudly. if (!element_map.has_traits("Classifier")) { p_errh.warning("elementmap has no information for Classifier, muddling along"); p_errh.message("(This is usually because of a missing 'elementmap.xml'.\nYou may get errors when running this configuration.)"); const char *classes[] = { "Classifier", "IPClassifier", "IPFilter", "CheckIPHeader", "CheckIPHeader2", "UDPIPEncap", "IPInputCombo", 0 }; for (const char **sp = classes; *sp; ++sp) { ElementTraits t = element_map.traits(*sp); t.flags += "A"; element_map.add(t); } } // decide on a driver if (specified_driver >= 0) { if (!element_map.driver_compatible(router, specified_driver)) errh->warning("configuration not compatible with %s driver", Driver::name(specified_driver)); element_map.set_driver_mask(1 << specified_driver); } else { int driver_mask = 0; for (int d = 0; d < Driver::COUNT; d++) if (element_map.driver_compatible(router, d)) driver_mask |= 1 << d; if (driver_mask == 0) errh->warning("configuration not compatible with any driver"); else element_map.set_driver_mask(driver_mask); } // correct classes for router //correct_classes(driver_mask); ElementClassT *align_class = ElementClassT::base_type("Align"); assert(align_class); int original_nelements = router->nelements(); int anonymizer = original_nelements + 1; while (router->eindex(aligner_name(anonymizer)) >= 0) anonymizer++; /* * Add Align elements for required alignments */ int num_aligns_added = 0; { // calculate current alignment RouterAlign ral(router, errh); do { ral.have_output(); } while (ral.have_input()); // calculate desired alignment RouterAlign want_ral(router, errh); do { want_ral.want_input(); } while (want_ral.want_output()); // add required aligns for (int i = 0; i < original_nelements; i++) for (int j = 0; j < ral._icount[i]; j++) { Alignment have = ral._ialign[ ral._ioffset[i] + j ]; Alignment want = want_ral._ialign[ ral._ioffset[i] + j ]; if (have <= want || want.bad()) /* do nothing */; else { ElementT *e = router->get_element (aligner_name(anonymizer), align_class, String(want.modulus()) + ", " + String(want.offset()), LandmarkT("<click-align>")); router->insert_before(e, PortT(router->element(i), j)); anonymizer++; num_aligns_added++; } } } /* * remove duplicate Aligns (Align_1 -> Align_2) */ { const Vector<ConnectionT> &conn = router->connections(); int nhook = conn.size(); for (int i = 0; i < nhook; i++) if (conn[i].live() && conn[i].to_element()->type() == align_class && conn[i].from_element()->type() == align_class) { // skip over hf[i] Vector<PortT> above, below; router->find_connections_to(conn[i].from(), above); router->find_connections_from(conn[i].from(), below); if (below.size() == 1) { for (int j = 0; j < nhook; j++) if (conn[j].to() == conn[i].from()) router->change_connection_to(j, conn[i].to()); } else if (above.size() == 1) { for (int j = 0; j < nhook; j++) if (conn[j].to() == conn[i].to()) router->change_connection_from(j, above[0]); } } } /* * Add Aligns required for adjustment alignments * * Classifier is an example: it can cope with any alignment that is * consistent and has a modulus >= 4. Rather than require a specific * alignment above, we handle Classifier here; required alignments may * have generated an alignment we can deal with. */ { // calculate current alignment RouterAlign ral(router, errh); do { ral.have_output(); } while (ral.have_input()); // calculate adjusted alignment RouterAlign want_ral(ral); want_ral.adjust(); // add required aligns for (int i = 0; i < original_nelements; i++) for (int j = 0; j < ral._icount[i]; j++) { Alignment have = ral._ialign[ ral._ioffset[i] + j ]; Alignment want = want_ral._ialign[ ral._ioffset[i] + j ]; if (have <= want || want.bad()) /* do nothing */; else { ElementT *e = router->get_element (aligner_name(anonymizer), align_class, String(want.modulus()) + ", " + String(want.offset()), LandmarkT("<click-align>")); router->insert_before(e, PortT(router->element(i), j)); anonymizer++; num_aligns_added++; } } } while (1) { // calculate current alignment RouterAlign ral(router, errh); do { ral.have_output(); } while (ral.have_input()); bool changed = false; // skip redundant Aligns for (RouterT::conn_iterator ci = router->begin_connections(); ci != router->end_connections(); ++ci) if (ci->live() && ci->to_element()->type() == align_class) { Alignment have = ral._oalign[ ral._ooffset[ci->from_eindex()] + ci->from_port() ]; Alignment want = ral._oalign[ ral._ooffset[ci->to_eindex()] ]; if (have <= want) { changed = true; Vector<PortT> align_dest; router->find_connections_from(ci->to(), align_dest); for (int j = 0; j < align_dest.size(); j++) router->add_connection(ci->from(), align_dest[j]); router->kill_connection(ci); } } if (!changed) break; router->remove_duplicate_connections(); } // remove unused Aligns (they have no input) and old AlignmentInfos ElementClassT *aligninfo_class = ElementClassT::base_type("AlignmentInfo"); { for (RouterT::type_iterator x = router->begin_elements(aligninfo_class); x != router->end_elements(); ++x) x->full_kill(); bool again; do { again = false; for (RouterT::type_iterator x = router->begin_elements(align_class); x != router->end_elements(); ++x) if (x->ninputs() == 0 || x->noutputs() == 0) { if (x->landmark() == "<click-align>") num_aligns_added--; again = true; x->full_kill(); } } while (again); router->remove_dead_elements(); } // make the AlignmentInfo element { RouterAlign ral(router, errh); do { ral.have_output(); } while (ral.have_input()); // collect alignment information StringAccum sa; for (RouterT::iterator x = router->begin_elements(); x; x++) { ElementTraits t = element_map.traits(x->type_name()); if (x->ninputs() && t.flag_value('A') > 0) { if (sa.length()) sa << ",\n "; sa << x->name(); int i = x->eindex(); for (int j = 0; j < ral._icount[i]; j++) { const Alignment &a = ral._ialign[ ral._ioffset[i] + j ]; sa << " " << a.modulus() << " " << a.offset(); } } } if (sa.length()) router->get_element(String("AlignmentInfo@click_align@") + String(anonymizer), aligninfo_class, sa.take_string(), LandmarkT("<click-align>")); } // warn if added aligns if (num_aligns_added > 0) errh->warning((num_aligns_added > 1 ? "added %d Align elements" : "added %d Align element"), num_aligns_added); // write result if (write_router_file(router, output_file, errh) < 0) exit(1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -