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

📄 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 页
字号:
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 + -