| #ifndef CLICK_IPFILTER_H |
| #define CLICK_IPFILTER_H |
| |
| #include "classifier.h" |
| #include "offload_req.h" |
| |
| class IPFilter : public Classifier { |
| public: |
| IPFilter() {} |
| ~IPFilter() {} |
| |
| int configure(stringvec &, ErrorHandler *); |
| void dump_integer_program(FILE *fp) const; |
| void dump_offload_settings(FILE *fp) const; |
| int save(const char *fname) const; |
| |
| int optimized_match(const OffloadReq &) const; |
| |
| enum { |
| TYPE_NONE = 0, // data types |
| TYPE_TYPE = 1, |
| TYPE_SYNTAX = 2, |
| TYPE_INT = 3, |
| |
| TYPE_HOST = 10, // expression types |
| TYPE_PORT = 13, |
| TYPE_VLAN = 15, |
| TYPE_LISTEN = 16, |
| TYPE_AOPEN = 17, |
| TYPE_POPEN = 18, |
| TYPE_MARK = 19, |
| |
| TYPE_NET = 30, // shorthands |
| |
| TYPE_FIELD = 0x40000000, |
| // bit 31 must be zero |
| // bit 30 must be one |
| // bits 29-21 represent IP protocol (9 bits); 0 means no protocol |
| // bits 20-5 represent field offset into header in bits (16 bits) |
| // bits 4-0 represent field length in bits minus one (5 bits) |
| FIELD_OFFSET_SHIFT = 5, |
| FIELD_OFFSET_MASK = (0xFFFF << FIELD_OFFSET_SHIFT), |
| FIELD_LENGTH_SHIFT = 0, |
| FIELD_LENGTH_MASK = (0x1F << FIELD_LENGTH_SHIFT), |
| FIELD_VERSION = (TYPE_FIELD | ((9*32+4) << FIELD_OFFSET_SHIFT) | 3), |
| FIELD_TOS = (TYPE_FIELD | ((9*32+8) << FIELD_OFFSET_SHIFT) | 7), |
| FIELD_DSCP = (TYPE_FIELD | ((9*32+8) << FIELD_OFFSET_SHIFT) | 5), |
| FIELD_VLAN = (TYPE_FIELD | ((9*32+20) << FIELD_OFFSET_SHIFT) | 11), |
| }; |
| |
| enum { |
| SD_SRC = 1, SD_DST = 2, SD_AND = 3, SD_OR = 4, |
| |
| OP_EQ = 0, OP_GT = 1, OP_LT = 2, |
| }; |
| |
| enum { OPEN_TYPE_LISTEN, OPEN_TYPE_ACTIVE, OPEN_TYPE_PASSIVE }; |
| |
| struct Primitive { |
| int _type; |
| int _data; |
| int _op; |
| bool _op_negated; |
| int _srcdst; |
| |
| union { |
| uint32_t u; |
| int32_t i; |
| uint8_t c[16]; |
| } _u, _mask; |
| |
| Primitive() { clear(); } |
| |
| void clear(); |
| void set_type(int, ErrorHandler *); |
| void set_srcdst(int, ErrorHandler *); |
| |
| int set_mask(uint32_t full_mask, int shift, uint32_t provided_mask, |
| ErrorHandler *); |
| int check(const Primitive &, uint32_t provided_mask, ErrorHandler *); |
| void add_exprs(Classifier *, Vector<int> &) const; |
| |
| bool negation_is_simple() const; |
| void simple_negate(); |
| |
| bool is_int_type() const; |
| |
| std::string unparse_type() const; |
| const char *unparse_op() const; |
| static std::string unparse_type(int srcdst, int type); |
| |
| private: |
| void add_comparison_exprs(Classifier *, Vector<int> &tree, int offset, |
| int shift, bool swapped, bool op_negate) const; |
| }; |
| |
| private: |
| Vector<uint32_t> _prog; |
| Vector<OffloadSettings> _settings; |
| |
| int lookup(const std::string &word, int type, uint32_t &data) const; |
| |
| int parse_expr(const Vector<std::string> &, int, Vector<int> &, Primitive &, |
| ErrorHandler *); |
| int parse_orexpr(const Vector<std::string> &, int, Vector<int> &, |
| Primitive &, ErrorHandler *); |
| int parse_term(const Vector<std::string> &, int, Vector<int> &, Primitive &, |
| ErrorHandler *); |
| int parse_factor(const Vector<std::string> &, int, Vector<int> &, |
| Primitive &, bool negated, ErrorHandler *); |
| int parse_offload_settings(const stringvec &, int, ErrorHandler *); |
| }; |
| |
| inline bool IPFilter::Primitive::negation_is_simple() const |
| { |
| return _type == TYPE_HOST || (_type & TYPE_FIELD); |
| } |
| #endif |
| |
| /* vim: set ts=8 sw=4: */ |