From fac10ea799fe9b6158d74f66d6ad46536d38a545 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 18 Mar 2009 04:55:00 +0100 Subject: Initial commit --- include/ct.h | 29 + include/datatype.h | 156 +++++ include/erec.h | 64 +++ include/expression.h | 323 +++++++++++ include/exthdr.h | 84 +++ include/gmputil.h | 42 ++ include/headers.h | 119 ++++ include/linux/netfilter.h | 59 ++ include/linux/netfilter/nf_conntrack_common.h | 152 +++++ .../linux/netfilter/nf_conntrack_tuple_common.h | 13 + include/linux/netfilter/nf_tables.h | 337 +++++++++++ include/linux/netfilter_arp.h | 19 + include/linux/netfilter_bridge.h | 27 + include/linux/netfilter_decnet.h | 72 +++ include/linux/netfilter_ipv4.h | 75 +++ include/linux/netfilter_ipv6.h | 72 +++ include/list.h | 625 +++++++++++++++++++++ include/meta.h | 29 + include/netlink.h | 60 ++ include/nftables.h | 96 ++++ include/parser.h | 36 ++ include/payload.h | 289 ++++++++++ include/rbtree.h | 98 ++++ include/rule.h | 174 ++++++ include/statement.h | 140 +++++ include/utils.h | 69 +++ 26 files changed, 3259 insertions(+) create mode 100644 include/ct.h create mode 100644 include/datatype.h create mode 100644 include/erec.h create mode 100644 include/expression.h create mode 100644 include/exthdr.h create mode 100644 include/gmputil.h create mode 100644 include/headers.h create mode 100644 include/linux/netfilter.h create mode 100644 include/linux/netfilter/nf_conntrack_common.h create mode 100644 include/linux/netfilter/nf_conntrack_tuple_common.h create mode 100644 include/linux/netfilter/nf_tables.h create mode 100644 include/linux/netfilter_arp.h create mode 100644 include/linux/netfilter_bridge.h create mode 100644 include/linux/netfilter_decnet.h create mode 100644 include/linux/netfilter_ipv4.h create mode 100644 include/linux/netfilter_ipv6.h create mode 100644 include/list.h create mode 100644 include/meta.h create mode 100644 include/netlink.h create mode 100644 include/nftables.h create mode 100644 include/parser.h create mode 100644 include/payload.h create mode 100644 include/rbtree.h create mode 100644 include/rule.h create mode 100644 include/statement.h create mode 100644 include/utils.h (limited to 'include') diff --git a/include/ct.h b/include/ct.h new file mode 100644 index 00000000..946bc297 --- /dev/null +++ b/include/ct.h @@ -0,0 +1,29 @@ +#ifndef _CT_H +#define _CT_H + +/** + * struct ct_template + * + * @token: parser token for the expression + * @dtype: data type of the expression + * @len: length of the expression + * @byteorder: byteorder + */ +struct ct_template { + const char *token; + const struct datatype *dtype; + enum byteorder byteorder; + unsigned int len; +}; + +#define CT_TEMPLATE(__token, __dtype, __byteorder, __len) { \ + .token = (__token), \ + .dtype = (__dtype), \ + .byteorder = (__byteorder), \ + .len = (__len), \ +} + +extern struct expr *ct_expr_alloc(const struct location *loc, + enum nft_ct_keys key); + +#endif /* _CT_H */ diff --git a/include/datatype.h b/include/datatype.h new file mode 100644 index 00000000..c6aeeeda --- /dev/null +++ b/include/datatype.h @@ -0,0 +1,156 @@ +#ifndef _DATATYPE_H +#define _DATATYPE_H + +/** + * enum datatypes + * + * @TYPE_INVALID: uninitialized + * @TYPE_VERDICT: nftables verdict + * @TYPE_BITMASK: bitmask + * @TYPE_INTEGER: integer + * @TYPE_STRING: string + * @TYPE_LLADDR: link layer address (integer subtype) + * @TYPE_IPADDR: IPv4 address (integer subtype) + * @TYPE_IP6ADDR: IPv6 address (integer subtype) + * @TYPE_ETHERTYPE: EtherType (integer subtype) + * @TYPE_ARPOP: ARP operation (integer subtype) + * @TYPE_INET_PROTOCOL: internet protocol (integer subtype) + * @TYPE_INET_SERVICE: internet service (integer subtype) + * @TYPE_ICMP_TYPE: ICMP type codes (integer subtype) + * @TYPE_TCP_FLAG: TCP flag (bitmask subtype) + * @TYPE_MH_TYPE: Mobility Header type (integer subtype) + * @TYPE_TIME: relative time + * @TYPE_MARK: packet mark (integer subtype) + * @TYPE_IFINDEX: interface index (integer subtype) + * @TYPE_ARPHRD: interface type (integer subtype) + * @TYPE_REALM: routing realm (integer subtype) + * @TYPE_TC_HANDLE: TC handle (integer subtype) + * @TYPE_UID: user ID (integer subtype) + * @TYPE_GID: group ID (integer subtype) + * @TYPE_CT_STATE: conntrack state (bitmask subtype) + * @TYPE_CT_DIR: conntrack direction + * @TYPE_CT_STATUS: conntrack status (bitmask subtype) + */ +enum datatypes { + TYPE_INVALID, + TYPE_VERDICT, + TYPE_BITMASK, + TYPE_INTEGER, + TYPE_STRING, + TYPE_LLADDR, + TYPE_IPADDR, + TYPE_IP6ADDR, + TYPE_ETHERTYPE, + TYPE_ARPOP, + TYPE_INET_PROTOCOL, + TYPE_INET_SERVICE, + TYPE_ICMP_TYPE, + TYPE_TCP_FLAG, + TYPE_MH_TYPE, + TYPE_TIME, + TYPE_MARK, + TYPE_IFINDEX, + TYPE_ARPHRD, + TYPE_REALM, + TYPE_TC_HANDLE, + TYPE_UID, + TYPE_GID, + TYPE_CT_STATE, + TYPE_CT_DIR, + TYPE_CT_STATUS, +}; + +/** + * enum byteorder + * + * @BYTEORDER_INVALID: uninitialized/unknown + * @BYTEORDER_HOST_ENDIAN: host endian + * @BYTEORDER_BIG_ENDIAN: big endian + */ +enum byteorder { + BYTEORDER_INVALID, + BYTEORDER_HOST_ENDIAN, + BYTEORDER_BIG_ENDIAN, +}; + +struct expr; + +/** + * struct datatype + * + * @type: numeric identifier + * @name: type name for diagnostics + * @basetype: basetype for subtypes, determines type compatibilty + * @basefmt: format string for basetype + * @print: function to print a constant of this type + * @parse: function to parse a symbol and return an expression + * @sym_tbl: symbol table for this type + */ +struct datatype { + enum datatypes type; + const char *name; + const struct datatype *basetype; + const char *basefmt; + void (*print)(const struct expr *expr); + struct error_record *(*parse)(const struct expr *sym, + struct expr **res); + const struct symbol_table *sym_tbl; +}; + +extern struct error_record *symbol_parse(const struct expr *sym, + struct expr **res); +extern void datatype_print(const struct expr *expr); + +/** + * struct symbolic_constant - symbol <-> constant mapping + * + * @identifier: symbol + * @value: symbolic value + */ +struct symbolic_constant { + const char *identifier; + uint64_t value; +}; + +#define SYMBOL(id, v) { .identifier = (id), .value = (v) } +#define SYMBOL_LIST_END (struct symbolic_constant) { } + +/** + * struct symbol_table - type construction from symbolic values + * + * @byteorder: byteorder of symbol values + * @size: size of symbol values + * @symbols: the symbols + */ +struct symbol_table { + enum byteorder byteorder; + unsigned int size; + struct symbolic_constant symbols[]; +}; + +extern struct error_record *symbolic_constant_parse(const struct expr *sym, + const struct symbol_table *tbl, + struct expr **res); +extern void symbolic_constant_print(const struct symbol_table *tbl, + const struct expr *expr); +extern void symbol_table_print(const struct symbol_table *tbl); + +extern struct symbol_table *rt_symbol_table_init(const char *filename); +extern void rt_symbol_table_free(struct symbol_table *tbl); + +extern const struct datatype invalid_type; +extern const struct datatype verdict_type; +extern const struct datatype bitmask_type; +extern const struct datatype integer_type; +extern const struct datatype string_type; +extern const struct datatype lladdr_type; +extern const struct datatype ipaddr_type; +extern const struct datatype ip6addr_type; +extern const struct datatype ethertype_type; +extern const struct datatype arphrd_type; +extern const struct datatype inet_protocol_type; +extern const struct datatype inet_service_type; +extern const struct datatype mark_type; +extern const struct datatype time_type; + +#endif /* _DATATYPE_H */ diff --git a/include/erec.h b/include/erec.h new file mode 100644 index 00000000..51f39588 --- /dev/null +++ b/include/erec.h @@ -0,0 +1,64 @@ +#ifndef _EREC_H +#define _EREC_H + +#include +#include + +/** + * enum error_record_types + * + * @EREC_INFORMATIONAL: informational message + * @EREC_WARNING: warning message + * @EREC_ERROR: error message + */ +enum error_record_types { + EREC_INFORMATIONAL, + EREC_WARNING, + EREC_ERROR, +}; + +#define EREC_MSGBUFSIZE 1024 +#define EREC_LOCATIONS_MAX 3 + +/** + * struct error_record + * + * @list: message queue node + * @type: error record type + * @num_locations: number of locations + * @locations: location(s) of error + * @msg: message + */ +struct error_record { + struct list_head list; + enum error_record_types type; + unsigned int num_locations; + struct location locations[EREC_LOCATIONS_MAX]; + char *msg; +}; + +extern struct error_record *erec_vcreate(enum error_record_types type, + const struct location *loc, + const char *fmt, va_list ap) + __gmp_fmtstring(3, 0); +extern struct error_record *erec_create(enum error_record_types type, + const struct location *loc, + const char *fmt, ...) __gmp_fmtstring(3, 4); +extern void erec_add_location(struct error_record *erec, + const struct location *loc); + +#define error(loc, fmt, args...) \ + erec_create(EREC_ERROR, (loc), (fmt), ## args) +#define warning(loc, fmt, args...) \ + erec_create(EREC_WARNING, (loc), (fmt), ## args) + +static inline void erec_queue(struct error_record *erec, + struct list_head *queue) +{ + list_add_tail(&erec->list, queue); +} + +extern void erec_print(FILE *f, const struct error_record *erec); +extern void erec_print_list(FILE *f, struct list_head *list); + +#endif /* _EREC_H */ diff --git a/include/expression.h b/include/expression.h new file mode 100644 index 00000000..72585469 --- /dev/null +++ b/include/expression.h @@ -0,0 +1,323 @@ +#ifndef _EXPRESSION_H +#define _EXPRESSION_H + +#include +#include +#include + +#include +#include +#include +#include + +/** + * enum expr_types + * + * @EXPR_INVALID: uninitialized type, should not happen + * @EXPR_VERDICT: nftables verdict expression + * @EXPR_SYMBOL: unparsed symbol + * @EXPR_VALUE: literal numeric or string expression + * @EXPR_PREFIX: prefixed expression + * @EXPR_RANGE: literal range + * @EXPR_PAYLOAD: payload expression + * @EXPR_EXTHDR: exthdr expression + * @EXPR_META: meta expression + * @EXPR_CT: conntrack expression + * @EXPR_CONCAT: concatenation + * @EXPR_LIST: list of expressions + * @EXPR_SET: literal set + * @EXPR_MAPPING: a single mapping (key => value) + * @EXPR_MAP: map operation (expr map { EXPR_MAPPING, ... }) + * @EXPR_UNARY: byteorder conversion, generated during evaluation + * @EXPR_BINOP: binary operations (bitwise, shifts) + * @EXPR_RELATIONAL: equality and relational expressions + */ +enum expr_types { + EXPR_INVALID, + EXPR_VERDICT, + EXPR_SYMBOL, + EXPR_VALUE, + EXPR_PREFIX, + EXPR_RANGE, + EXPR_PAYLOAD, + EXPR_EXTHDR, + EXPR_META, + EXPR_CT, + EXPR_CONCAT, + EXPR_LIST, + EXPR_SET, + EXPR_MAPPING, + EXPR_MAP, + EXPR_UNARY, + EXPR_BINOP, + EXPR_RELATIONAL, +}; + +enum ops { + OP_INVALID, + /* Unary operations */ + OP_HTON, + OP_NTOH, + /* Binary operations */ + OP_LSHIFT, + OP_RSHIFT, + OP_AND, + OP_XOR, + OP_OR, + /* Relational operations */ + OP_EQ, + OP_NEQ, + OP_LT, + OP_GT, + OP_LTE, + OP_GTE, + /* Range comparison */ + OP_RANGE, + /* Flag comparison */ + OP_FLAGCMP, + /* Set lookup */ + OP_LOOKUP, +}; + +extern const char *expr_op_symbols[]; + +/** + * struct expr_ctx - type context for symbol parsing during evaluation + * + * @dtype: expected datatype + * @len: expected len + */ +struct expr_ctx { + const struct datatype *dtype; + unsigned int len; +}; + +static inline void expr_set_context(struct expr_ctx *ctx, + const struct datatype *dtype, + unsigned int len) +{ + ctx->dtype = dtype; + ctx->len = len; +} + +/** + * struct expr_ops + * + * @type: expression type + * @name: expression name for diagnostics + * @destroy: destructor, must release inner expressions + * @set_type: function to promote type and byteorder of inner types + * @print: function to print the expression + */ +struct expr_ops { + enum expr_types type; + const char *name; + void (*destroy)(struct expr *expr); + void (*set_type)(const struct expr *expr, + const struct datatype *dtype, + enum byteorder byteorder); + void (*print)(const struct expr *expr); +}; + +/** + * enum expr_flags + * + * @EXPR_F_PRIMARY: primary expression + * @EXPR_F_CONSTANT: constant expression + * @EXPR_F_SINGLETON: singleton (implies primary and constant) + * @EXPR_F_INTERVAL_END: set member ends an open interval + * @SET_F_INTERVAL: set includes ranges and/or prefix expressions + */ +enum expr_flags { + EXPR_F_PRIMARY = 0x1, + EXPR_F_CONSTANT = 0x2, + EXPR_F_SINGLETON = 0x4, + EXPR_F_INTERVAL_END = 0x8, + SET_F_INTERVAL = 0x10, +}; + +#include +#include +#include +#include + +/** + * struct expr + * + * @list: list node + * @location: location from parser + * @refcnt: reference count + * @flags: mask of enum expr_flags + * @dtype: data type of expression + * @byteorder: byteorder of expression + * @len: length of expression + * @ops: expression ops + * @op: operation for unary, binary and relational expressions + * @union: type specific data + */ +struct expr { + struct list_head list; + struct location location; + + unsigned int refcnt; + unsigned int flags; + + const struct datatype *dtype; + enum byteorder byteorder; + unsigned int len; + + const struct expr_ops *ops; + enum ops op; + union { + struct { + /* EXPR_SYMBOL */ + const struct datatype *sym_type; + const char *identifier; + }; + struct { + /* EXPR_VERDICT */ + int verdict; + const char *chain; + }; + struct { + /* EXPR_VALUE */ + mpz_t value; + }; + struct { + /* EXPR_PREFIX */ + struct expr *expr; + unsigned int prefix_len; + }; + struct { + /* EXPR_CONCAT, EXPR_LIST, EXPR_SET */ + struct list_head expressions; + unsigned int size; + }; + struct { + /* EXPR_UNARY */ + struct expr *arg; + }; + struct { + /* EXPR_RANGE, EXPR_BINOP, EXPR_MAPPING, EXPR_RELATIONAL */ + struct expr *left; + struct expr *right; + }; + struct { + /* EXPR_MAP */ + struct expr *expr; + struct expr *mappings; + }; + + struct { + /* EXPR_PAYLOAD */ + const struct payload_desc *desc; + const struct payload_template *tmpl; + enum payload_bases base; + unsigned int offset; + unsigned int flags; + } payload; + struct { + /* EXPR_EXTHDR */ + const struct exthdr_desc *desc; + const struct payload_template *tmpl; + } exthdr; + struct { + /* EXPR_META */ + enum nft_meta_keys key; + } meta; + struct { + /* EXPR_CT */ + enum nft_ct_keys key; + } ct; + }; +}; + +extern struct expr *expr_alloc(const struct location *loc, + const struct expr_ops *ops, + const struct datatype *dtype, + enum byteorder byteorder, unsigned int len); +extern struct expr *expr_get(struct expr *expr); +extern void expr_free(struct expr *expr); +extern void expr_print(const struct expr *expr); +extern void expr_describe(const struct expr *expr); + +extern const struct datatype *expr_basetype(const struct expr *expr); +extern void expr_set_type(struct expr *expr, const struct datatype *dtype, + enum byteorder byteorder); + +struct eval_ctx; +extern int expr_binary_error(struct eval_ctx *ctx, + const struct expr *e1, const struct expr *e2, + const char *fmt, ...) __gmp_fmtstring(4, 5); + +#define expr_error(ctx, expr, fmt, args...) \ + expr_binary_error(ctx, expr, NULL, fmt, ## args) + +static inline bool expr_is_primary(const struct expr *expr) +{ + return expr->flags & EXPR_F_PRIMARY ? true : false; +} + +static inline bool expr_is_constant(const struct expr *expr) +{ + return expr->flags & EXPR_F_CONSTANT ? true : false; +} + +static inline bool expr_is_singleton(const struct expr *expr) +{ + return expr->flags & EXPR_F_SINGLETON ? true : false; +} + +extern struct expr *unary_expr_alloc(const struct location *loc, + enum ops op, struct expr *arg); + +extern struct expr *binop_expr_alloc(const struct location *loc, enum ops op, + struct expr *left, struct expr *right); + +extern struct expr *relational_expr_alloc(const struct location *loc, enum ops op, + struct expr *left, struct expr *right); + +extern struct expr *verdict_expr_alloc(const struct location *loc, + int verdict, const char *chain); + +extern struct expr *symbol_expr_alloc(const struct location *loc, + const char *identifier); + +static inline void symbol_expr_set_type(struct expr *expr, + const struct datatype *dtype) +{ + if (expr->ops->type == EXPR_SYMBOL) + expr->sym_type = dtype; +} + +extern struct expr *constant_expr_alloc(const struct location *loc, + const struct datatype *dtype, + enum byteorder byteorder, + unsigned int len, const void *data); +extern struct expr *constant_expr_join(const struct expr *e1, + const struct expr *e2); +extern struct expr *constant_expr_splice(struct expr *expr, unsigned int len); + +extern struct expr *prefix_expr_alloc(const struct location *loc, + struct expr *expr, + unsigned int prefix_len); + +extern struct expr *range_expr_alloc(const struct location *loc, + struct expr *low, struct expr *high); + +extern void compound_expr_add(struct expr *compound, struct expr *expr); +extern void compound_expr_remove(struct expr *compound, struct expr *expr); + +extern struct expr *concat_expr_alloc(const struct location *loc); + +extern struct expr *list_expr_alloc(const struct location *loc); + +extern struct expr *set_expr_alloc(const struct location *loc); +extern void set_to_intervals(struct expr *set); + +extern struct expr *mapping_expr_alloc(const struct location *loc, + struct expr *from, struct expr *to); +extern struct expr *map_expr_alloc(const struct location *loc, + struct expr *arg, struct expr *list); + +#endif /* _EXPRESSION_H */ diff --git a/include/exthdr.h b/include/exthdr.h new file mode 100644 index 00000000..8ef0b395 --- /dev/null +++ b/include/exthdr.h @@ -0,0 +1,84 @@ +#ifndef _EXTHDR_H +#define _EXTHDR_H + +/** + * struct exthdr_desc - extension header description + * + * @name: extension header name + * @type: extension header protocol value + * @templates: header templates + */ +struct exthdr_desc { + const char *name; + uint8_t type; + struct payload_template templates[10]; +}; + +extern struct expr *exthdr_expr_alloc(const struct location *loc, + const struct exthdr_desc *desc, + uint8_t type); + +extern void exthdr_init_raw(struct expr *expr, uint8_t type, + unsigned int offset, unsigned int len); + + +enum hbh_hdr_fields { + HBHHDR_INVALID, + HBHHDR_NEXTHDR, + HBHHDR_HDRLENGTH, +}; + +enum rt_hdr_fields { + RTHDR_INVALID, + RTHDR_NEXTHDR, + RTHDR_HDRLENGTH, + RTHDR_TYPE, + RTHDR_SEG_LEFT, +}; + +enum rt0_hdr_fields { + RT0HDR_INVALID, + RT0HDR_RESERVED, + RT0HDR_ADDR_1, +}; + +enum rt2_hdr_fields { + RT2HDR_INVALID, + RT2HDR_RESERVED, + RT2HDR_ADDR, +}; + +enum frag_hdr_fields { + FRAGHDR_INVALID, + FRAGHDR_NEXTHDR, + FRAGHDR_RESERVED, + FRAGHDR_FRAG_OFF, + FRAGHDR_RESERVED2, + FRAGHDR_MFRAGS, + FRAGHDR_ID, +}; + +enum dst_hdr_fields { + DSTHDR_INVALID, + DSTHDR_NEXTHDR, + DSTHDR_HDRLENGTH, +}; + +enum mh_hdr_fields { + MHHDR_INVALID, + MHHDR_NEXTHDR, + MHHDR_HDRLENGTH, + MHHDR_TYPE, + MHHDR_RESERVED, + MHHDR_CHECKSUM, +}; + +extern const struct exthdr_desc exthdr_hbh; +extern const struct exthdr_desc exthdr_rt; +extern const struct exthdr_desc exthdr_rt0; +extern const struct exthdr_desc exthdr_rt2; +extern const struct exthdr_desc exthdr_frag; +extern const struct exthdr_desc exthdr_dst; +extern const struct exthdr_desc exthdr_mh; + +#endif /* _EXTHDR_H */ diff --git a/include/gmputil.h b/include/gmputil.h new file mode 100644 index 00000000..41a6c270 --- /dev/null +++ b/include/gmputil.h @@ -0,0 +1,42 @@ +#ifndef _GMPUTIL_H +#define _GMPUTIL_H + +#include + +enum mpz_word_order { + MPZ_MSWF = 1, + MPZ_LSWF = -1, +}; + +enum mpz_byte_order { + MPZ_BIG_ENDIAN = 1, + MPZ_HOST_ENDIAN = 0, + MPZ_LITTLE_ENDIAN = -1, +}; + +extern void mpz_bitmask(mpz_t rop, unsigned int width); +extern void mpz_init_bitmask(mpz_t rop, unsigned int width); +extern void mpz_prefixmask(mpz_t rop, unsigned int width, unsigned int prefix_len); + +extern void mpz_lshift_ui(mpz_t rop, unsigned int n); +extern void mpz_rshift_ui(mpz_t rop, unsigned int n); + +extern uint64_t mpz_get_uint64(const mpz_t op); +extern uint32_t mpz_get_uint32(const mpz_t op); +extern uint16_t mpz_get_uint16(const mpz_t op); +extern uint8_t mpz_get_uint8(const mpz_t op); + +extern uint64_t mpz_get_be64(const mpz_t op); +extern uint32_t mpz_get_be32(const mpz_t op); +extern uint16_t mpz_get_be16(const mpz_t op); + +enum byteorder; +extern void *mpz_export_data(void *data, const mpz_t op, + enum byteorder byteorder, + unsigned int len); +extern void mpz_import_data(mpz_t rop, const void *data, + enum byteorder byteorder, + unsigned int len); +extern void mpz_switch_byteorder(mpz_t rop, unsigned int len); + +#endif /* _GMPUTIL_H */ diff --git a/include/headers.h b/include/headers.h new file mode 100644 index 00000000..be20cec0 --- /dev/null +++ b/include/headers.h @@ -0,0 +1,119 @@ +#ifndef _HEADERS_H +#define _HEADERS_H + +#ifndef IPPROTO_UDPLITE +# define IPPROTO_UDPLITE 136 +#endif + +enum tcp_hdr_flags { + TCP_FLAG_FIN = 0x01, + TCP_FLAG_SYN = 0x02, + TCP_FLAG_RST = 0x04, + TCP_FLAG_PSH = 0x08, + TCP_FLAG_ACK = 0x10, + TCP_FLAG_URG = 0x20, + TCP_FLAG_ECN = 0x40, + TCP_FLAG_CWR = 0x80, +}; + +struct ip_auth_hdr { + uint8_t nexthdr; + uint8_t hdrlen; + uint16_t reserved; + uint32_t spi; + uint32_t seq_no; +}; + +struct ip_esp_hdr { + uint32_t spi; + uint32_t seq_no; +}; + +struct ip_comp_hdr { + uint8_t nexthdr; + uint8_t flags; + uint16_t cpi; +}; + +#ifndef IPPROTO_DCCP +# define IPPROTO_DCCP 33 +#endif + +struct dccp_hdr { + uint16_t dccph_sport, + dccph_dport; + uint8_t dccph_doff; + uint8_t dccph_ccval:4, + dccph_cscov:4; + uint16_t dccph_checksum; + uint8_t dccph_reserved:3, + dccph_type:4, + dccph_x:1; + uint8_t dccph_seq2; + uint16_t dccph_seq; +}; + +#ifndef IPPROTO_SCTP +# define IPPROTO_SCTP 132 +#endif + +struct sctphdr { + uint16_t source; + uint16_t dest; + uint32_t vtag; + uint32_t checksum; +}; + +struct ipv6hdr { + uint8_t version:4, + priority:4; + uint8_t flow_lbl[3]; + + uint16_t payload_len; + uint8_t nexthdr; + uint8_t hop_limit; + + struct in6_addr saddr; + struct in6_addr daddr; +}; + +struct vlan_hdr { + uint16_t vlan_id:12, + vlan_cfi:1, + vlan_pcp:3; + uint16_t vlan_type; +}; + +#ifndef IPPROTO_MH +# define IPPROTO_MH 135 +#endif + +struct ip6_mh { + uint8_t ip6mh_proto; + uint8_t ip6mh_hdrlen; + uint8_t ip6mh_type; + uint8_t ip6mh_reserved; + uint16_t ip6mh_cksum; + /* Followed by type specific messages */ + uint8_t data[0]; +}; + +/* RFC 3775 */ +#define IP6_MH_TYPE_BRR 0 /* Binding Refresh Request */ +#define IP6_MH_TYPE_HOTI 1 /* HOTI Message */ +#define IP6_MH_TYPE_COTI 2 /* COTI Message */ +#define IP6_MH_TYPE_HOT 3 /* HOT Message */ +#define IP6_MH_TYPE_COT 4 /* COT Message */ +#define IP6_MH_TYPE_BU 5 /* Binding Update */ +#define IP6_MH_TYPE_BACK 6 /* Binding ACK */ +#define IP6_MH_TYPE_BERROR 7 /* Binding Error */ +/* RFC 4068 */ +#define IP6_MH_TYPE_FBU 8 /* Fast Binding Update */ +#define IP6_MH_TYPE_FBACK 9 /* Fast Binding ACK */ +#define IP6_MH_TYPE_FNA 10 /* Fast Binding Advertisement */ +/* RFC 5096 */ +#define IP6_MH_TYPE_EMH 11 /* Experimental Mobility Header */ +/* RFC 5142 */ +#define IP6_MH_TYPE_HASM 12 /* Home Agent Switch Message */ + +#endif /* _HEADERS_H */ diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h new file mode 100644 index 00000000..2eb00b6c --- /dev/null +++ b/include/linux/netfilter.h @@ -0,0 +1,59 @@ +#ifndef __LINUX_NETFILTER_H +#define __LINUX_NETFILTER_H + +#include + + +/* Responses from hook functions. */ +#define NF_DROP 0 +#define NF_ACCEPT 1 +#define NF_STOLEN 2 +#define NF_QUEUE 3 +#define NF_REPEAT 4 +#define NF_STOP 5 +#define NF_MAX_VERDICT NF_STOP + +/* we overload the higher bits for encoding auxiliary data such as the queue + * number. Not nice, but better than additional function arguments. */ +#define NF_VERDICT_MASK 0x0000ffff +#define NF_VERDICT_BITS 16 + +#define NF_VERDICT_QMASK 0xffff0000 +#define NF_VERDICT_QBITS 16 + +#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) + +/* only for userspace compatibility */ +/* Generic cache responses from hook functions. + <= 0x2000 is used for protocol-flags. */ +#define NFC_UNKNOWN 0x4000 +#define NFC_ALTERED 0x8000 + +enum nf_inet_hooks { + NF_INET_PRE_ROUTING, + NF_INET_LOCAL_IN, + NF_INET_FORWARD, + NF_INET_LOCAL_OUT, + NF_INET_POST_ROUTING, + NF_INET_NUMHOOKS +}; + +enum { + NFPROTO_UNSPEC = 0, + NFPROTO_IPV4 = 2, + NFPROTO_ARP = 3, + NFPROTO_BRIDGE = 7, + NFPROTO_IPV6 = 10, + NFPROTO_DECNET = 12, + NFPROTO_NUMPROTO, +}; + +union nf_inet_addr { + __u32 all[4]; + __be32 ip; + __be32 ip6[4]; + struct in_addr in; + struct in6_addr in6; +}; + +#endif /*__LINUX_NETFILTER_H*/ diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h new file mode 100644 index 00000000..27a18952 --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -0,0 +1,152 @@ +#ifndef _NF_CONNTRACK_COMMON_H +#define _NF_CONNTRACK_COMMON_H +/* Connection state tracking for netfilter. This is separated from, + but required by, the NAT layer; it can also be used by an iptables + extension. */ +enum ip_conntrack_info +{ + /* Part of an established connection (either direction). */ + IP_CT_ESTABLISHED, + + /* Like NEW, but related to an existing connection, or ICMP error + (in either direction). */ + IP_CT_RELATED, + + /* Started a new connection to track (only + IP_CT_DIR_ORIGINAL); may be a retransmission. */ + IP_CT_NEW, + + /* >= this indicates reply direction */ + IP_CT_IS_REPLY, + + /* Number of distinct IP_CT types (no NEW in reply dirn). */ + IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1 +}; + +#define NF_CT_STATE_INVALID_BIT (1 << 0) +#define NF_CT_STATE_BIT(ctinfo) (1 << ((ctinfo) % IP_CT_IS_REPLY + 1)) +#define NF_CT_STATE_UNTRACKED_BIT (1 << (IP_CT_NUMBER + 1)) + +/* Bitset representing status of connection. */ +enum ip_conntrack_status { + /* It's an expected connection: bit 0 set. This bit never changed */ + IPS_EXPECTED_BIT = 0, + IPS_EXPECTED = (1 << IPS_EXPECTED_BIT), + + /* We've seen packets both ways: bit 1 set. Can be set, not unset. */ + IPS_SEEN_REPLY_BIT = 1, + IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT), + + /* Conntrack should never be early-expired. */ + IPS_ASSURED_BIT = 2, + IPS_ASSURED = (1 << IPS_ASSURED_BIT), + + /* Connection is confirmed: originating packet has left box */ + IPS_CONFIRMED_BIT = 3, + IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT), + + /* Connection needs src nat in orig dir. This bit never changed. */ + IPS_SRC_NAT_BIT = 4, + IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT), + + /* Connection needs dst nat in orig dir. This bit never changed. */ + IPS_DST_NAT_BIT = 5, + IPS_DST_NAT = (1 << IPS_DST_NAT_BIT), + + /* Both together. */ + IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT), + + /* Connection needs TCP sequence adjusted. */ + IPS_SEQ_ADJUST_BIT = 6, + IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT), + + /* NAT initialization bits. */ + IPS_SRC_NAT_DONE_BIT = 7, + IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT), + + IPS_DST_NAT_DONE_BIT = 8, + IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT), + + /* Both together */ + IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE), + + /* Connection is dying (removed from lists), can not be unset. */ + IPS_DYING_BIT = 9, + IPS_DYING = (1 << IPS_DYING_BIT), + + /* Connection has fixed timeout. */ + IPS_FIXED_TIMEOUT_BIT = 10, + IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT), +}; + +/* Connection tracking event bits */ +enum ip_conntrack_events +{ + /* New conntrack */ + IPCT_NEW_BIT = 0, + IPCT_NEW = (1 << IPCT_NEW_BIT), + + /* Expected connection */ + IPCT_RELATED_BIT = 1, + IPCT_RELATED = (1 << IPCT_RELATED_BIT), + + /* Destroyed conntrack */ + IPCT_DESTROY_BIT = 2, + IPCT_DESTROY = (1 << IPCT_DESTROY_BIT), + + /* Timer has been refreshed */ + IPCT_REFRESH_BIT = 3, + IPCT_REFRESH = (1 << IPCT_REFRESH_BIT), + + /* Status has changed */ + IPCT_STATUS_BIT = 4, + IPCT_STATUS = (1 << IPCT_STATUS_BIT), + + /* Update of protocol info */ + IPCT_PROTOINFO_BIT = 5, + IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT), + + /* Volatile protocol info */ + IPCT_PROTOINFO_VOLATILE_BIT = 6, + IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT), + + /* New helper for conntrack */ + IPCT_HELPER_BIT = 7, + IPCT_HELPER = (1 << IPCT_HELPER_BIT), + + /* Update of helper info */ + IPCT_HELPINFO_BIT = 8, + IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT), + + /* Volatile helper info */ + IPCT_HELPINFO_VOLATILE_BIT = 9, + IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT), + + /* NAT info */ + IPCT_NATINFO_BIT = 10, + IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), + + /* Counter highest bit has been set, unused */ + IPCT_COUNTER_FILLING_BIT = 11, + IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), + + /* Mark is set */ + IPCT_MARK_BIT = 12, + IPCT_MARK = (1 << IPCT_MARK_BIT), + + /* NAT sequence adjustment */ + IPCT_NATSEQADJ_BIT = 13, + IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT), + + /* Secmark is set */ + IPCT_SECMARK_BIT = 14, + IPCT_SECMARK = (1 << IPCT_SECMARK_BIT), +}; + +enum ip_conntrack_expect_events { + IPEXP_NEW_BIT = 0, + IPEXP_NEW = (1 << IPEXP_NEW_BIT), +}; + + +#endif /* _NF_CONNTRACK_COMMON_H */ diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/linux/netfilter/nf_conntrack_tuple_common.h new file mode 100644 index 00000000..8e145f0d --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_tuple_common.h @@ -0,0 +1,13 @@ +#ifndef _NF_CONNTRACK_TUPLE_COMMON_H +#define _NF_CONNTRACK_TUPLE_COMMON_H + +enum ip_conntrack_dir +{ + IP_CT_DIR_ORIGINAL, + IP_CT_DIR_REPLY, + IP_CT_DIR_MAX +}; + +#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) + +#endif /* _NF_CONNTRACK_TUPLE_COMMON_H */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h new file mode 100644 index 00000000..b4d518e3 --- /dev/null +++ b/include/linux/netfilter/nf_tables.h @@ -0,0 +1,337 @@ +#ifndef _LINUX_NF_TABLES_H +#define _LINUX_NF_TABLES_H + +enum nft_registers { + NFT_REG_VERDICT, + NFT_REG_1, + NFT_REG_2, + NFT_REG_3, + NFT_REG_4, + __NFT_REG_MAX +}; +#define NFT_REG_MAX (__NFT_REG_MAX - 1) + +enum nft_verdicts { + NFT_CONTINUE = -1, + NFT_BREAK = -2, + NFT_JUMP = -3, + NFT_GOTO = -4, + NFT_RETURN = -5, +}; + +enum nf_tables_msg_types { + NFT_MSG_NEWTABLE, + NFT_MSG_GETTABLE, + NFT_MSG_DELTABLE, + NFT_MSG_NEWCHAIN, + NFT_MSG_GETCHAIN, + NFT_MSG_DELCHAIN, + NFT_MSG_NEWRULE, + NFT_MSG_GETRULE, + NFT_MSG_DELRULE, + NFT_MSG_MAX, +}; + +enum nft_list_attributes { + NFTA_LIST_UNPEC, + NFTA_LIST_ELEM, + __NFTA_LIST_MAX +}; +#define NFTA_LIST_MAX (__NFTA_LIST_MAX - 1) + +enum nft_hook_attributes { + NFTA_HOOK_UNSPEC, + NFTA_HOOK_HOOKNUM, + NFTA_HOOK_PRIORITY, + __NFTA_HOOK_MAX +}; +#define NFTA_HOOK_MAX (__NFTA_HOOK_MAX - 1) + +enum nft_table_attributes { + NFTA_TABLE_UNSPEC, + NFTA_TABLE_NAME, + __NFTA_TABLE_MAX +}; +#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1) + +enum nft_chain_attributes { + NFTA_CHAIN_UNSPEC, + NFTA_CHAIN_TABLE, + NFTA_CHAIN_NAME, + NFTA_CHAIN_HOOK, + __NFTA_CHAIN_MAX +}; +#define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1) + +enum nft_rule_attributes { + NFTA_RULE_UNSPEC, + NFTA_RULE_TABLE, + NFTA_RULE_CHAIN, + NFTA_RULE_HANDLE, + NFTA_RULE_EXPRESSIONS, + __NFTA_RULE_MAX +}; +#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1) + +enum nft_data_attributes { + NFTA_DATA_UNSPEC, + NFTA_DATA_VALUE, + NFTA_DATA_VERDICT, + __NFTA_DATA_MAX +}; +#define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1) + +enum nft_verdict_attributes { + NFTA_VERDICT_UNSPEC, + NFTA_VERDICT_CODE, + NFTA_VERDICT_CHAIN, + __NFTA_VERDICT_MAX +}; +#define NFTA_VERDICT_MAX (__NFTA_VERDICT_MAX - 1) + +enum nft_expr_attributes { + NFTA_EXPR_UNSPEC, + NFTA_EXPR_NAME, + NFTA_EXPR_DATA, + __NFTA_EXPR_MAX +}; +#define NFTA_EXPR_MAX (__NFTA_EXPR_MAX - 1) + +enum nft_immediate_attributes { + NFTA_IMMEDIATE_UNSPEC, + NFTA_IMMEDIATE_DREG, + NFTA_IMMEDIATE_DATA, + __NFTA_IMMEDIATE_MAX +}; +#define NFTA_IMMEDIATE_MAX (__NFTA_IMMEDIATE_MAX - 1) + +enum nft_bitwise_attributes { + NFTA_BITWISE_UNSPEC, + NFTA_BITWISE_SREG, + NFTA_BITWISE_DREG, + NFTA_BITWISE_LEN, + NFTA_BITWISE_MASK, + NFTA_BITWISE_XOR, + __NFTA_BITWISE_MAX +}; +#define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1) + +enum nft_byteorder_ops { + NFT_BYTEORDER_NTOH, + NFT_BYTEORDER_HTON, +}; + +enum nft_byteorder_attributes { + NFTA_BYTEORDER_UNSPEC, + NFTA_BYTEORDER_SREG, + NFTA_BYTEORDER_DREG, + NFTA_BYTEORDER_OP, + NFTA_BYTEORDER_LEN, + NFTA_BYTEORDER_SIZE, + __NFTA_BYTEORDER_MAX +}; +#define NFTA_BYTEORDER_MAX (__NFTA_BYTEORDER_MAX - 1) + +enum nft_cmp_ops { + NFT_CMP_EQ, + NFT_CMP_NEQ, + NFT_CMP_LT, + NFT_CMP_LTE, + NFT_CMP_GT, + NFT_CMP_GTE, +}; + +enum nft_cmp_attributes { + NFTA_CMP_UNSPEC, + NFTA_CMP_SREG, + NFTA_CMP_OP, + NFTA_CMP_DATA, + __NFTA_CMP_MAX +}; +#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) + +enum nft_set_elem_flags { + NFT_SE_INTERVAL_END = 0x1, +}; + +enum nft_set_elem_attributes { + NFTA_SE_UNSPEC, + NFTA_SE_KEY, + NFTA_SE_DATA, + NFTA_SE_FLAGS, + __NFTA_SE_MAX +}; +#define NFTA_SE_MAX (__NFTA_SE_MAX - 1) + +enum nft_set_flags { + NFT_SET_INTERVAL = 0x1, + NFT_SET_MAP = 0x2, +}; + +enum nft_set_attributes { + NFTA_SET_UNSPEC, + NFTA_SET_FLAGS, + NFTA_SET_SREG, + NFTA_SET_DREG, + NFTA_SET_KLEN, + NFTA_SET_ELEMENTS, + __NFTA_SET_MAX +}; +#define NFTA_SET_MAX (__NFTA_SET_MAX - 1) + +enum nft_hash_flags { + NFT_HASH_MAP = 0x1, +}; + +enum nft_hash_elem_attributes { + NFTA_HE_UNSPEC, + NFTA_HE_KEY, + NFTA_HE_DATA, + __NFTA_HE_MAX +}; +#define NFTA_HE_MAX (__NFTA_HE_MAX - 1) + +enum nft_hash_attributes { + NFTA_HASH_UNSPEC, + NFTA_HASH_FLAGS, + NFTA_HASH_SREG, + NFTA_HASH_DREG, + NFTA_HASH_KLEN, + NFTA_HASH_ELEMENTS, + __NFTA_HASH_MAX +}; +#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1) + +enum nft_payload_bases { + NFT_PAYLOAD_LL_HEADER, + NFT_PAYLOAD_NETWORK_HEADER, + NFT_PAYLOAD_TRANSPORT_HEADER, +}; + +enum nft_payload_attributes { + NFTA_PAYLOAD_UNSPEC, + NFTA_PAYLOAD_DREG, + NFTA_PAYLOAD_BASE, + NFTA_PAYLOAD_OFFSET, + NFTA_PAYLOAD_LEN, + __NFTA_PAYLOAD_MAX +}; +#define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1) + +enum nft_exthdr_attributes { + NFTA_EXTHDR_UNSPEC, + NFTA_EXTHDR_DREG, + NFTA_EXTHDR_TYPE, + NFTA_EXTHDR_OFFSET, + NFTA_EXTHDR_LEN, + __NFTA_EXTHDR_MAX +}; +#define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1) + +enum nft_meta_keys { + NFT_META_LEN, + NFT_META_PROTOCOL, + NFT_META_PRIORITY, + NFT_META_MARK, + NFT_META_IIF, + NFT_META_OIF, + NFT_META_IIFNAME, + NFT_META_OIFNAME, + NFT_META_IIFTYPE, + NFT_META_OIFTYPE, + NFT_META_SKUID, + NFT_META_SKGID, + NFT_META_NFTRACE, + NFT_META_RTCLASSID, + NFT_META_SECMARK, +}; + +enum nft_meta_attributes { + NFTA_META_UNSPEC, + NFTA_META_DREG, + NFTA_META_KEY, + __NFTA_META_MAX +}; +#define NFTA_META_MAX (__NFTA_META_MAX - 1) + +enum nft_ct_keys { + NFT_CT_STATE, + NFT_CT_DIRECTION, + NFT_CT_STATUS, + NFT_CT_MARK, + NFT_CT_SECMARK, + NFT_CT_EXPIRATION, + NFT_CT_HELPER, + NFT_CT_L3PROTO, + NFT_CT_SADDR, + NFT_CT_DADDR, + NFT_CT_PROTOCOL, + NFT_CT_PROTO_SRC, + NFT_CT_PROTO_DST, +}; + +enum nft_ct_attributes { + NFTA_CT_UNSPEC, + NFTA_CT_DREG, + NFTA_CT_KEY, + NFTA_CT_DIRECTION, + __NFTA_CT_MAX +}; +#define NFTA_CT_MAX (__NFTA_CT_MAX - 1) + +enum nft_limit_attributes { + NFTA_LIMIT_UNSPEC, + NFTA_LIMIT_RATE, + NFTA_LIMIT_DEPTH, + __NFTA_LIMIT_MAX +}; +#define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1) + +enum nft_counter_attributes { + NFTA_COUNTER_UNSPEC, + NFTA_COUNTER_BYTES, + NFTA_COUNTER_PACKETS, + __NFTA_COUNTER_MAX +}; +#define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1) + +enum nft_log_attributes { + NFTA_LOG_UNSPEC, + NFTA_LOG_GROUP, + NFTA_LOG_PREFIX, + NFTA_LOG_SNAPLEN, + NFTA_LOG_QTHRESHOLD, + __NFTA_LOG_MAX +}; +#define NFTA_LOG_MAX (__NFTA_LOG_MAX - 1) + +enum nft_reject_types { + NFT_REJECT_ICMP_UNREACH, + NFT_REJECT_TCP_RST, +}; + +enum nft_reject_attributes { + NFTA_REJECT_UNSPEC, + NFTA_REJECT_TYPE, + NFTA_REJECT_ICMP_CODE, + __NFTA_REJECT_MAX +}; +#define NFTA_REJECT_MAX (__NFTA_REJECT_MAX - 1) + +enum nft_nat_types { + NFT_NAT_SNAT, + NFT_NAT_DNAT, +}; + +enum nft_nat_attributes { + NFTA_NAT_UNSPEC, + NFTA_NAT_TYPE, + NFTA_NAT_ADDR_MIN, + NFTA_NAT_ADDR_MAX, + NFTA_NAT_PROTO_MIN, + NFTA_NAT_PROTO_MAX, + __NFTA_NAT_MAX +}; +#define NFTA_NAT_MAX (__NFTA_NAT_MAX - 1) + +#endif /* _LINUX_NF_TABLES_H */ diff --git a/include/linux/netfilter_arp.h b/include/linux/netfilter_arp.h new file mode 100644 index 00000000..92bc6ddc --- /dev/null +++ b/include/linux/netfilter_arp.h @@ -0,0 +1,19 @@ +#ifndef __LINUX_ARP_NETFILTER_H +#define __LINUX_ARP_NETFILTER_H + +/* ARP-specific defines for netfilter. + * (C)2002 Rusty Russell IBM -- This code is GPL. + */ + +#include + +/* There is no PF_ARP. */ +#define NF_ARP 0 + +/* ARP Hooks */ +#define NF_ARP_IN 0 +#define NF_ARP_OUT 1 +#define NF_ARP_FORWARD 2 +#define NF_ARP_NUMHOOKS 3 + +#endif /* __LINUX_ARP_NETFILTER_H */ diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h new file mode 100644 index 00000000..5094ecca --- /dev/null +++ b/include/linux/netfilter_bridge.h @@ -0,0 +1,27 @@ +#ifndef __LINUX_BRIDGE_NETFILTER_H +#define __LINUX_BRIDGE_NETFILTER_H + +/* bridge-specific defines for netfilter. + */ + +#include +#include +#include +#include + +/* Bridge Hooks */ +/* After promisc drops, checksum checks. */ +#define NF_BR_PRE_ROUTING 0 +/* If the packet is destined for this box. */ +#define NF_BR_LOCAL_IN 1 +/* If the packet is destined for another interface. */ +#define NF_BR_FORWARD 2 +/* Packets coming from a local process. */ +#define NF_BR_LOCAL_OUT 3 +/* Packets about to hit the wire. */ +#define NF_BR_POST_ROUTING 4 +/* Not really a hook, but used for the ebtables broute table */ +#define NF_BR_BROUTING 5 +#define NF_BR_NUMHOOKS 6 + +#endif diff --git a/include/linux/netfilter_decnet.h b/include/linux/netfilter_decnet.h new file mode 100644 index 00000000..ca70c6cd --- /dev/null +++ b/include/linux/netfilter_decnet.h @@ -0,0 +1,72 @@ +#ifndef __LINUX_DECNET_NETFILTER_H +#define __LINUX_DECNET_NETFILTER_H + +/* DECnet-specific defines for netfilter. + * This file (C) Steve Whitehouse 1999 derived from the + * ipv4 netfilter header file which is + * (C)1998 Rusty Russell -- This code is GPL. + */ + +#include + +/* only for userspace compatibility */ +/* IP Cache bits. */ +/* Src IP address. */ +#define NFC_DN_SRC 0x0001 +/* Dest IP address. */ +#define NFC_DN_DST 0x0002 +/* Input device. */ +#define NFC_DN_IF_IN 0x0004 +/* Output device. */ +#define NFC_DN_IF_OUT 0x0008 + +/* DECnet Hooks */ +/* After promisc drops, checksum checks. */ +#define NF_DN_PRE_ROUTING 0 +/* If the packet is destined for this box. */ +#define NF_DN_LOCAL_IN 1 +/* If the packet is destined for another interface. */ +#define NF_DN_FORWARD 2 +/* Packets coming from a local process. */ +#define NF_DN_LOCAL_OUT 3 +/* Packets about to hit the wire. */ +#define NF_DN_POST_ROUTING 4 +/* Input Hello Packets */ +#define NF_DN_HELLO 5 +/* Input Routing Packets */ +#define NF_DN_ROUTE 6 +#define NF_DN_NUMHOOKS 7 + +enum nf_dn_hook_priorities { + NF_DN_PRI_FIRST = INT_MIN, + NF_DN_PRI_CONNTRACK = -200, + NF_DN_PRI_MANGLE = -150, + NF_DN_PRI_NAT_DST = -100, + NF_DN_PRI_FILTER = 0, + NF_DN_PRI_NAT_SRC = 100, + NF_DN_PRI_DNRTMSG = 200, + NF_DN_PRI_LAST = INT_MAX, +}; + +struct nf_dn_rtmsg { + int nfdn_ifindex; +}; + +#define NFDN_RTMSG(r) ((unsigned char *)(r) + NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg))) + +/* backwards compatibility for userspace */ +#define DNRMG_L1_GROUP 0x01 +#define DNRMG_L2_GROUP 0x02 + +enum { + DNRNG_NLGRP_NONE, +#define DNRNG_NLGRP_NONE DNRNG_NLGRP_NONE + DNRNG_NLGRP_L1, +#define DNRNG_NLGRP_L1 DNRNG_NLGRP_L1 + DNRNG_NLGRP_L2, +#define DNRNG_NLGRP_L2 DNRNG_NLGRP_L2 + __DNRNG_NLGRP_MAX +}; +#define DNRNG_NLGRP_MAX (__DNRNG_NLGRP_MAX - 1) + +#endif /*__LINUX_DECNET_NETFILTER_H*/ diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h new file mode 100644 index 00000000..4d7ba3e4 --- /dev/null +++ b/include/linux/netfilter_ipv4.h @@ -0,0 +1,75 @@ +#ifndef __LINUX_IP_NETFILTER_H +#define __LINUX_IP_NETFILTER_H + +/* IPv4-specific defines for netfilter. + * (C)1998 Rusty Russell -- This code is GPL. + */ + +#include + +/* only for userspace compatibility */ +/* IP Cache bits. */ +/* Src IP address. */ +#define NFC_IP_SRC 0x0001 +/* Dest IP address. */ +#define NFC_IP_DST 0x0002 +/* Input device. */ +#define NFC_IP_IF_IN 0x0004 +/* Output device. */ +#define NFC_IP_IF_OUT 0x0008 +/* TOS. */ +#define NFC_IP_TOS 0x0010 +/* Protocol. */ +#define NFC_IP_PROTO 0x0020 +/* IP options. */ +#define NFC_IP_OPTIONS 0x0040 +/* Frag & flags. */ +#define NFC_IP_FRAG 0x0080 + +/* Per-protocol information: only matters if proto match. */ +/* TCP flags. */ +#define NFC_IP_TCPFLAGS 0x0100 +/* Source port. */ +#define NFC_IP_SRC_PT 0x0200 +/* Dest port. */ +#define NFC_IP_DST_PT 0x0400 +/* Something else about the proto */ +#define NFC_IP_PROTO_UNKNOWN 0x2000 + +/* IP Hooks */ +/* After promisc drops, checksum checks. */ +#define NF_IP_PRE_ROUTING 0 +/* If the packet is destined for this box. */ +#define NF_IP_LOCAL_IN 1 +/* If the packet is destined for another interface. */ +#define NF_IP_FORWARD 2 +/* Packets coming from a local process. */ +#define NF_IP_LOCAL_OUT 3 +/* Packets about to hit the wire. */ +#define NF_IP_POST_ROUTING 4 +#define NF_IP_NUMHOOKS 5 + +enum nf_ip_hook_priorities { + NF_IP_PRI_FIRST = INT_MIN, + NF_IP_PRI_CONNTRACK_DEFRAG = -400, + NF_IP_PRI_RAW = -300, + NF_IP_PRI_SELINUX_FIRST = -225, + NF_IP_PRI_CONNTRACK = -200, + NF_IP_PRI_MANGLE = -150, + NF_IP_PRI_NAT_DST = -100, + NF_IP_PRI_FILTER = 0, + NF_IP_PRI_SECURITY = 50, + NF_IP_PRI_NAT_SRC = 100, + NF_IP_PRI_SELINUX_LAST = 225, + NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, + NF_IP_PRI_LAST = INT_MAX, +}; + +/* Arguments for setsockopt SOL_IP: */ +/* 2.0 firewalling went from 64 through 71 (and +256, +512, etc). */ +/* 2.2 firewalling (+ masq) went from 64 through 76 */ +/* 2.4 firewalling went 64 through 67. */ +#define SO_ORIGINAL_DST 80 + + +#endif /*__LINUX_IP_NETFILTER_H*/ diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h new file mode 100644 index 00000000..7430b392 --- /dev/null +++ b/include/linux/netfilter_ipv6.h @@ -0,0 +1,72 @@ +#ifndef __LINUX_IP6_NETFILTER_H +#define __LINUX_IP6_NETFILTER_H + +/* IPv6-specific defines for netfilter. + * (C)1998 Rusty Russell -- This code is GPL. + * (C)1999 David Jeffery + * this header was blatantly ripped from netfilter_ipv4.h + * it's amazing what adding a bunch of 6s can do =8^) + */ + +#include + +/* only for userspace compatibility */ +/* IP Cache bits. */ +/* Src IP address. */ +#define NFC_IP6_SRC 0x0001 +/* Dest IP address. */ +#define NFC_IP6_DST 0x0002 +/* Input device. */ +#define NFC_IP6_IF_IN 0x0004 +/* Output device. */ +#define NFC_IP6_IF_OUT 0x0008 +/* TOS. */ +#define NFC_IP6_TOS 0x0010 +/* Protocol. */ +#define NFC_IP6_PROTO 0x0020 +/* IP options. */ +#define NFC_IP6_OPTIONS 0x0040 +/* Frag & flags. */ +#define NFC_IP6_FRAG 0x0080 + + +/* Per-protocol information: only matters if proto match. */ +/* TCP flags. */ +#define NFC_IP6_TCPFLAGS 0x0100 +/* Source port. */ +#define NFC_IP6_SRC_PT 0x0200 +/* Dest port. */ +#define NFC_IP6_DST_PT 0x0400 +/* Something else about the proto */ +#define NFC_IP6_PROTO_UNKNOWN 0x2000 + +/* IP6 Hooks */ +/* After promisc drops, checksum checks. */ +#define NF_IP6_PRE_ROUTING 0 +/* If the packet is destined for this box. */ +#define NF_IP6_LOCAL_IN 1 +/* If the packet is destined for another interface. */ +#define NF_IP6_FORWARD 2 +/* Packets coming from a local process. */ +#define NF_IP6_LOCAL_OUT 3 +/* Packets about to hit the wire. */ +#define NF_IP6_POST_ROUTING 4 +#define NF_IP6_NUMHOOKS 5 + + +enum nf_ip6_hook_priorities { + NF_IP6_PRI_FIRST = INT_MIN, + NF_IP6_PRI_CONNTRACK_DEFRAG = -400, + NF_IP6_PRI_SELINUX_FIRST = -225, + NF_IP6_PRI_CONNTRACK = -200, + NF_IP6_PRI_MANGLE = -150, + NF_IP6_PRI_NAT_DST = -100, + NF_IP6_PRI_FILTER = 0, + NF_IP6_PRI_SECURITY = 50, + NF_IP6_PRI_NAT_SRC = 100, + NF_IP6_PRI_SELINUX_LAST = 225, + NF_IP6_PRI_LAST = INT_MAX, +}; + + +#endif /*__LINUX_IP6_NETFILTER_H*/ diff --git a/include/list.h b/include/list.h new file mode 100644 index 00000000..75d29212 --- /dev/null +++ b/include/list.h @@ -0,0 +1,625 @@ +#ifndef _LINUX_LIST_H +#define _LINUX_LIST_H + +#include + +#define prefetch(x) ((void)0) + +#define LIST_POISON1 ((void *)0x12345678) +#define LIST_POISON2 ((void *)0x87654321) + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void init_list_head(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} + +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +static inline void list_replace_init(struct list_head *old, + struct list_head *new) +{ + list_replace(old, new); + init_list_head(old); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + init_list_head(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_last(const struct list_head *list, + const struct list_head *head) +{ + return list->next == head; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +/** + * list_empty_careful - tests whether a list is empty and not being modified + * @head: the list to test + * + * Description: + * tests whether a list is empty _and_ checks that no other CPU might be + * in the process of modifying either member (next or prev) + * + * NOTE: using list_empty_careful() without synchronization + * can only be safe if the only activity that can happen + * to the list entry is list_del_init(). Eg. it cannot be used + * if another CPU could re-list_add() it. + */ +static inline int list_empty_careful(const struct list_head *head) +{ + struct list_head *next = head->next; + return (next == head) && (next == head->prev); +} + +/** + * list_is_singular - tests whether a list has just one entry. + * @head: the list to test. + */ +static inline int list_is_singular(const struct list_head *head) +{ + return !list_empty(head) && (head->next == head->prev); +} + +static inline void __list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + struct list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + if (list_empty(head)) + return; + if (list_is_singular(head) && + (head->next != entry && head != entry)) + return; + if (entry == head) + init_list_head(list); + else + __list_cut_position(list, head, entry); +} + +static inline void __list_splice(const struct list_head *list, + struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice - join two lists, this is designed for stacks + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(const struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice_tail(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head->prev, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head, head->next); + init_list_head(list); + } +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void list_splice_tail_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head->prev, head); + init_list_head(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ + prefetch(pos->member.prev), &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() + * @pos: the type * to use as a start point + * @head: the head of the list + * @member: the name of the list_struct within the struct. + * + * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). + */ +#define list_prepare_entry(pos, head, member) \ + ((pos) ? : list_entry(head, typeof(*pos), member)) + +/** + * list_for_each_entry_continue - continue iteration over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Continue to iterate over list of given type, continuing after + * the current position. + */ +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = list_entry(pos->member.next, typeof(*pos), member); \ + prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_continue_reverse - iterate backwards from the given point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Start to iterate over list of given type backwards, continuing after + * the current position. + */ +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ + prefetch(pos->member.prev), &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_for_each_entry_from - iterate over list of given type from the current point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing from current position. + */ +#define list_for_each_entry_from(pos, head, member) \ + for (; prefetch(pos->member.next), &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_continue + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = list_entry(pos->member.next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_from + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define list_for_each_entry_safe_from(pos, n, head, member) \ + for (n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_reverse + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define list_for_each_entry_safe_reverse(pos, n, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member), \ + n = list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.prev, typeof(*n), member)) + +/* + * Double linked lists with a single pointer list head. + * Mostly useful for hash tables where the two pointer list head is + * too wasteful. + * You lose the ability to access the tail in O(1). + */ + +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +#define HLIST_HEAD_INIT { .first = NULL } +#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } + +#define init_hlist_head(ptr) ((ptr)->first = NULL) + +static inline void init_hlist_node(struct hlist_node *h) +{ + h->next = NULL; + h->pprev = NULL; +} + +static inline int hlist_unhashed(const struct hlist_node *h) +{ + return !h->pprev; +} + +static inline int hlist_empty(const struct hlist_head *h) +{ + return !h->first; +} + +static inline void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + *pprev = next; + if (next) + next->pprev = pprev; +} + +static inline void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = LIST_POISON1; + n->pprev = LIST_POISON2; +} + +static inline void hlist_del_init(struct hlist_node *n) +{ + if (!hlist_unhashed(n)) { + __hlist_del(n); + init_hlist_node(n); + } +} + +static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + if (first) + first->pprev = &n->next; + h->first = n; + n->pprev = &h->first; +} + +/* next must be != NULL */ +static inline void hlist_add_before(struct hlist_node *n, + struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +static inline void hlist_add_after(struct hlist_node *n, + struct hlist_node *next) +{ + next->next = n->next; + n->next = next; + next->pprev = &n->next; + + if(next->next) + next->next->pprev = &next->next; +} + +#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + +#define hlist_for_each(pos, head) \ + for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ + pos = pos->next) + +#define hlist_for_each_safe(pos, n, head) \ + for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ + pos = n) + +/** + * hlist_for_each_entry - iterate over list of given type + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry(tpos, pos, head, member) \ + for (pos = (head)->first; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_continue - iterate over a hlist continuing after current point + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_continue(tpos, pos, member) \ + for (pos = (pos)->next; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_from - iterate over a hlist continuing from current point + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_from(tpos, pos, member) \ + for (; pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @n: another &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ + for (pos = (head)->first; \ + pos && ({ n = pos->next; 1; }) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = n) + +#endif diff --git a/include/meta.h b/include/meta.h new file mode 100644 index 00000000..75b1f1eb --- /dev/null +++ b/include/meta.h @@ -0,0 +1,29 @@ +#ifndef _META_H +#define _META_H + +/** + * struct meta_template - template for meta expressions and statements + * + * @token: parser token for the expression + * @dtype: data type of the expression + * @len: length of the expression + * @byteorder: byteorder + */ +struct meta_template { + const char *token; + const struct datatype *dtype; + enum byteorder byteorder; + unsigned int len; +}; + +#define META_TEMPLATE(__token, __dtype, __len, __byteorder) { \ + .token = (__token), \ + .dtype = (__dtype), \ + .len = (__len), \ + .byteorder = (__byteorder), \ +} + +extern struct expr *meta_expr_alloc(const struct location *loc, + enum nft_meta_keys key); + +#endif /* _META_H */ diff --git a/include/netlink.h b/include/netlink.h new file mode 100644 index 00000000..4849ff51 --- /dev/null +++ b/include/netlink.h @@ -0,0 +1,60 @@ +#ifndef _NETLINK_H +#define _NETLINK_H + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * struct netlink_ctx + * + * @msgs: message queue + * @list: list of parsed rules/chains/tables + */ +struct netlink_ctx { + struct list_head *msgs; + struct list_head list; +}; + +extern void netlink_dump_object(struct nl_object *obj); + +extern struct nfnl_nft_table *alloc_nft_table(const struct handle *h); +extern struct nfnl_nft_chain *alloc_nft_chain(const struct handle *h); +extern struct nfnl_nft_rule *alloc_nft_rule(const struct handle *h); +extern struct nfnl_nft_expr *alloc_nft_expr(int (*init)(struct nfnl_nft_expr *)); +extern struct nfnl_nft_data *alloc_nft_data(const void *data, unsigned int len); + +extern int netlink_linearize_rule(struct netlink_ctx *ctx, + struct nfnl_nft_rule *nlr, + const struct rule *rule); +extern struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx, + const struct nl_object *obj); + +extern int netlink_add_rule(struct netlink_ctx *ctx, const struct handle *h, + const struct rule *rule); +extern int netlink_delete_rule(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_get_rule(struct netlink_ctx *ctx, const struct handle *h); + +extern int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h, + const struct chain *chain); +extern int netlink_delete_chain(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_list_chains(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_get_chain(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_list_chain(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_flush_chain(struct netlink_ctx *ctx, const struct handle *h); + +extern int netlink_add_table(struct netlink_ctx *ctx, const struct handle *h, + const struct table *table); +extern int netlink_delete_table(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_list_tables(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_get_table(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_list_table(struct netlink_ctx *ctx, const struct handle *h); +extern int netlink_flush_table(struct netlink_ctx *ctx, const struct handle *h); + +#endif /* _NETLINK_H */ diff --git a/include/nftables.h b/include/nftables.h new file mode 100644 index 00000000..7e4a2fc8 --- /dev/null +++ b/include/nftables.h @@ -0,0 +1,96 @@ +#ifndef _NFTABLES_H +#define _NFTABLES_H + +#include +#include +#include + +enum numeric_level { + NUMERIC_NONE, + NUMERIC_ADDR, + NUMERIC_ALL, +}; + +#define INCLUDE_PATHS_MAX 16 + +extern unsigned int numeric_output; +extern const char *include_paths[INCLUDE_PATHS_MAX]; + +struct parser_state; +extern int cli_init(void *scanner, struct parser_state *state); +extern void cli_exit(void); +extern void cli_display(const char *fmt, va_list ap) __fmtstring(1, 0); + +enum nftables_exit_codes { + NFT_EXIT_SUCCESS = 0, + NFT_EXIT_FAILURE = 1, + NFT_EXIT_NOMEM = 2, +}; + +struct input_descriptor; +struct location { + const struct input_descriptor *indesc; + union { + struct { + off_t token_offset; + off_t line_offset; + + unsigned int first_line; + unsigned int last_line; + unsigned int first_column; + unsigned int last_column; + }; + struct { + struct nl_object *nl_obj; + }; + }; +}; + +extern const struct location internal_location; + +/** + * enum input_descriptor_types + * + * @INDESC_INVALID: invalid + * @INDESC_INTERNAL: dummy type for internally generated messages + * @INDESC_BUFFER: buffer (command line arguments) + * @INDESC_FILE: file + * @INDESC_CLI: command line interface + * @INDESC_NETLINK: received from netlink + */ +enum input_descriptor_types { + INDESC_INVALID, + INDESC_INTERNAL, + INDESC_BUFFER, + INDESC_FILE, + INDESC_CLI, + INDESC_NETLINK, +}; + +/** + * struct input_descriptor + * + * @location: location, used for include statements + * @type: input descriptor type + * @name: name describing the input + * @union: buffer or file descriptor, depending on type + * @lineno: current line number in the input + * @column: current column in the input + * @token_offset: offset of the current token to the beginning + * @line_offset: offset of the current line to the beginning + */ +struct input_descriptor { + struct location location; + enum input_descriptor_types type; + const char *name; + union { + const char *data; + int fd; + }; + unsigned int lineno; + unsigned int column; + off_t token_offset; + off_t line_offset; +}; + +#endif /* _NFTABLES_H */ diff --git a/include/parser.h b/include/parser.h new file mode 100644 index 00000000..2a4c73b4 --- /dev/null +++ b/include/parser.h @@ -0,0 +1,36 @@ +#ifndef _PARSER_H +#define _PARSER_H + +#include + +#define MAX_INCLUDE_DEPTH 16 +#define TABSIZE 8 + +#define YYLTYPE struct location +#define YYLTYPE_IS_TRIVIAL 0 +#define YYENABLE_NLS 0 + +struct parser_state { + struct input_descriptor *indesc; + struct input_descriptor indescs[MAX_INCLUDE_DEPTH]; + unsigned int indesc_idx; + + struct list_head *msgs; + struct list_head cmds; +}; + +extern void parser_init(struct parser_state *state, struct list_head *msgs); +extern int nft_parse(void *, struct parser_state *state); + +extern void *scanner_init(struct parser_state *state); +extern void scanner_destroy(struct parser_state *state); + +extern int scanner_read_file(void *scanner, const char *filename, + const struct location *loc); +extern int scanner_include_file(void *scanner, const char *filename, + const struct location *loc); +extern void scanner_push_buffer(void *scanner, + const struct input_descriptor *indesc, + const char *buffer); + +#endif /* _PARSER_H */ diff --git a/include/payload.h b/include/payload.h new file mode 100644 index 00000000..ff9b1381 --- /dev/null +++ b/include/payload.h @@ -0,0 +1,289 @@ +#ifndef _PAYLOAD_H +#define _PAYLOAD_H + +#include + +/** + * enum payload_bases + * + * @PAYLOAD_BASE_INVALID: uninitialised, does not happen + * @PAYLOAD_BASE_LL_HDR: link layer header + * @PAYLOAD_BASE_NETWORK_HDR: network layer header + * @PAYLOAD_BASE_TRANSPORT_HDR: transport layer header + */ +enum payload_bases { + PAYLOAD_BASE_INVALID, + PAYLOAD_BASE_LL_HDR, + PAYLOAD_BASE_NETWORK_HDR, + PAYLOAD_BASE_TRANSPORT_HDR, + __PAYLOAD_BASE_MAX +}; +#define PAYLOAD_BASE_MAX (__PAYLOAD_BASE_MAX - 1) + +/** + * enum payload_expr_flags + * + * @PAYLOAD_PROTOCOL_EXPR: payload expression contains upper layer protocol + */ +enum payload_expr_flags { + PAYLOAD_PROTOCOL_EXPR = 0x1, +}; + +/** + * struct payload_template - template for a payload header expression + * + * @token: parser token describing the header field + * @dtype: data type of the expression + * @offset: offset from base + * @len: length of header field + */ +struct payload_template { + const char *token; + const struct datatype *dtype; + uint16_t offset; + uint16_t len; +}; + +#define PAYLOAD_TEMPLATE(__token, __dtype, __offset, __len) \ + { \ + .token = (__token), \ + .dtype = (__dtype), \ + .offset = (__offset), \ + .len = (__len), \ + } + +#define PAYLOAD_PROTO_MAX 16 +#define PAYLOAD_TEMPLATE_MAX 20 + +/** + * struct payload_desc - payload protocol description + * + * @name: protocol name + * @base: header base + * @protocol_key: key of template containing upper layer protocol description + * @protocols: link to upper layer protocol description indexed by protocol value + * @templates: header templates + */ +struct payload_desc { + const char *name; + enum payload_bases base; + unsigned int protocol_key; + struct { + unsigned int num; + const struct payload_desc *desc; + } protocols[PAYLOAD_PROTO_MAX]; + struct payload_template templates[PAYLOAD_TEMPLATE_MAX]; +}; + +#define PAYLOAD_PROTO(__num, __desc) { .num = (__num), .desc = (__desc), } + +/** + * struct payload_hook_desc - description of constraints imposed by hook family + * + * @base: protocol base of packets + * @desc: protocol description of packets + */ +struct payload_hook_desc { + enum payload_bases base; + const struct payload_desc *desc; +}; + +#define PAYLOAD_HOOK(__base, __desc) { .base = (__base), .desc = (__desc), } + +/** + * struct dev_payload_desc - description of device LL protocol + * + * @desc: protocol description + * @type: arphrd value + */ +struct dev_payload_desc { + const struct payload_desc *desc; + uint16_t type; +}; + +#define DEV_PAYLOAD_DESC(__type, __desc) { .type = (__type), .desc = (__desc), } + +/** + * struct payload_ctx - payload expression protocol context + * + * @family: hook family + * @location: location of expression defining the context + * @desc: payload description for this layer + * + * The location of the context is the location of the relational expression + * defining it, either directly through a protocol match or indirectly + * through a dependency. + */ +struct payload_ctx { + unsigned int family; + struct { + struct location location; + const struct payload_desc *desc; + } protocol[PAYLOAD_BASE_MAX + 1]; +}; + +extern struct expr *payload_expr_alloc(const struct location *loc, + const struct payload_desc *desc, + unsigned int type); +extern void payload_init_raw(struct expr *expr, enum payload_bases base, + unsigned int offset, unsigned int len); + +extern void payload_ctx_init(struct payload_ctx *ctx, unsigned int family); +extern void payload_ctx_update_meta(struct payload_ctx *ctx, + const struct expr *expr); +extern void payload_ctx_update(struct payload_ctx *ctx, + const struct expr *expr); + +struct eval_ctx; +extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr, + struct expr **res); + +extern bool payload_is_adjacent(const struct expr *e1, const struct expr *e2); +extern struct expr *payload_expr_join(const struct expr *e1, + const struct expr *e2); + +extern void payload_expr_expand(struct list_head *list, struct expr *expr, + const struct payload_ctx *ctx); +extern void payload_expr_complete(struct expr *expr, + const struct payload_ctx *ctx); + +enum eth_hdr_fields { + ETHHDR_INVALID, + ETHHDR_DADDR, + ETHHDR_SADDR, + ETHHDR_TYPE, +}; + +enum vlan_hdr_fields { + VLANHDR_INVALID, + VLANHDR_VID, + VLANHDR_CFI, + VLANHDR_PCP, + VLANHDR_TYPE, +}; + +enum arp_hdr_fields { + ARPHDR_INVALID, + ARPHDR_HRD, + ARPHDR_PRO, + ARPHDR_HLN, + ARPHDR_PLN, + ARPHDR_OP, +}; + +enum ip_hdr_fields { + IPHDR_INVALID, + IPHDR_VERSION, + IPHDR_HDRLENGTH, + IPHDR_TOS, + IPHDR_LENGTH, + IPHDR_ID, + IPHDR_FRAG_OFF, + IPHDR_TTL, + IPHDR_PROTOCOL, + IPHDR_CHECKSUM, + IPHDR_SADDR, + IPHDR_DADDR, +}; + +enum icmp_hdr_fields { + ICMPHDR_INVALID, + ICMPHDR_TYPE, + ICMPHDR_CODE, + ICMPHDR_CHECKSUM, + ICMPHDR_ID, + ICMPHDR_SEQ, + ICMPHDR_GATEWAY, + ICMPHDR_MTU, +}; + +enum ip6_hdr_fields { + IP6HDR_INVALID, + IP6HDR_VERSION, + IP6HDR_PRIORITY, + IP6HDR_FLOWLABEL, + IP6HDR_LENGTH, + IP6HDR_NEXTHDR, + IP6HDR_HOPLIMIT, + IP6HDR_SADDR, + IP6HDR_DADDR, +}; + +enum ah_hdr_fields { + AHHDR_INVALID, + AHHDR_NEXTHDR, + AHHDR_HDRLENGTH, + AHHDR_RESERVED, + AHHDR_SPI, + AHHDR_SEQUENCE, +}; + +enum esp_hdr_fields { + ESPHDR_INVALID, + ESPHDR_SPI, + ESPHDR_SEQUENCE, +}; + +enum comp_hdr_fields { + COMPHDR_INVALID, + COMPHDR_NEXTHDR, + COMPHDR_FLAGS, + COMPHDR_CPI, +}; + +enum udp_hdr_fields { + UDPHDR_INVALID, + UDPHDR_SPORT, + UDPHDR_DPORT, + UDPHDR_LENGTH, + UDPHDR_CSUMCOV = UDPHDR_LENGTH, + UDPHDR_CHECKSUM, +}; + +enum tcp_hdr_fields { + TCPHDR_INVALID, + TCPHDR_SPORT, + TCPHDR_DPORT, + TCPHDR_SEQ, + TCPHDR_ACKSEQ, + TCPHDR_DOFF, + TCPHDR_RESERVED, + TCPHDR_FLAGS, + TCPHDR_WINDOW, + TCPHDR_CHECKSUM, + TCPHDR_URGPTR, +}; + +enum dccp_hdr_fields { + DCCPHDR_INVALID, + DCCPHDR_SPORT, + DCCPHDR_DPORT, +}; + +enum sctp_hdr_fields { + SCTPHDR_INVALID, + SCTPHDR_SPORT, + SCTPHDR_DPORT, + SCTPHDR_VTAG, + SCTPHDR_CHECKSUM, +}; + +extern const struct payload_desc payload_icmp; +extern const struct payload_desc payload_ah; +extern const struct payload_desc payload_esp; +extern const struct payload_desc payload_comp; +extern const struct payload_desc payload_udp; +extern const struct payload_desc payload_udplite; +extern const struct payload_desc payload_tcp; +extern const struct payload_desc payload_dccp; +extern const struct payload_desc payload_sctp; + +extern const struct payload_desc payload_ip; +extern const struct payload_desc payload_ip6; + +extern const struct payload_desc payload_arp; + +extern const struct payload_desc payload_vlan; +extern const struct payload_desc payload_eth; + +#endif /* _PAYLOAD_H */ diff --git a/include/rbtree.h b/include/rbtree.h new file mode 100644 index 00000000..26b6b44a --- /dev/null +++ b/include/rbtree.h @@ -0,0 +1,98 @@ +/* + * Red Black Trees + * (C) 1999 Andrea Arcangeli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _RBTREE_H +#define _RBTREE_H + +#include + +struct rb_node +{ + unsigned long rb_parent_color; +#define RB_RED 0 +#define RB_BLACK 1 + struct rb_node *rb_right; + struct rb_node *rb_left; +}; + +struct rb_root +{ + struct rb_node *rb_node; +}; + +#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3)) +#define rb_color(r) ((r)->rb_parent_color & 1) +#define rb_is_red(r) (!rb_color(r)) +#define rb_is_black(r) rb_color(r) +#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0) +#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0) + +static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) +{ + rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p; +} +static inline void rb_set_color(struct rb_node *rb, int color) +{ + rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; +} + +#define RB_ROOT (struct rb_root) { NULL, } +#define rb_entry(ptr, type, member) container_of(ptr, type, member) + +#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) +#define RB_EMPTY_NODE(node) (rb_parent(node) == node) +#define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) + +extern void rb_insert_color(struct rb_node *, struct rb_root *); +extern void rb_erase(struct rb_node *, struct rb_root *); + +/* Find logical next and previous nodes in a tree */ +extern struct rb_node *rb_next(struct rb_node *); +extern struct rb_node *rb_prev(struct rb_node *); +extern struct rb_node *rb_first(struct rb_root *); +extern struct rb_node *rb_last(struct rb_root *); + +/* Fast replacement of a single node without remove/rebalance/add/rebalance */ +extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root); + +static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, + struct rb_node ** rb_link) +{ + node->rb_parent_color = (unsigned long )parent; + node->rb_left = node->rb_right = NULL; + + *rb_link = node; +} + +#define rb_for_each_entry(pos, root, member) \ + for ((pos) = (root)->rb_node ? \ + rb_entry(rb_first(root), typeof(*pos), member) : NULL; \ + (pos) != NULL; \ + (pos) = rb_entry(rb_next(&(pos)->member), typeof(*pos), member)) + +#define rb_for_each_entry_safe(pos, node, next, root, member) \ + for ((node) = rb_first(root); \ + (pos) = (node) ? rb_entry((node), typeof(*pos), member) : NULL, \ + (next) = (node) ? rb_next(node) : NULL, \ + (pos) != NULL; \ + (node) = (next)) + +#endif /* _RBTREE_H */ diff --git a/include/rule.h b/include/rule.h new file mode 100644 index 00000000..e4ad9f58 --- /dev/null +++ b/include/rule.h @@ -0,0 +1,174 @@ +#ifndef _RULE_H +#define _RULE_H + +#include +#include +#include + +/** + * struct handle - handle for tables, chains and rules + * + * @family: protocol family + * @table: table name + * @chain: chain name (chains and rules only) + * @handle: rule handle (rules only) + */ +struct handle { + int family; + const char *table; + const char *chain; + uint32_t handle; +}; + +extern void handle_merge(struct handle *dst, const struct handle *src); +extern void handle_free(struct handle *h); + +/** + * struct table - nftables table + * + * @list: list node + * @handle: table handle + * @chains: chains contained in the table + */ +struct table { + struct list_head list; + struct handle handle; + struct list_head chains; +}; + +extern struct table *table_alloc(void); +extern void table_free(struct table *table); +extern void table_add_hash(struct table *table); +extern struct table *table_lookup(const struct handle *h); + +/** + * struct chain - nftables chain + * + * @list: list node in table list + * @handle: chain handle + * @hooknum: hook number (base chains) + * @priority: hook priority (base chains) + * @rules: rules contained in the chain + */ +struct chain { + struct list_head list; + struct handle handle; + unsigned int hooknum; + unsigned int priority; + struct list_head rules; +}; + +extern struct chain *chain_alloc(const char *name); +extern void chain_free(struct chain *chain); +extern void chain_add_hash(struct chain *chain, struct table *table); +extern struct chain *chain_lookup(const struct table *table, + const struct handle *h); + +/** + * struct rule - nftables rule + * + * @list: list node in chain list + * @handle: rule handle + * @location: location the rule was defined at + * @stmt: list of statements + * @num_stmts: number of statements in stmts list + */ +struct rule { + struct list_head list; + struct handle handle; + struct location location; + struct list_head stmts; + unsigned int num_stmts; +}; + +extern struct rule *rule_alloc(const struct location *loc, + const struct handle *h); +extern void rule_free(struct rule *rule); +extern void rule_print(const struct rule *rule); + +/** + * enum cmd_ops - command operations + * + * @CMD_INVALID: invalid + * @CMD_ADD: add object + * @CMD_DELETE: delete object + * @CMD_LIST: list container + * @CMD_FLUSH: flush container + */ +enum cmd_ops { + CMD_INVALID, + CMD_ADD, + CMD_DELETE, + CMD_LIST, + CMD_FLUSH, +}; + +/** + * enum cmd_obj - command objects + * + * @CMD_OBJ_INVALID: invalid + * @CMD_OBJ_RULE: rule + * @CMD_OBJ_CHAIN: chain + * @CMD_OBJ_TABLE: table + */ +enum cmd_obj { + CMD_OBJ_INVALID, + CMD_OBJ_RULE, + CMD_OBJ_CHAIN, + CMD_OBJ_TABLE, +}; + +/** + * struct cmd - command statement + * + * @list: list node + * @location: location of the statement + * @op: operation + * @obj: object type to perform operation on + * @handle: handle for operations working without full objects + * @union: object + */ +struct cmd { + struct list_head list; + struct location location; + enum cmd_ops op; + enum cmd_obj obj; + struct handle handle; + union { + void *data; + struct rule *rule; + struct chain *chain; + struct table *table; + }; +}; + +extern struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj, + const struct handle *h, void *data); +extern void cmd_free(struct cmd *cmd); + +#include +#include + +/** + * struct eval_ctx - evaluation context + * + * @msgs: message queue + * @stmt: current statement + * @ectx: expression context + * @pctx: payload context + */ +struct eval_ctx { + struct list_head *msgs; + struct stmt *stmt; + struct expr_ctx ectx; + struct payload_ctx pctx; +}; + +extern int evaluate(struct eval_ctx *ctx, struct list_head *commands); + +extern struct error_record *rule_postprocess(struct rule *rule); + +struct netlink_ctx; +extern int do_command(struct netlink_ctx *ctx, struct cmd *cmd); + +#endif /* RULE_H */ diff --git a/include/statement.h b/include/statement.h new file mode 100644 index 00000000..6e5cfbdb --- /dev/null +++ b/include/statement.h @@ -0,0 +1,140 @@ +#ifndef _STATEMENT_H +#define _STATEMENT_H + +#include +#include + +extern struct stmt *expr_stmt_alloc(const struct location *loc, + struct expr *expr); + +extern struct stmt *verdict_stmt_alloc(const struct location *loc, + struct expr *expr); + +struct counter_stmt { + uint64_t packets; + uint64_t bytes; +}; + +extern struct stmt *counter_stmt_alloc(const struct location *loc); + +#include +struct meta_stmt { + enum nft_meta_keys key; + const struct meta_template *tmpl; + struct expr *expr; +}; + +extern struct stmt *meta_stmt_alloc(const struct location *loc, + enum nft_meta_keys key, + struct expr *expr); + +struct log_stmt { + const char *prefix; + unsigned int group; + unsigned int snaplen; + unsigned int qthreshold; +}; + +extern struct stmt *log_stmt_alloc(const struct location *loc); + + +struct limit_stmt { + uint64_t rate; + uint64_t unit; + uint64_t depth; +}; + +extern struct stmt *limit_stmt_alloc(const struct location *loc); + +struct reject_stmt { + enum nft_reject_types type; +}; + +extern struct stmt *reject_stmt_alloc(const struct location *loc); + +struct nat_stmt { + enum nft_nat_types type; + struct expr *addr; + struct expr *proto; +}; + +extern struct stmt *nat_stmt_alloc(const struct location *loc); + +/** + * enum stmt_types - statement types + * + * @STMT_INVALID: uninitialised + * @STMT_EXPRESSION: expression statement (relational) + * @STMT_VERDICT: verdict statement + * @STMT_COUNTER: counters + * @STMT_META: meta statement + * @STMT_LIMIT: limit statement + * @STMT_LOG: log statement + * @STMT_REJECT: REJECT statement + * @STMT_NAT: NAT statement + */ +enum stmt_types { + STMT_INVALID, + STMT_EXPRESSION, + STMT_VERDICT, + STMT_COUNTER, + STMT_META, + STMT_LIMIT, + STMT_LOG, + STMT_REJECT, + STMT_NAT, +}; + +/** + * struct stmt_ops + * + * @type: statement type + * @name: name + * @destroy: destructor + * @print: function to print statement + */ +struct stmt; +struct stmt_ops { + enum stmt_types type; + const char *name; + void (*destroy)(struct stmt *stmt); + void (*print)(const struct stmt *stmt); +}; + +enum stmt_flags { + STMT_F_TERMINAL = 0x1, +}; + +/** + * struct stmt + * + * @list: rule list node + * @ops: statement ops + * @location: location where the statement was defined + * @flags: statement flags + * @union: type specific data + */ +struct stmt { + struct list_head list; + const struct stmt_ops *ops; + struct location location; + enum stmt_flags flags; + + union { + struct expr *expr; + struct counter_stmt counter; + struct meta_stmt meta; + struct log_stmt log; + struct limit_stmt limit; + struct reject_stmt reject; + struct nat_stmt nat; + }; +}; + +extern struct stmt *stmt_alloc(const struct location *loc, + const struct stmt_ops *ops); +extern void stmt_free(struct stmt *stmt); +extern void stmt_list_free(struct list_head *list); +extern void stmt_print(const struct stmt *stmt); + +#endif /* _STATEMENT_H */ diff --git a/include/utils.h b/include/utils.h new file mode 100644 index 00000000..beb63868 --- /dev/null +++ b/include/utils.h @@ -0,0 +1,69 @@ +#ifndef _UTILS_H +#define _UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BITS_PER_BYTE 8 + +#ifdef DEBUG +#define pr_debug(fmt, arg...) gmp_printf(fmt, ##arg) +#else +#define pr_debug(fmt, arg...) ({ if (false) gmp_printf(fmt, ##arg); 0; }) +#endif + +#define __fmtstring(x, y) __attribute__((format(printf, x, y))) +#if 0 +#define __gmp_fmtstring(x, y) __fmtstring(x, y) +#else +#define __gmp_fmtstring(x, y) +#endif + +#define __init __attribute__((constructor)) +#define __exit __attribute__((destructor)) +#define __must_check __attribute__((warn_unused_result)) +#define __noreturn __attribute__((__noreturn__)) + +#define BUG() assert(0) + +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) +#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) + +#define __must_be_array(a) \ + BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) + +#define container_of(ptr, type, member) ({ \ + typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define field_sizeof(t, f) (sizeof(((t *)NULL)->f)) +#define array_size(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) +#define div_round_up(n, d) (((n) + (d) - 1) / (d)) + +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +#define max(x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +extern void memory_allocation_error(void) __noreturn; + +extern void xfree(const void *ptr); +extern void *xmalloc(size_t size); +extern void *xrealloc(void *ptr, size_t size); +extern void *xzalloc(size_t size); +extern char *xstrdup(const char *s); + +#endif /* _UTILS_H */ -- cgit v1.2.3