diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/ct.h | 1 | ||||
-rw-r--r-- | include/datatype.h | 3 | ||||
-rw-r--r-- | include/expression.h | 18 | ||||
-rw-r--r-- | include/exthdr.h | 6 | ||||
-rw-r--r-- | include/linux/netfilter.h | 22 | ||||
-rw-r--r-- | include/linux/netfilter/nf_tables.h | 130 | ||||
-rw-r--r-- | include/nftables.h | 5 | ||||
-rw-r--r-- | include/payload.h | 288 | ||||
-rw-r--r-- | include/proto.h | 304 | ||||
-rw-r--r-- | include/rule.h | 2 | ||||
-rw-r--r-- | include/statement.h | 11 |
11 files changed, 476 insertions, 314 deletions
diff --git a/include/ct.h b/include/ct.h index 67718c84..64366ab7 100644 --- a/include/ct.h +++ b/include/ct.h @@ -25,5 +25,6 @@ struct ct_template { extern struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key); +extern void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr); #endif /* NFTABLES_CT_H */ diff --git a/include/datatype.h b/include/datatype.h index 84dcdc8c..9e609cf2 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -6,6 +6,7 @@ * * @TYPE_INVALID: uninitialized * @TYPE_VERDICT: nftables verdict + * @TYPE_NFPROTO: netfilter protocol (integer subtype) * @TYPE_BITMASK: bitmask * @TYPE_INTEGER: integer * @TYPE_STRING: string @@ -37,6 +38,7 @@ enum datatypes { TYPE_INVALID, TYPE_VERDICT, + TYPE_NFPROTO, TYPE_BITMASK, TYPE_INTEGER, TYPE_STRING, @@ -175,6 +177,7 @@ 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 nfproto_type; extern const struct datatype bitmask_type; extern const struct datatype integer_type; extern const struct datatype string_type; diff --git a/include/expression.h b/include/expression.h index a167cf59..0633102e 100644 --- a/include/expression.h +++ b/include/expression.h @@ -118,7 +118,9 @@ static inline void expr_set_context(struct expr_ctx *ctx, * @destroy: destructor, must release inner expressions * @set_type: function to promote type and byteorder of inner types * @print: function to print the expression + * @pctx_update:update protocol context */ +struct proto_ctx; struct expr_ops { enum expr_types type; const char *name; @@ -128,6 +130,8 @@ struct expr_ops { const struct datatype *dtype, enum byteorder byteorder); void (*print)(const struct expr *expr); + void (*pctx_update)(struct proto_ctx *ctx, + const struct expr *expr); }; /** @@ -135,12 +139,14 @@ struct expr_ops { * * @EXPR_F_CONSTANT: constant expression * @EXPR_F_SINGLETON: singleton (implies primary and constant) + * @EXPR_F_PROTOCOL: expressions describes upper layer protocol * @EXPR_F_INTERVAL_END: set member ends an open interval */ enum expr_flags { EXPR_F_CONSTANT = 0x1, EXPR_F_SINGLETON = 0x2, - EXPR_F_INTERVAL_END = 0x4, + EXPR_F_PROTOCOL = 0x4, + EXPR_F_INTERVAL_END = 0x8, }; #include <payload.h> @@ -223,20 +229,20 @@ struct expr { struct { /* EXPR_PAYLOAD */ - const struct payload_desc *desc; - const struct payload_template *tmpl; - enum payload_bases base; + const struct proto_desc *desc; + const struct proto_hdr_template *tmpl; + enum proto_bases base; unsigned int offset; - unsigned int flags; } payload; struct { /* EXPR_EXTHDR */ const struct exthdr_desc *desc; - const struct payload_template *tmpl; + const struct proto_hdr_template *tmpl; } exthdr; struct { /* EXPR_META */ enum nft_meta_keys key; + enum proto_bases base; } meta; struct { /* EXPR_CT */ diff --git a/include/exthdr.h b/include/exthdr.h index 62e69bd2..87c42857 100644 --- a/include/exthdr.h +++ b/include/exthdr.h @@ -1,17 +1,19 @@ #ifndef NFTABLES_EXTHDR_H #define NFTABLES_EXTHDR_H +#include <proto.h> + /** * struct exthdr_desc - extension header description * * @name: extension header name * @type: extension header protocol value - * @templates: header templates + * @templates: header field templates */ struct exthdr_desc { const char *name; uint8_t type; - struct payload_template templates[10]; + struct proto_hdr_template templates[10]; }; extern struct expr *exthdr_expr_alloc(const struct location *loc, diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 2eb00b6c..be0bc182 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -3,6 +3,8 @@ #include <linux/types.h> +#include <linux/sysctl.h> + /* Responses from hook functions. */ #define NF_DROP 0 @@ -14,14 +16,20 @@ #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 + * number or errno values. Not nice, but better than additional function + * arguments. */ +#define NF_VERDICT_MASK 0x000000ff + +/* extra verdict flags have mask 0x0000ff00 */ +#define NF_VERDICT_FLAG_QUEUE_BYPASS 0x00008000 +/* queue number (NF_QUEUE) or errno (NF_DROP) */ #define NF_VERDICT_QMASK 0xffff0000 #define NF_VERDICT_QBITS 16 -#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) +#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE) + +#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP) /* only for userspace compatibility */ /* Generic cache responses from hook functions. @@ -29,6 +37,9 @@ #define NFC_UNKNOWN 0x4000 #define NFC_ALTERED 0x8000 +/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */ +#define NF_VERDICT_BITS 16 + enum nf_inet_hooks { NF_INET_PRE_ROUTING, NF_INET_LOCAL_IN, @@ -40,6 +51,7 @@ enum nf_inet_hooks { enum { NFPROTO_UNSPEC = 0, + NFPROTO_INET = 1, NFPROTO_IPV4 = 2, NFPROTO_ARP = 3, NFPROTO_BRIDGE = 7, @@ -56,4 +68,4 @@ union nf_inet_addr { struct in6_addr in6; }; -#endif /*__LINUX_NETFILTER_H*/ +#endif /* __LINUX_NETFILTER_H */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index a236cc31..448593c0 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -32,6 +32,25 @@ enum nft_verdicts { NFT_RETURN = -5, }; +/** + * enum nf_tables_msg_types - nf_tables netlink message types + * + * @NFT_MSG_NEWTABLE: create a new table (enum nft_table_attributes) + * @NFT_MSG_GETTABLE: get a table (enum nft_table_attributes) + * @NFT_MSG_DELTABLE: delete a table (enum nft_table_attributes) + * @NFT_MSG_NEWCHAIN: create a new chain (enum nft_chain_attributes) + * @NFT_MSG_GETCHAIN: get a chain (enum nft_chain_attributes) + * @NFT_MSG_DELCHAIN: delete a chain (enum nft_chain_attributes) + * @NFT_MSG_NEWRULE: create a new rule (enum nft_rule_attributes) + * @NFT_MSG_GETRULE: get a rule (enum nft_rule_attributes) + * @NFT_MSG_DELRULE: delete a rule (enum nft_rule_attributes) + * @NFT_MSG_NEWSET: create a new set (enum nft_set_attributes) + * @NFT_MSG_GETSET: get a set (enum nft_set_attributes) + * @NFT_MSG_DELSET: delete a set (enum nft_set_attributes) + * @NFT_MSG_NEWSETELEM: create a new set element (enum nft_set_elem_attributes) + * @NFT_MSG_GETSETELEM: get a set element (enum nft_set_elem_attributes) + * @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes) + */ enum nf_tables_msg_types { NFT_MSG_NEWTABLE, NFT_MSG_GETTABLE, @@ -48,8 +67,6 @@ enum nf_tables_msg_types { NFT_MSG_NEWSETELEM, NFT_MSG_GETSETELEM, NFT_MSG_DELSETELEM, - NFT_MSG_COMMIT, - NFT_MSG_ABORT, NFT_MSG_MAX, }; @@ -92,11 +109,14 @@ enum nft_table_flags { * enum nft_table_attributes - nf_tables table netlink attributes * * @NFTA_TABLE_NAME: name of the table (NLA_STRING) + * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32) + * @NFTA_TABLE_USE: number of chains in this table (NLA_U32) */ enum nft_table_attributes { NFTA_TABLE_UNSPEC, NFTA_TABLE_NAME, NFTA_TABLE_FLAGS, + NFTA_TABLE_USE, __NFTA_TABLE_MAX }; #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1) @@ -105,8 +125,13 @@ enum nft_table_attributes { * enum nft_chain_attributes - nf_tables chain netlink attributes * * @NFTA_CHAIN_TABLE: name of the table containing the chain (NLA_STRING) + * @NFTA_CHAIN_HANDLE: numeric handle of the chain (NLA_U64) * @NFTA_CHAIN_NAME: name of the chain (NLA_STRING) * @NFTA_CHAIN_HOOK: hook specification for basechains (NLA_NESTED: nft_hook_attributes) + * @NFTA_CHAIN_POLICY: numeric policy of the chain (NLA_U32) + * @NFTA_CHAIN_USE: number of references to this chain (NLA_U32) + * @NFTA_CHAIN_TYPE: type name of the string (NLA_NUL_STRING) + * @NFTA_CHAIN_COUNTERS: counter specification of the chain (NLA_NESTED: nft_counter_attributes) */ enum nft_chain_attributes { NFTA_CHAIN_UNSPEC, @@ -122,18 +147,15 @@ enum nft_chain_attributes { }; #define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1) -enum { - NFT_RULE_F_COMMIT = (1 << 0), - NFT_RULE_F_MASK = NFT_RULE_F_COMMIT, -}; - /** * enum nft_rule_attributes - nf_tables rule netlink attributes * * @NFTA_RULE_TABLE: name of the table containing the rule (NLA_STRING) * @NFTA_RULE_CHAIN: name of the chain containing the rule (NLA_STRING) - * @NFTA_RULE_HANDLE: numeric handle of the rule (NLA_U16) + * @NFTA_RULE_HANDLE: numeric handle of the rule (NLA_U64) * @NFTA_RULE_EXPRESSIONS: list of expressions (NLA_NESTED: nft_expr_attributes) + * @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes) + * @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64) */ enum nft_rule_attributes { NFTA_RULE_UNSPEC, @@ -141,17 +163,28 @@ enum nft_rule_attributes { NFTA_RULE_CHAIN, NFTA_RULE_HANDLE, NFTA_RULE_EXPRESSIONS, - NFTA_RULE_FLAGS, NFTA_RULE_COMPAT, + NFTA_RULE_POSITION, __NFTA_RULE_MAX }; #define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1) +/** + * enum nft_rule_compat_flags - nf_tables rule compat flags + * + * @NFT_RULE_COMPAT_F_INV: invert the check result + */ enum nft_rule_compat_flags { NFT_RULE_COMPAT_F_INV = (1 << 1), NFT_RULE_COMPAT_F_MASK = NFT_RULE_COMPAT_F_INV, }; +/** + * enum nft_rule_compat_attributes - nf_tables rule compat attributes + * + * @NFTA_RULE_COMPAT_PROTO: numerice value of handled protocol (NLA_U32) + * @NFTA_RULE_COMPAT_FLAGS: bitmask of enum nft_rule_compat_flags (NLA_U32) + */ enum nft_rule_compat_attributes { NFTA_RULE_COMPAT_UNSPEC, NFTA_RULE_COMPAT_PROTO, @@ -349,11 +382,26 @@ enum nft_bitwise_attributes { }; #define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1) +/** + * enum nft_byteorder_ops - nf_tables byteorder operators + * + * @NFT_BYTEORDER_NTOH: network to host operator + * @NFT_BYTEORDER_HTON: host to network opertaor + */ enum nft_byteorder_ops { NFT_BYTEORDER_NTOH, NFT_BYTEORDER_HTON, }; +/** + * enum nft_byteorder_attributes - nf_tables byteorder expression netlink attributes + * + * @NFTA_BYTEORDER_SREG: source register (NLA_U32: nft_registers) + * @NFTA_BYTEORDER_DREG: destination register (NLA_U32: nft_registers) + * @NFTA_BYTEORDER_OP: operator (NLA_U32: enum nft_byteorder_ops) + * @NFTA_BYTEORDER_LEN: length of the data (NLA_U32) + * @NFTA_BYTEORDER_SIZE: data size in bytes (NLA_U32: 2 or 4) + */ enum nft_byteorder_attributes { NFTA_BYTEORDER_UNSPEC, NFTA_BYTEORDER_SREG, @@ -365,6 +413,16 @@ enum nft_byteorder_attributes { }; #define NFTA_BYTEORDER_MAX (__NFTA_BYTEORDER_MAX - 1) +/** + * enum nft_cmp_ops - nf_tables relational operator + * + * @NFT_CMP_EQ: equal + * @NFT_CMP_NEQ: not equal + * @NFT_CMP_LT: less than + * @NFT_CMP_LTE: less than or equal to + * @NFT_CMP_GT: greater than + * @NFT_CMP_GTE: greater than or equal to + */ enum nft_cmp_ops { NFT_CMP_EQ, NFT_CMP_NEQ, @@ -390,6 +448,13 @@ enum nft_cmp_attributes { }; #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) +/** + * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes + * + * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING) + * @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers) + * @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers) + */ enum nft_lookup_attributes { NFTA_LOOKUP_UNSPEC, NFTA_LOOKUP_SET, @@ -430,6 +495,14 @@ enum nft_payload_attributes { }; #define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1) +/** + * enum nft_exthdr_attributes - nf_tables IPv6 extension header expression netlink attributes + * + * @NFTA_EXTHDR_DREG: destination register (NLA_U32: nft_registers) + * @NFTA_EXTHDR_TYPE: extension header type (NLA_U8) + * @NFTA_EXTHDR_OFFSET: extension header offset (NLA_U32) + * @NFTA_EXTHDR_LEN: extension header length (NLA_U32) + */ enum nft_exthdr_attributes { NFTA_EXTHDR_UNSPEC, NFTA_EXTHDR_DREG, @@ -458,6 +531,8 @@ enum nft_exthdr_attributes { * @NFT_META_NFTRACE: packet nftrace bit * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid) * @NFT_META_SECMARK: packet secmark (skb->secmark) + * @NFT_META_NFPROTO: netfilter protocol + * @NFT_META_L4PROTO: layer 4 protocol number */ enum nft_meta_keys { NFT_META_LEN, @@ -475,6 +550,8 @@ enum nft_meta_keys { NFT_META_NFTRACE, NFT_META_RTCLASSID, NFT_META_SECMARK, + NFT_META_NFPROTO, + NFT_META_L4PROTO, }; /** @@ -482,11 +559,13 @@ enum nft_meta_keys { * * @NFTA_META_DREG: destination register (NLA_U32) * @NFTA_META_KEY: meta data item to load (NLA_U32: nft_meta_keys) + * @NFTA_META_SREG: source register (NLA_U32) */ enum nft_meta_attributes { NFTA_META_UNSPEC, NFTA_META_DREG, NFTA_META_KEY, + NFTA_META_SREG, __NFTA_META_MAX }; #define NFTA_META_MAX (__NFTA_META_MAX - 1) @@ -544,12 +623,12 @@ enum nft_ct_attributes { * enum nft_limit_attributes - nf_tables limit expression netlink attributes * * @NFTA_LIMIT_RATE: refill rate (NLA_U64) - * @NFTA_LIMIT_DEPTH: bucket depth (NLA_U64) + * @NFTA_LIMIT_UNIT: refill unit (NLA_U64) */ enum nft_limit_attributes { NFTA_LIMIT_UNSPEC, NFTA_LIMIT_RATE, - NFTA_LIMIT_DEPTH, + NFTA_LIMIT_UNIT, __NFTA_LIMIT_MAX }; #define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1) @@ -587,6 +666,26 @@ enum nft_log_attributes { #define NFTA_LOG_MAX (__NFTA_LOG_MAX - 1) /** + * enum nft_queue_attributes - nf_tables queue expression netlink attributes + * + * @NFTA_QUEUE_NUM: netlink queue to send messages to (NLA_U16) + * @NFTA_QUEUE_TOTAL: number of queues to load balance packets on (NLA_U16) + * @NFTA_QUEUE_FLAGS: various flags (NLA_U16) + */ +enum nft_queue_attributes { + NFTA_QUEUE_UNSPEC, + NFTA_QUEUE_NUM, + NFTA_QUEUE_TOTAL, + NFTA_QUEUE_FLAGS, + __NFTA_QUEUE_MAX +}; +#define NFTA_QUEUE_MAX (__NFTA_QUEUE_MAX - 1) + +#define NFT_QUEUE_FLAG_BYPASS 0x01 /* for compatibility with v2 */ +#define NFT_QUEUE_FLAG_CPU_FANOUT 0x02 /* use current CPU (no hashing) */ +#define NFT_QUEUE_FLAG_MASK 0x03 + +/** * enum nft_reject_types - nf_tables reject expression reject types * * @NFT_REJECT_ICMP_UNREACH: reject using ICMP unreachable @@ -626,10 +725,11 @@ enum nft_nat_types { * enum nft_nat_attributes - nf_tables nat expression netlink attributes * * @NFTA_NAT_TYPE: NAT type (NLA_U32: nft_nat_types) - * @NFTA_NAT_ADDR_MIN: source register of address range start (NLA_U32: nft_registers) - * @NFTA_NAT_ADDR_MAX: source register of address range end (NLA_U32: nft_registers) - * @NFTA_NAT_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) - * @NFTA_NAT_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) + * @NFTA_NAT_FAMILY: NAT family (NLA_U32) + * @NFTA_NAT_REG_ADDR_MIN: source register of address range start (NLA_U32: nft_registers) + * @NFTA_NAT_REG_ADDR_MAX: source register of address range end (NLA_U32: nft_registers) + * @NFTA_NAT_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) + * @NFTA_NAT_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) */ enum nft_nat_attributes { NFTA_NAT_UNSPEC, diff --git a/include/nftables.h b/include/nftables.h index b36e10ae..5a000870 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -17,8 +17,9 @@ enum debug_level { DEBUG_PARSER = 0x2, DEBUG_EVALUATION = 0x4, DEBUG_NETLINK = 0x8, - DEBUG_SEGTREE = 0x10, - DEBUG_MNL = 0x20, + DEBUG_MNL = 0x10, + DEBUG_PROTO_CTX = 0x20, + DEBUG_SEGTREE = 0x40, }; #define INCLUDE_PATHS_MAX 16 diff --git a/include/payload.h b/include/payload.h index c9cc84f3..d47e5645 100644 --- a/include/payload.h +++ b/include/payload.h @@ -2,138 +2,14 @@ #define NFTABLES_PAYLOAD_H #include <nftables.h> - -/** - * 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]; -}; +#include <proto.h> extern struct expr *payload_expr_alloc(const struct location *loc, - const struct payload_desc *desc, + const struct proto_desc *desc, unsigned int type); -extern void payload_init_raw(struct expr *expr, enum payload_bases base, +extern void payload_init_raw(struct expr *expr, enum proto_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); @@ -143,162 +19,8 @@ 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); + const struct proto_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 icmp6_hdr_fields { - ICMP6HDR_INVALID, - ICMP6HDR_TYPE, - ICMP6HDR_CODE, - ICMP6HDR_CHECKSUM, - ICMP6HDR_PPTR, - ICMP6HDR_MTU, - ICMP6HDR_ID, - ICMP6HDR_SEQ, - ICMP6HDR_MAXDELAY, -}; - -enum ip6_hdr_fields { - IP6HDR_INVALID, - IP6HDR_VERSION, - IP6HDR_PRIORITY, - IP6HDR_FLOWLABEL, - IP6HDR_LENGTH, - IP6HDR_NEXTHDR, - IP6HDR_HOPLIMIT, - IP6HDR_SADDR, - IP6HDR_DADDR, - IP6HDR_PROTOCOL, -}; - -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, - DCCPHDR_TYPE, -}; - -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_icmp6; - -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; + const struct proto_ctx *ctx); #endif /* NFTABLES_PAYLOAD_H */ diff --git a/include/proto.h b/include/proto.h new file mode 100644 index 00000000..bd3701e3 --- /dev/null +++ b/include/proto.h @@ -0,0 +1,304 @@ +#ifndef NFTABLES_PROTO_H +#define NFTABLES_PROTO_H + +#include <nftables.h> +#include <linux/netfilter/nf_tables.h> + +/** + * enum proto_bases - protocol bases + * + * @PROTO_BASE_INVALID: uninitialised, does not happen + * @PROTO_BASE_LL_HDR: link layer header + * @PROTO_BASE_NETWORK_HDR: network layer header + * @PROTO_BASE_TRANSPORT_HDR: transport layer header + */ +enum proto_bases { + PROTO_BASE_INVALID, + PROTO_BASE_LL_HDR, + PROTO_BASE_NETWORK_HDR, + PROTO_BASE_TRANSPORT_HDR, + __PROTO_BASE_MAX +}; +#define PROTO_BASE_MAX (__PROTO_BASE_MAX - 1) + +extern const char *proto_base_names[]; +extern const char *proto_base_tokens[]; + +/** + * struct proto_hdr_template - protocol header field description + * + * @token: parser token describing the header field + * @dtype: data type of the header field + * @offset: offset of the header field from base + * @len: length of header field + * @meta_key: special case: meta expression key + */ +struct proto_hdr_template { + const char *token; + const struct datatype *dtype; + uint16_t offset; + uint16_t len; + enum nft_meta_keys meta_key; +}; + +#define PROTO_HDR_TEMPLATE(__token, __dtype, __offset, __len) \ + { \ + .token = (__token), \ + .dtype = (__dtype), \ + .offset = (__offset), \ + .len = (__len), \ + } + +#define PROTO_META_TEMPLATE(__token, __dtype, __key, __len) \ + { \ + .token = (__token), \ + .dtype = (__dtype), \ + .meta_key = (__key), \ + .len = (__len), \ + } + +#define PROTO_UPPER_MAX 16 +#define PROTO_HDRS_MAX 20 + +/** + * struct proto_desc - protocol header description + * + * @name: protocol name + * @base: header base + * @protocol_key: key of template containing upper layer protocol description + * @protocols: link to upper layer protocol descriptions indexed by protocol value + * @templates: header templates + */ +struct proto_desc { + const char *name; + enum proto_bases base; + unsigned int protocol_key; + struct { + unsigned int num; + const struct proto_desc *desc; + } protocols[PROTO_UPPER_MAX]; + struct proto_hdr_template templates[PROTO_HDRS_MAX]; +}; + +#define PROTO_LINK(__num, __desc) { .num = (__num), .desc = (__desc), } + +/** + * struct hook_proto_desc - description of protocol constraints imposed by hook family + * + * @base: protocol base of packets + * @desc: protocol description of packets + */ +struct hook_proto_desc { + enum proto_bases base; + const struct proto_desc *desc; +}; + +#define HOOK_PROTO_DESC(__base, __desc) { .base = (__base), .desc = (__desc), } + +extern const struct hook_proto_desc hook_proto_desc[]; + +/** + * struct dev_proto_desc - description of device LL protocol + * + * @desc: protocol description + * @type: arphrd value + */ +struct dev_proto_desc { + const struct proto_desc *desc; + uint16_t type; +}; + +#define DEV_PROTO_DESC(__type, __desc) { .type = (__type), .desc = (__desc), } + +extern int proto_dev_type(const struct proto_desc *desc, uint16_t *res); +extern const struct proto_desc *proto_dev_desc(uint16_t type); + +/** + * struct proto_ctx - protocol context + * + * @family: hook family + * @location: location of the relational expression defining the context + * @desc: protocol 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 proto_ctx { + unsigned int family; + struct { + struct location location; + const struct proto_desc *desc; + } protocol[PROTO_BASE_MAX + 1]; +}; + +extern void proto_ctx_init(struct proto_ctx *ctx, unsigned int family); +extern void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base, + const struct location *loc, + const struct proto_desc *desc); +extern const struct proto_desc *proto_find_upper(const struct proto_desc *base, + unsigned int num); +extern int proto_find_num(const struct proto_desc *base, + const struct proto_desc *desc); + +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 icmp6_hdr_fields { + ICMP6HDR_INVALID, + ICMP6HDR_TYPE, + ICMP6HDR_CODE, + ICMP6HDR_CHECKSUM, + ICMP6HDR_PPTR, + ICMP6HDR_MTU, + ICMP6HDR_ID, + ICMP6HDR_SEQ, + ICMP6HDR_MAXDELAY, +}; + +enum ip6_hdr_fields { + IP6HDR_INVALID, + IP6HDR_VERSION, + IP6HDR_PRIORITY, + IP6HDR_FLOWLABEL, + IP6HDR_LENGTH, + IP6HDR_NEXTHDR, + IP6HDR_HOPLIMIT, + IP6HDR_SADDR, + IP6HDR_DADDR, + IP6HDR_PROTOCOL, +}; + +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, + DCCPHDR_TYPE, +}; + +enum sctp_hdr_fields { + SCTPHDR_INVALID, + SCTPHDR_SPORT, + SCTPHDR_DPORT, + SCTPHDR_VTAG, + SCTPHDR_CHECKSUM, +}; + +extern const struct proto_desc proto_icmp; +extern const struct proto_desc proto_ah; +extern const struct proto_desc proto_esp; +extern const struct proto_desc proto_comp; +extern const struct proto_desc proto_udp; +extern const struct proto_desc proto_udplite; +extern const struct proto_desc proto_tcp; +extern const struct proto_desc proto_dccp; +extern const struct proto_desc proto_sctp; +extern const struct proto_desc proto_icmp6; + +extern const struct proto_desc proto_ip; +extern const struct proto_desc proto_ip6; + +extern const struct proto_desc proto_inet; +extern const struct proto_desc proto_inet_service; + +extern const struct proto_desc proto_arp; + +extern const struct proto_desc proto_vlan; +extern const struct proto_desc proto_eth; + +extern const struct proto_desc proto_unknown; +extern const struct proto_hdr_template proto_unknown_template; + +#endif /* NFTABLES_PROTO_H */ diff --git a/include/rule.h b/include/rule.h index 6ad8af3b..2a7b7980 100644 --- a/include/rule.h +++ b/include/rule.h @@ -292,7 +292,7 @@ struct eval_ctx { struct set *set; struct stmt *stmt; struct expr_ctx ectx; - struct payload_ctx pctx; + struct proto_ctx pctx; }; extern int evaluate(struct eval_ctx *ctx, struct list_head *commands); diff --git a/include/statement.h b/include/statement.h index 6ecbb18d..14a66df6 100644 --- a/include/statement.h +++ b/include/statement.h @@ -59,6 +59,14 @@ struct nat_stmt { extern struct stmt *nat_stmt_alloc(const struct location *loc); +struct queue_stmt { + uint16_t queuenum; + uint16_t queues_total; + uint16_t flags; +}; + +extern struct stmt *queue_stmt_alloc(const struct location *loc); + /** * enum stmt_types - statement types * @@ -71,6 +79,7 @@ extern struct stmt *nat_stmt_alloc(const struct location *loc); * @STMT_LOG: log statement * @STMT_REJECT: REJECT statement * @STMT_NAT: NAT statement + * @STMT_QUEUE: QUEUE statement */ enum stmt_types { STMT_INVALID, @@ -82,6 +91,7 @@ enum stmt_types { STMT_LOG, STMT_REJECT, STMT_NAT, + STMT_QUEUE, }; /** @@ -127,6 +137,7 @@ struct stmt { struct limit_stmt limit; struct reject_stmt reject; struct nat_stmt nat; + struct queue_stmt queue; }; }; |