diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:08:37 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:08:37 +0000 |
commit | 971e619d8602fa52b1bfcb3ea65b7ab96be85318 (patch) | |
tree | 26feb2498c72b796e07b86349d17f544046de279 /include/expression.h | |
parent | Initial commit. (diff) | |
download | nftables-971e619d8602fa52b1bfcb3ea65b7ab96be85318.tar.xz nftables-971e619d8602fa52b1bfcb3ea65b7ab96be85318.zip |
Adding upstream version 1.0.9.upstream/1.0.9upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/expression.h')
-rw-r--r-- | include/expression.h | 530 |
1 files changed, 530 insertions, 0 deletions
diff --git a/include/expression.h b/include/expression.h new file mode 100644 index 0000000..aede223 --- /dev/null +++ b/include/expression.h @@ -0,0 +1,530 @@ +#ifndef NFTABLES_EXPRESSION_H +#define NFTABLES_EXPRESSION_H + +#include <gmputil.h> +#include <linux/netfilter/nf_tables.h> + +#include <nftables.h> +#include <datatype.h> +#include <utils.h> +#include <list.h> +#include <json.h> +#include <libnftnl/udata.h> + +/** + * enum expr_types + * + * @EXPR_INVALID: uninitialized type, should not happen + * @EXPR_VERDICT: nftables verdict expression + * @EXPR_SYMBOL: unparsed symbol + * @EXPR_VARIABLE: variable + * @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_SOCKET: socket expression + * @EXPR_OSF: osf expression + * @EXPR_CT: conntrack expression + * @EXPR_CONCAT: concatenation + * @EXPR_LIST: list of expressions + * @EXPR_SET: literal set + * @EXPR_SET_REF: set reference + * @EXPR_SET_ELEM: set element + * @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 + * @EXPR_NUMGEN: number generation expression + * @EXPR_HASH: hash expression + * @EXPR_RT: routing expression + * @EXPR_FIB forward information base expression + * @EXPR_XFRM XFRM (ipsec) expression + * @EXPR_SET_ELEM_CATCHALL catchall element expression + * @EXPR_FLAGCMP flagcmp expression + */ +enum expr_types { + EXPR_INVALID, + EXPR_VERDICT, + EXPR_SYMBOL, + EXPR_VARIABLE, + EXPR_VALUE, + EXPR_PREFIX, + EXPR_RANGE, + EXPR_PAYLOAD, + EXPR_EXTHDR, + EXPR_META, + EXPR_SOCKET, + EXPR_OSF, + EXPR_CT, + EXPR_CONCAT, + EXPR_LIST, + EXPR_SET, + EXPR_SET_REF, + EXPR_SET_ELEM, + EXPR_MAPPING, + EXPR_MAP, + EXPR_UNARY, + EXPR_BINOP, + EXPR_RELATIONAL, + EXPR_NUMGEN, + EXPR_HASH, + EXPR_RT, + EXPR_FIB, + EXPR_XFRM, + EXPR_SET_ELEM_CATCHALL, + EXPR_FLAGCMP, + + EXPR_MAX = EXPR_FLAGCMP +}; + +enum ops { + OP_INVALID, + OP_IMPLICIT, + /* 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, + OP_NEG, + __OP_MAX +}; +#define OP_MAX (__OP_MAX - 1) + +extern const char *expr_op_symbols[]; + +enum symbol_types { + SYMBOL_VALUE, + SYMBOL_SET, +}; + +/** + * struct expr_ctx - type context for symbol parsing during evaluation + * + * @dtype: expected datatype + * @byteorder: expected byteorder + * @len: expected len + * @maxval: expected maximum value + */ +struct expr_ctx { + /* expr_ctx does not own the reference to dtype. The caller must ensure + * the valid lifetime. + */ + const struct datatype *dtype; + + enum byteorder byteorder; + unsigned int len; + unsigned int maxval; + const struct expr *key; +}; + +static inline void __expr_set_context(struct expr_ctx *ctx, + const struct datatype *dtype, + enum byteorder byteorder, + unsigned int len, unsigned int maxval) +{ + ctx->dtype = dtype; + ctx->byteorder = byteorder; + ctx->len = len; + ctx->maxval = maxval; + ctx->key = NULL; +} + +static inline void expr_set_context(struct expr_ctx *ctx, + const struct datatype *dtype, + unsigned int len) +{ + __expr_set_context(ctx, dtype, + dtype ? dtype->byteorder : BYTEORDER_INVALID, + len, 0); +} + +/** + * struct expr_ops + * + * @type: expression type + * @name: expression name for diagnostics + * @clone: function to clone type specific data + * @destroy: destructor, must release inner expressions + * @set_type: function to promote type and byteorder of inner types + * @print: function to print the expression + * @cmp: function to compare two expressions of the same types + * @pctx_update:update protocol context + */ +struct proto_ctx; +struct expr_ops { + enum expr_types type; + const char *name; + void (*clone)(struct expr *new, const struct expr *expr); + 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, + struct output_ctx *octx); + json_t *(*json)(const struct expr *expr, + struct output_ctx *octx); + bool (*cmp)(const struct expr *e1, + const struct expr *e2); + void (*pctx_update)(struct proto_ctx *ctx, + const struct location *loc, + const struct expr *left, + const struct expr *right); + int (*build_udata)(struct nftnl_udata_buf *udbuf, + const struct expr *expr); + struct expr * (*parse_udata)(const struct nftnl_udata *ud); +}; + +const struct expr_ops *expr_ops(const struct expr *e); +const struct expr_ops *expr_ops_by_type_u32(uint32_t value); + +/** + * enum expr_flags + * + * @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 + * @EXPR_F_BOOLEAN: expression is boolean (set by relational expr on LHS) + * @EXPR_F_INTERVAL: expression describes a interval + * @EXPR_F_KERNEL: expression resides in the kernel + */ +enum expr_flags { + EXPR_F_CONSTANT = 0x1, + EXPR_F_SINGLETON = 0x2, + EXPR_F_PROTOCOL = 0x4, + EXPR_F_INTERVAL_END = 0x8, + EXPR_F_BOOLEAN = 0x10, + EXPR_F_INTERVAL = 0x20, + EXPR_F_KERNEL = 0x40, + EXPR_F_REMOVE = 0x80, +}; + +#include <payload.h> +#include <exthdr.h> +#include <fib.h> +#include <numgen.h> +#include <meta.h> +#include <rt.h> +#include <hash.h> +#include <ct.h> +#include <socket.h> +#include <osf.h> +#include <xfrm.h> + +/** + * 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 + * @etype: expression type + * @op: operation for unary, binary and relational expressions + * @len: length of expression + * @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:8; + enum expr_types etype:8; + enum ops op:8; + unsigned int len; + struct cmd *cmd; + + union { + struct { + /* EXPR_SYMBOL */ + const struct scope *scope; + const char *identifier; + enum symbol_types symtype; + }; + struct { + /* EXPR_VARIABLE */ + struct symbol *sym; + }; + struct { + /* EXPR_VERDICT */ + int verdict; + struct expr *chain; + uint32_t chain_id; + }; + struct { + /* EXPR_VALUE */ + mpz_t value; + }; + struct { + /* EXPR_PREFIX */ + struct expr *prefix; + unsigned int prefix_len; + }; + struct { + /* EXPR_CONCAT, EXPR_LIST, EXPR_SET */ + struct list_head expressions; + unsigned int size; + uint32_t set_flags; + uint8_t field_len[NFT_REG32_COUNT]; + uint8_t field_count; + }; + struct { + /* EXPR_SET_REF */ + struct set *set; + }; + struct { + /* EXPR_SET_ELEM */ + struct expr *key; + uint64_t timeout; + uint64_t expiration; + const char *comment; + struct list_head stmt_list; + uint32_t elem_flags; + }; + 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 *map; + struct expr *mappings; + }; + + struct { + /* EXPR_PAYLOAD */ + const struct proto_desc *desc; + const struct proto_hdr_template *tmpl; + const struct proto_desc *inner_desc; + enum proto_bases base; + unsigned int offset; + bool is_raw; + bool evaluated; + } payload; + struct { + /* EXPR_EXTHDR */ + const struct exthdr_desc *desc; + const struct proto_hdr_template *tmpl; + uint16_t offset; + uint8_t raw_type; + enum nft_exthdr_op op; + unsigned int flags; + } exthdr; + struct { + /* EXPR_META */ + enum nft_meta_keys key; + enum proto_bases base; + const struct proto_desc *inner_desc; + } meta; + struct { + /* SOCKET */ + enum nft_socket_keys key; + uint32_t level; + } socket; + struct { + /* EXPR_RT */ + enum nft_rt_keys key; + } rt; + struct { + /* EXPR_CT */ + enum nft_ct_keys key; + enum proto_bases base; + int8_t direction; + uint8_t nfproto; + } ct; + struct { + /* EXPR_NUMGEN */ + enum nft_ng_types type; + uint32_t mod; + uint32_t offset; + } numgen; + struct { + /* EXPR_HASH */ + struct expr *expr; + uint32_t mod; + bool seed_set; + uint32_t seed; + uint32_t offset; + enum nft_hash_types type; + } hash; + struct { + /* EXPR_FIB */ + uint32_t flags; + uint32_t result; + } fib; + struct { + /* EXPR_XFRM */ + enum nft_xfrm_keys key; + uint8_t direction; + uint8_t spnum; + } xfrm; + struct { + /* EXPR_OSF */ + uint8_t ttl; + uint32_t flags; + } osf; + struct { + /* EXPR_FLAGCMP */ + struct expr *expr; + struct expr *mask; + struct expr *value; + } flagcmp; + }; +}; + +extern struct expr *expr_alloc(const struct location *loc, + enum expr_types etype, + const struct datatype *dtype, + enum byteorder byteorder, unsigned int len); +extern struct expr *expr_clone(const struct expr *expr); +extern struct expr *expr_get(struct expr *expr); +extern void expr_free(struct expr *expr); +extern void expr_print(const struct expr *expr, struct output_ctx *octx); +extern bool expr_cmp(const struct expr *e1, const struct expr *e2); +extern void expr_describe(const struct expr *expr, struct output_ctx *octx); + +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); + +void expr_to_string(const struct expr *expr, char *string); + +struct eval_ctx; +extern int expr_binary_error(struct list_head *msgs, + const struct expr *e1, const struct expr *e2, + const char *fmt, ...) __gmp_fmtstring(4, 5); + +#define expr_error(msgs, expr, fmt, args...) \ + expr_binary_error(msgs, expr, NULL, fmt, ## args) + +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 bool must_print_eq_op(const struct expr *expr); + +extern struct expr *relational_expr_alloc(const struct location *loc, enum ops op, + struct expr *left, struct expr *right); + +extern void relational_expr_pctx_update(struct proto_ctx *ctx, + const struct expr *expr); + +extern struct expr *verdict_expr_alloc(const struct location *loc, + int verdict, struct expr *chain); + +extern struct expr *symbol_expr_alloc(const struct location *loc, + enum symbol_types type, struct scope *scope, + const char *identifier); + +const char *expr_name(const struct expr *e); + +static inline void symbol_expr_set_type(struct expr *expr, + const struct datatype *dtype) +{ + if (expr->etype == EXPR_SYMBOL) + datatype_set(expr, dtype); +} + +struct expr *variable_expr_alloc(const struct location *loc, + struct scope *scope, struct symbol *sym); + +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 *flag_expr_alloc(const struct location *loc, + const struct datatype *dtype, + enum byteorder byteorder, + unsigned int len, unsigned long n); +extern struct expr *bitmask_expr_to_binops(struct expr *expr); + +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); +struct expr *range_expr_to_prefix(struct expr *range); + +extern struct expr *compound_expr_alloc(const struct location *loc, + enum expr_types etypes); +extern void compound_expr_add(struct expr *compound, struct expr *expr); +extern void compound_expr_remove(struct expr *compound, struct expr *expr); +extern void list_expr_sort(struct list_head *head); +extern void list_splice_sorted(struct list_head *list, struct list_head *head); + +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, + const struct set *set); +extern void concat_range_aggregate(struct expr *set); +extern void interval_map_decompose(struct expr *set); + +extern struct expr *get_set_intervals(const struct set *set, + const struct expr *init); +struct table; +extern int get_set_decompose(struct set *cache_set, struct set *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); + +extern struct expr *set_ref_expr_alloc(const struct location *loc, + struct set *set); + +extern struct expr *set_elem_expr_alloc(const struct location *loc, + struct expr *key); + +struct expr *set_elem_catchall_expr_alloc(const struct location *loc); + +struct expr *flagcmp_expr_alloc(const struct location *loc, enum ops op, + struct expr *expr, struct expr *mask, + struct expr *value); + +extern void range_expr_value_low(mpz_t rop, const struct expr *expr); +extern void range_expr_value_high(mpz_t rop, const struct expr *expr); + +#endif /* NFTABLES_EXPRESSION_H */ |