📄 classifier.hh
字号:
#ifndef CLICK_CLASSIFIER_HH#define CLICK_CLASSIFIER_HH#include <click/element.hh>CLICK_DECLS/* * =c * Classifier(pattern1, ..., patternN) * =s classification * classifies packets by contents * =d * Classifies packets. The Classifier has N outputs, each associated with the * corresponding pattern from the configuration string. * A pattern is a set of clauses, where each clause is either "offset/value" * or "offset/value%mask". A pattern matches if the packet has the indicated * value at each offset. * * The clauses in each pattern are separated * by spaces. A clause consists of the offset, "/", the value, and (optionally) * "%" and a mask. The offset is in decimal. The value and mask are in hex. * The length of the value is implied by the number of hex digits, which must * be even. "?" is also allowed as a "hex digit"; it means "don't care about * the value of this nibble". * * If present, the mask must have the same number of hex digits as the value. * The matcher will only check bits that are 1 in the mask. * * A clause may be preceded by "!", in which case the clause must NOT match * the packet. * * As a special case, a pattern consisting of "-" matches every packet. * * The patterns are scanned in order, and the packet is sent to the output * corresponding to the first matching pattern. Thus more specific patterns * should come before less specific ones. You will get a warning if no packet * could ever match a pattern. Usually, this is because an earlier pattern is * more general, or because your pattern is contradictory (`12/0806 12/0800'). * * =n * * The IPClassifier and IPFilter elements have a friendlier syntax if you are * classifying IP packets. * * =e * For example, * * Classifier(12/0806 20/0001, * 12/0806 20/0002, * 12/0800, * -); * * creates an element with four outputs intended to process * Ethernet packets. * ARP requests are sent to output 0, ARP replies are sent to * output 1, IP packets to output 2, and all others to output 3. * * =h program read-only * Returns a human-readable definition of the program the Classifier element * is using to classify packets. At each step in the program, four bytes * of packet data are ANDed with a mask and compared against four bytes of * classifier pattern. * * The Classifier patterns above compile into the following program: * * 0 12/08060000%ffff0000 yes->step 1 no->step 3 * 1 20/00010000%ffff0000 yes->[0] no->step 2 * 2 20/00020000%ffff0000 yes->[1] no->[3] * 3 12/08000000%ffff0000 yes->[2] no->[3] * safe length 22 * alignment offset 0 * * =a IPClassifier, IPFilter */class Classifier : public Element { public: class Expr; Classifier(); ~Classifier(); const char *class_name() const { return "Classifier"; } const char *port_count() const { return "1/-"; } const char *processing() const { return PUSH; } // this element needs AlignmentInfo, so supply the "A" flag const char *flags() const { return "A"; } int configure(Vector<String> &, ErrorHandler *); void add_handlers(); // creating Exprs enum { NEVER = -2147483647, FAILURE, SUCCESS }; void add_expr(Vector<int> &, const Expr &); void add_expr(Vector<int> &, int offset, uint32_t value, uint32_t mask); void init_expr_subtree(Vector<int> &); void start_expr_subtree(Vector<int> &); void negate_expr_subtree(Vector<int> &); enum Combiner { C_AND, C_OR, C_TERNARY }; void finish_expr_subtree(Vector<int> &, Combiner = C_AND, int success = SUCCESS, int failure = FAILURE); void push(int port, Packet *); struct Expr { int offset; union { unsigned char c[4]; uint32_t u; } mask; union { unsigned char c[4]; uint32_t u; } value; int32_t j[2]; int32_t yes() const { return j[1]; } int32_t no() const { return j[0]; } int32_t &yes() { return j[1]; } int32_t &no() { return j[0]; } bool implies(const Expr &) const; bool implies_not(const Expr &) const; bool not_implies(const Expr &) const; bool not_implies_not(const Expr &) const; bool compatible(const Expr &) const; bool flippable() const; void flip(); String s() const; }; protected: enum { UBYTES = (int)(sizeof(uint32_t)) }; Vector<Expr> _exprs; int _output_everything; unsigned _safe_length; unsigned _align_offset; void redirect_expr_subtree(int first, int next, int success, int failure); void combine_compatible_states(); bool remove_unused_states(); //int count_occurrences(const Expr &, int state, bool first) const; //bool remove_duplicate_states(); void unaligned_optimize(); void count_inbranches(Vector<int> &) const; void bubble_sort_and_exprs(int sort_stopper = 0x7FFFFFFF); void optimize_exprs(ErrorHandler *, int sort_stopper = 0x7FFFFFFF); void compress_exprs(Vector<uint32_t> &prog, bool perform_binary_search = true, unsigned min_binary_search = 7) const; static String program_string(Element *, void *); void length_checked_push(Packet *); private: class DominatorOptimizer { public: DominatorOptimizer(Classifier *c); static int brno(int state, bool br) { return (state << 1) + br; } static int stateno(int brno) { return brno >> 1; } static bool br(int brno) { return brno & 1; } bool br_implies(int brno, int state) const; bool br_implies_not(int brno, int state) const; void run(int); void print(); private: Classifier *_c; Vector<int> _dom; Vector<int> _dom_start; Vector<int> _domlist_start; enum { MAX_DOMLIST = 4 }; Classifier::Expr &expr(int state) const; int nexprs() const; static void intersect_lists(const Vector<int> &, const Vector<int> &, const Vector<int> &, int pos1, int pos2, Vector<int> &); static int last_common_state_in_lists(const Vector<int> &, const Vector<int> &, const Vector<int> &); void find_predecessors(int state, Vector<int> &) const; int dom_shift_branch(int brno, int to_state, int dom, int dom_end, Vector<int> *collector); void shift_branch(int brno); void calculate_dom(int state); }; //bool check_path_iterative(Vector<int> &, int interested, int eventual) const; //bool check_path(const Vector<int> &path, Vector<int> &, int ei, int interested, int eventual, bool first, bool yet) const; //int check_path(int, bool) const; //void drift_expr(int); friend class DominatorOptimizer;};CLICK_ENDDECLS#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -