📄 iprw.hh
字号:
// -*- mode: c++; c-basic-offset: 4 -*-#ifndef CLICK_IPRW_HH#define CLICK_IPRW_HH#include <click/element.hh>#include <click/timer.hh>#include <click/bighashmap.hh>#include <click/ipflowid.hh>#include <clicknet/ip.h>CLICK_DECLSclass IPMapper;class IPRw : public Element { public: class Pattern; class Mapping; typedef HashMap<IPFlowID, Mapping*> Map; enum InputSpecName { INPUT_SPEC_NOCHANGE, INPUT_SPEC_KEEP, INPUT_SPEC_DROP, INPUT_SPEC_PATTERN, INPUT_SPEC_MAPPER }; struct InputSpec { int kind; union { int output; struct { Pattern* p; int fport; int rport; } pattern; /* also used for INPUT_SPEC_KEEP */ IPMapper* mapper; } u; }; IPRw(); ~IPRw(); enum ConfigurePhase { CONFIGURE_PHASE_PATTERNS = CONFIGURE_PHASE_INFO, CONFIGURE_PHASE_REWRITER = CONFIGURE_PHASE_DEFAULT, CONFIGURE_PHASE_MAPPER = CONFIGURE_PHASE_REWRITER - 1, CONFIGURE_PHASE_USER = CONFIGURE_PHASE_REWRITER + 1 }; int configure_phase() const { return CONFIGURE_PHASE_REWRITER; } int parse_input_spec(const String&, InputSpec&, String, ErrorHandler*); virtual int notify_pattern(Pattern*, ErrorHandler*); virtual Mapping* apply_pattern(Pattern*, int ip_p, const IPFlowID&, int, int) = 0; virtual Mapping* get_mapping(int ip_p, const IPFlowID&) const = 0; protected: Vector<Pattern*> _all_patterns; enum { GC_INTERVAL_SEC = 3600 }; void take_state_map(Map&, Mapping** free_head, Mapping** free_tail, const Vector<Pattern*>&, const Vector<Pattern*>&); void clear_map(Map&); void clean_map(Map&, uint32_t last_jif); void clean_map_free_tracked(Map&, Mapping*& free_head, Mapping*& free_tail, uint32_t last_jif); void incr_clean_map_free_tracked(Map&, Mapping*& head, Mapping*& tail, uint32_t last_jif);};class IPRw::Mapping { public: enum { F_REVERSE = 1, F_MARKED = 2, F_FLOW_OVER = 4, F_FREE_TRACKED = 8, F_DST_ANNO = 16 }; Mapping(bool dst_anno); void initialize(int ip_p, const IPFlowID& inf, const IPFlowID& outf, int output, uint16_t flags, Mapping* reverse); static void make_pair(int ip_p, const IPFlowID& inf, const IPFlowID& outf, int foutput, int routput, Mapping* f, Mapping* r); const IPFlowID& flow_id() const { return _mapto; } Pattern* pattern() const { return _pat; } int output() const { return _output; } bool is_primary() const { return !(_flags & F_REVERSE); } const Mapping* primary() const { return is_primary() ? this : _reverse; } Mapping* primary() { return is_primary() ? this : _reverse; } Mapping* reverse() const { return _reverse; } inline bool used_since(uint32_t) const; void mark_used() { _used = click_jiffies(); } bool marked() const { return (_flags & F_MARKED); } void mark() { _flags |= F_MARKED; } void unmark() { _flags &= ~F_MARKED; } uint16_t sport() const { return _mapto.sport(); } // network Mapping* free_next() const { return _free_next; } void set_free_next(Mapping* m) { _free_next = m; } bool session_over() const { return (_flags & F_FLOW_OVER) && (_reverse->_flags & F_FLOW_OVER); } void set_session_over() { _flags |= F_FLOW_OVER; _reverse->_flags |= F_FLOW_OVER; } void set_session_flow_over() { _flags |= F_FLOW_OVER; } void clear_session_flow_over() { _flags &= ~F_FLOW_OVER; } bool free_tracked() const { return (_flags & F_FREE_TRACKED); } inline void add_to_free_tracked_tail(Mapping*& head, Mapping*& tail); inline void clear_free_tracked(); void apply(WritablePacket*); String unparse() const; protected: IPFlowID _mapto; uint16_t _ip_csum_delta; uint16_t _udp_csum_delta; Mapping* _reverse; uint16_t _flags; uint8_t _ip_p; uint8_t _output; unsigned _used; // these variables maintained by IPRw::Pattern Pattern* _pat; Mapping* _free_next; friend class IPRw; friend class IPRw::Pattern; inline Mapping* free_from_list(Map&, bool notify); inline void append_to_free(Mapping*& head, Mapping*& tail);};class IPRw::Pattern { public: // Pattern is <saddr/sport[-sport2]/daddr/dport>. // It is associated with a IPRewriter output port. // It can be applied to a specific IPFlowID (<saddr/sport/daddr/dport>) // to obtain a new IPFlowID rewritten according to the Pattern. // Any Pattern component can be '-', which means that the corresponding // IPFlowID component is left unchanged. Pattern(const IPAddress&, int, const IPAddress&, int, bool is_napt, bool sequential, uint32_t variation); static int parse(const String&, Pattern**, Element*, ErrorHandler*); static int parse_with_ports(const String&, Pattern**, int*, int*, Element*, ErrorHandler*); void use() { _refcount++; } void unuse() { if (--_refcount <= 0) delete this; } int nmappings() const { return _nmappings; } operator bool() const { return _saddr || _sport || _daddr || _dport; } IPAddress daddr() const { return _daddr; } bool allow_nat() const { return !_is_napt || _variation_top == 0; } bool allow_napt() const { return _is_napt || _variation_top == 0; } bool can_accept_from(const Pattern&) const; bool create_mapping(int ip_p, const IPFlowID&, int fport, int rport, Mapping*, Mapping*, const Map&); void accept_mapping(Mapping*); inline void mapping_freed(Mapping*); String unparse() const; public: IPAddress _saddr; int _sport; // host byte order IPAddress _daddr; int _dport; // host byte order uint32_t _variation_top; uint32_t _variation_mask; uint32_t _next_variation; bool _is_napt; bool _sequential; int _refcount; int _nmappings; Pattern(const Pattern&); Pattern& operator=(const Pattern&); static int parse_napt(Vector<String>&, Pattern**, Element*, ErrorHandler*); static int parse_nat(Vector<String>&, Pattern**, Element*, ErrorHandler*); friend class Mapping;};class IPMapper { public: IPMapper() { } virtual ~IPMapper() { } void notify_rewriter(IPRw*, ErrorHandler*); virtual IPRw::Mapping* get_map(IPRw*, int ip_p, const IPFlowID&, Packet*);};inline voidIPRw::Mapping::append_to_free(Mapping*& head, Mapping*& tail){ assert((!head && !tail) || (head && tail && (head->_flags & F_FREE_TRACKED) && (tail->_flags & F_FREE_TRACKED))); assert(!_free_next && !_reverse->_free_next); if (tail) tail = tail->_free_next = this; else head = tail = this;}inline voidIPRw::Mapping::add_to_free_tracked_tail(Mapping*& head, Mapping*& tail){ assert(!(_flags & F_FREE_TRACKED) && !(_reverse->_flags & F_FREE_TRACKED)); _flags |= F_FREE_TRACKED; _reverse->_flags |= F_FREE_TRACKED; primary()->append_to_free(head, tail);}inline voidIPRw::Mapping::clear_free_tracked(){ _flags &= ~F_FREE_TRACKED; _reverse->_flags &= ~F_FREE_TRACKED; _free_next = 0; assert(_reverse->_free_next == 0);}inline boolIPRw::Mapping::used_since(uint32_t t) const{ return ((int32_t)(_used - t)) >= 0 || ((int32_t)(_reverse->_used - t)) >= 0;}CLICK_ENDDECLS#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -