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

📄 click-fastclassifier.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 页
字号:
      String step = program.substring(program.begin(), find(program, '\n'));      program = program.substring(step.end() + 1, program.end());      // check for many things      if (isdigit((unsigned char) step[0]) || isspace((unsigned char) step[0])) {	// real step	Classifier_Insn e;	int crap, pos;	int v[4], m[4];	sscanf(step.c_str(), "%d %d/%2x%2x%2x%2x%%%2x%2x%2x%2x yes->%n",	       &crap, &e.offset, &v[0], &v[1], &v[2], &v[3],	       &m[0], &m[1], &m[2], &m[3], &pos);	for (int i = 0; i < 4; i++) {	  e.value.c[i] = v[i];	  e.mask.c[i] = m[i];	}	// read yes destination	step = step.substring(pos);	if (step[0] == '[') {	  sscanf(step.c_str(), "[%d] no->%n", &e.yes, &pos);	  e.yes = -e.yes;	} else	  sscanf(step.c_str(), "step %d no->%n", &e.yes, &pos);	// read no destination	step = step.substring(pos);	if (step[0] == '[') {	  sscanf(step.c_str(), "[%d]", &e.no);	  e.no = -e.no;	} else	  sscanf(step.c_str(), "step %d", &e.no);	// push expr onto list	prog.program.push_back(e);      } else if (sscanf(step.c_str(), "all->[%d]", &prog.output_everything))	/* nada */;      else if (sscanf(step.c_str(), "safe length %d", &prog.safe_length))	/* nada */;      else if (sscanf(step.c_str(), "alignment offset %d", &prog.align_offset)) {	/* nada */;      }    }    // search for an existing fast classifier with the same program    bool found_program = false;    for (int i = 0; i < all_programs.size() && !found_program; i++)      if (prog == all_programs[i]) {	program_map.push_back(i);	found_program = true;      }    if (!found_program) {      // set new names      String class_name = "Fast" + classifier_tname + "@@" + c->name();      String cxx_name = translate_class_name(class_name);      prog.eclass = ElementClassT::base_type(class_name);      // add new program      all_programs.push_back(prog);      gen_eclass_names.push_back(class_name);      gen_cxxclass_names.push_back(cxx_name);      old_configurations.push_back(c->configuration());      program_map.push_back(all_programs.size() - 1);    }  }  // complain if any programs missing  for (int i = 0; i < iprograms.size(); i++)    if (program_map[i] < 0)      errh->fatal("classifier program missing for '%s :: %s'!", classifiers[i]->name_c_str(), classifiers[i]->type_name().c_str());}static voidoutput_classifier_program(int which,			  StringAccum &header, StringAccum &source,			  ErrorHandler *){  String cxx_name = gen_cxxclass_names[which];  String class_name = gen_eclass_names[which];  const Classifier_Program &prog = all_programs[which];  FastClassifier_Cid *cid = cids[prog.type];  if (cid->headers) {    cid->headers(prog, source);    cid->headers = 0;		// only call cid->headers once  }  header << "class " << cxx_name << " : public Element {\n\  void devirtualize_all() { }\n\ public:\n  "	 << cxx_name << "() { }\n  ~" << cxx_name << "() { }\n\  const char *class_name() const { return \"" << class_name << "\"; }\n\  const char *port_count() const { return \"1/" << prog.noutputs << "\"; }\n\  const char *processing() const { return PUSH; }\n";  if (prog.output_everything >= 0) {    header << "  void push(int, Packet *);\n};\n";    source << "void\n" << cxx_name << "::push(int, Packet *p)\n{\n";    if (prog.output_everything < prog.noutputs)      source << "  output(" << prog.output_everything << ").push(p);\n";    else      source << "  p->kill();\n";    source << "}\n";  } else {    bool need_checked = (prog.safe_length >= cid->guaranteed_packet_length);    if (need_checked) {      header << "  void length_checked_push(Packet *);\n";      source << "void\n" << cxx_name << "::length_checked_push(Packet *p)\n{\n";      cid->checked_body(prog, source);      source << "}\n";    }    header << "  inline void length_unchecked_push(Packet *);\n\  void push(int, Packet *);\n};\n";    source << "inline void\n" << cxx_name	   << "::length_unchecked_push(Packet *p)\n{\n";    cid->unchecked_body(prog, source);    source << "}\n";    source << "void\n" << cxx_name << "::push(int, Packet *p)\n{\n";    cid->push_body(prog, source);    source << "}\n";  }}static voidcompile_classifiers(RouterT *r, const String &package_name,		    RouterT *nr, Vector<ElementT *> &classifiers,		    int compile_drivers, ErrorHandler *errh){    // create C++ files    StringAccum header, source, source_body;    header << "#ifndef CLICK_" << package_name << "_HH\n"	   << "#define CLICK_" << package_name << "_HH\n"	   << "#include <click/package.hh>\n#include <click/element.hh>\n";    // analyze Classifiers into programs    analyze_classifiers(nr, classifiers, errh);    // add requirement    r->add_requirement(package_name);    // write Classifier programs    for (int i = 0; i < all_programs.size(); i++)	output_classifier_program(i, header, source_body, errh);    // change element landmarks and types    for (int i = 0; i < classifiers.size(); i++) {	ElementT *classifier_e = classifiers[i];	const Classifier_Program &prog = all_programs[program_map[i]];	classifier_e->set_type(prog.eclass);	classifier_e->set_configuration(String());	change_landmark(classifier_e);    }    // write final text    header << "#endif\n";    source << "/** click-compile: -w */\n";    {	StringAccum elem2package, cmd_sa;	int nclasses = gen_cxxclass_names.size();	for (int i = 0; i < nclasses; i++)	    elem2package <<  "-\t\"" << package_name << ".hh\"\t" << gen_cxxclass_names[i] << '-' << gen_eclass_names[i] << '\n';	cmd_sa << click_buildtool_prog << " elem2package " << package_name;	source << shell_command_output_string(cmd_sa.take_string(), elem2package.take_string(), errh);    }    source << "CLICK_DECLS\n" << source_body << "CLICK_ENDDECLS\n";    // add source files to archive    {	ArchiveElement ae = init_archive_element(package_name + ".cc", 0600);	ae.data = source.take_string();	r->add_archive(ae);	ae.name = package_name + ".hh";	ae.data = header.take_string();	r->add_archive(ae);    }    // add compiled versions to archive    if (compile_drivers) {	int source_ae = r->archive_index(package_name + ".cc");	BailErrorHandler berrh(errh);	bool tmpdir_populated = false;	if (compile_drivers & (1 << Driver::LINUXMODULE))	    if (String fn = click_compile_archive_file(r->archive(), &r->archive()[source_ae], package_name, "linuxmodule", "", tmpdir_populated, &berrh)) {		ArchiveElement ae = init_archive_element(package_name + ".ko", 0600);		ae.data = file_string(fn, errh);		r->add_archive(ae);	    }	if (compile_drivers & (1 << Driver::USERLEVEL))	    if (String fn = click_compile_archive_file(r->archive(), &r->archive()[source_ae], package_name, "userlevel", "", tmpdir_populated, &berrh)) {		ArchiveElement ae = init_archive_element(package_name + ".uo", 0600);		ae.data = file_string(fn, errh);		r->add_archive(ae);	    }    }    // add elementmap to archive    {	String emap_package = "elementmap-" + package_name + ".xml";	if (r->archive_index(emap_package) < 0)	    r->add_archive(init_archive_element(emap_package, 0600));	ArchiveElement &ae = r->archive(emap_package);	ElementMap em(ae.data);	ElementTraits t;	t.header_file = package_name + ".hh";	t.source_file = package_name + ".cc";	t.processing_code = "h/h";	t.flow_code = "x/x";	for (int i = 0; i < gen_eclass_names.size(); i++) {	    t.name = gen_eclass_names[i];	    t.cxx = gen_cxxclass_names[i];	    em.add(t);	}	ae.data = em.unparse("fastclassifier");    }    // add classifier configurations to archive    {	if (r->archive_index("fastclassifier_info") < 0)	    r->add_archive(init_archive_element("fastclassifier_info", 0600));	ArchiveElement &ae = r->archive("fastclassifier_info");	StringAccum sa;	for (int i = 0; i < gen_eclass_names.size(); i++) {	    sa << gen_eclass_names[i] << '\t'	       << cids[all_programs[i].type]->name << '\t'	       << cp_quote(old_configurations[i]) << '\n';	}	ae.data += sa.take_string();    }}static voidreverse_transformation(RouterT *r, ErrorHandler *){  // parse fastclassifier_config  if (r->archive_index("fastclassifier_info") < 0)    return;  ArchiveElement &fc_ae = r->archive("fastclassifier_info");  Vector<String> click_names, old_type_names, configurations;  parse_tabbed_lines(fc_ae.data, &click_names, &old_type_names,		     &configurations, (void *)0);  // prepare type_map : type -> configuration #  HashTable<ElementClassT *, int> type_map(-1);  for (int i = 0; i < click_names.size(); i++)    type_map.set(ElementClassT::base_type(click_names[i]), i);  // change configuration  for (int i = 0; i < r->nelements(); i++) {    ElementT *e = r->element(i);    int x = type_map.get(e->type());    if (x >= 0) {      e->set_configuration(configurations[x]);      e->set_type(ElementClassT::base_type(old_type_names[x]));    }  }  // remove requirements  {    Vector<String> requirements = r->requirements();    for (int i = 0; i < requirements.size(); i++)      if (requirements[i].substring(0, 14) == "fastclassifier")	r->remove_requirement(requirements[i]);  }  // remove archive elements  for (int i = 0; i < r->narchive(); i++) {    ArchiveElement &ae = r->archive(i);    if (ae.name.substring(0, 14) == "fastclassifier"	|| ae.name == "elementmap-fastclassifier.xml")      ae.name = String();  }}extern "C" {void add_fast_classifiers_1();void add_fast_classifiers_2();}intmain(int argc, char **argv){  click_static_initialize();  CLICK_DEFAULT_PROVIDES;  ErrorHandler *errh = new PrefixErrorHandler(ErrorHandler::default_handler(), "click-fastclassifier: ");  // 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;  const char *output_file = 0;  int compile_drivers = 0;  bool combine_classifiers = true;  bool do_compile = true;  bool source_only = false;  bool config_only = false;  bool reverse = false;  bool file_is_expr = false;  while (1) {    int opt = Clp_Next(clp);    switch (opt) {     case HELP_OPT:      usage();      exit(0);      break;     case VERSION_OPT:      printf("click-fastclassifier (Click) %s\n", CLICK_VERSION);      printf("Copyright (c) 1999-2000 Massachusetts Institute of Technology\n\Copyright (c) 2000-2001 Mazu Networks, Inc.\n\Copyright (c) 2001 International Computer Science Institute\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 CLICKPATH_OPT:      set_clickpath(clp->vstr);      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 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;     case COMBINE_OPT:      combine_classifiers = !clp->negated;      break;     case COMPILE_OPT:      do_compile = !clp->negated;      break;     case REVERSE_OPT:      reverse = !clp->negated;      break;     case SOURCE_OPT:      source_only = !clp->negated;      break;     case CONFIG_OPT:      config_only = !clp->negated;      break;     case KERNEL_OPT:      compile_drivers |= 1 << Driver::LINUXMODULE;      break;     case USERLEVEL_OPT:      compile_drivers |= 1 << Driver::USERLEVEL;      break;     case QUIET_OPT:      quiet_arg = (clp->negated ? "" : "-q ");      break;     case VERBOSE_OPT:      verbose = !clp->negated;      break;     bad_option:     case Clp_BadOption:      short_usage();      exit(1);      break;     case Clp_Done:      goto done;    }  } done:  RouterT *r = read_router(router_file, file_is_expr, errh);  if (r)    r->flatten(errh);  if (!r || errh->nerrors() > 0)    exit(1);  if (source_only || config_only)    compile_drivers = 0;  // open output file  FILE *outf = stdout;  if (output_file && strcmp(output_file, "-") != 0) {    outf = fopen(output_file, "w");    if (!outf)      errh->fatal("%s: %s", output_file, strerror(errno));  }  // handle reverse case  if (reverse) {    reverse_transformation(r, errh);    write_router_file(r, outf, errh);    exit(0);  }  // install classifier handlers  add_interesting_handler("program");  add_fast_classifiers_1();  add_fast_classifiers_2();  // find Click binaries  runclick_prog = clickpath_find_file("click", "bin", CLICK_BINDIR, errh);  click_buildtool_prog = clickpath_find_file("click-buildtool", "bin", CLICK_BINDIR, errh);  // find Classifiers  Vector<ElementT *> classifiers;  for (RouterT::iterator x = r->begin_elements(); x; x++)    if (cid_name_map.get(x->type_name()) >= 0)      classifiers.push_back(x);  // quit early if no Classifiers  if (classifiers.size() == 0) {    if (source_only)      errh->message("no Classifiers in router");    else      write_router_file(r, outf, errh);    exit(0);  }  // try combining classifiers  if (combine_classifiers) {    bool any_combined = false;    for (int i = 0; i < classifiers.size(); i++)      any_combined |= try_combine_classifiers(r, classifiers[i]);    if (any_combined)      try_remove_classifiers(r, classifiers);  }  // create classifiers program  RouterT *classprogr = classifiers_program(r, classifiers);  // figure out package name  String package_name;  {      md5_state_t pms;      char buf[MD5_TEXT_DIGEST_MAX_SIZE];      String s = classprogr->configuration_string();      md5_init(&pms);      md5_append(&pms, (const md5_byte_t *) s.data(), s.length());      int buflen = md5_finish_text(&pms, buf, 0);      md5_free(&pms);      package_name = "clickfc_" + String(buf, buflen);  }  if (do_compile)    compile_classifiers(r, package_name, classprogr, classifiers, compile_drivers, errh);  // write output  if (source_only) {    if (r->archive_index(package_name + ".hh") < 0) {      errh->error("no source code generated");      exit(1);    }    const ArchiveElement &aeh = r->archive(package_name + ".hh");    const ArchiveElement &aec = r->archive(package_name + ".cc");    ignore_result(fwrite(aeh.data.data(), 1, aeh.data.length(), outf));    ignore_result(fwrite(aec.data.data(), 1, aec.data.length(), outf));  } else if (config_only) {    String config = r->configuration_string();    ignore_result(fwrite(config.data(), 1, config.length(), outf));  } else    write_router_file(r, outf, errh);  exit(0);}

⌨️ 快捷键说明

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