Blame include/expression.h

Packit c5a612
#ifndef NFTABLES_EXPRESSION_H
Packit c5a612
#define NFTABLES_EXPRESSION_H
Packit c5a612
Packit c5a612
#include <stdbool.h>
Packit c5a612
#include <gmputil.h>
Packit c5a612
#include <linux/netfilter/nf_tables.h>
Packit c5a612
Packit c5a612
#include <nftables.h>
Packit c5a612
#include <datatype.h>
Packit c5a612
#include <utils.h>
Packit c5a612
#include <list.h>
Packit c5a612
#include <json.h>
Packit c5a612
Packit c5a612
/**
Packit c5a612
 * enum expr_types
Packit c5a612
 *
Packit c5a612
 * @EXPR_INVALID:	uninitialized type, should not happen
Packit c5a612
 * @EXPR_VERDICT:	nftables verdict expression
Packit c5a612
 * @EXPR_SYMBOL:	unparsed symbol
Packit c5a612
 * @EXPR_VARIABLE:	variable
Packit c5a612
 * @EXPR_VALUE:		literal numeric or string expression
Packit c5a612
 * @EXPR_PREFIX:	prefixed expression
Packit c5a612
 * @EXPR_RANGE:		literal range
Packit c5a612
 * @EXPR_PAYLOAD:	payload expression
Packit c5a612
 * @EXPR_EXTHDR:	exthdr expression
Packit c5a612
 * @EXPR_META:		meta expression
Packit c5a612
 * @EXPR_SOCKET:	socket expression
Packit c5a612
 * @EXPR_OSF:		osf expression
Packit c5a612
 * @EXPR_CT:		conntrack expression
Packit c5a612
 * @EXPR_CONCAT:	concatenation
Packit c5a612
 * @EXPR_LIST:		list of expressions
Packit c5a612
 * @EXPR_SET:		literal set
Packit c5a612
 * @EXPR_SET_REF:	set reference
Packit c5a612
 * @EXPR_SET_ELEM:	set element
Packit c5a612
 * @EXPR_MAPPING:	a single mapping (key : value)
Packit c5a612
 * @EXPR_MAP:		map operation (expr map { EXPR_MAPPING, ... })
Packit c5a612
 * @EXPR_UNARY:		byteorder conversion, generated during evaluation
Packit c5a612
 * @EXPR_BINOP:		binary operations (bitwise, shifts)
Packit c5a612
 * @EXPR_RELATIONAL:	equality and relational expressions
Packit c5a612
 * @EXPR_NUMGEN:	number generation expression
Packit c5a612
 * @EXPR_HASH:		hash expression
Packit c5a612
 * @EXPR_RT:		routing expression
Packit c5a612
 */
Packit c5a612
enum expr_types {
Packit c5a612
	EXPR_INVALID,
Packit c5a612
	EXPR_VERDICT,
Packit c5a612
	EXPR_SYMBOL,
Packit c5a612
	EXPR_VARIABLE,
Packit c5a612
	EXPR_VALUE,
Packit c5a612
	EXPR_PREFIX,
Packit c5a612
	EXPR_RANGE,
Packit c5a612
	EXPR_PAYLOAD,
Packit c5a612
	EXPR_EXTHDR,
Packit c5a612
	EXPR_META,
Packit c5a612
	EXPR_SOCKET,
Packit c5a612
	EXPR_OSF,
Packit c5a612
	EXPR_CT,
Packit c5a612
	EXPR_CONCAT,
Packit c5a612
	EXPR_LIST,
Packit c5a612
	EXPR_SET,
Packit c5a612
	EXPR_SET_REF,
Packit c5a612
	EXPR_SET_ELEM,
Packit c5a612
	EXPR_MAPPING,
Packit c5a612
	EXPR_MAP,
Packit c5a612
	EXPR_UNARY,
Packit c5a612
	EXPR_BINOP,
Packit c5a612
	EXPR_RELATIONAL,
Packit c5a612
	EXPR_NUMGEN,
Packit c5a612
	EXPR_HASH,
Packit c5a612
	EXPR_RT,
Packit c5a612
	EXPR_FIB,
Packit c5a612
	EXPR_XFRM,
Packit c5a612
};
Packit c5a612
Packit c5a612
enum ops {
Packit c5a612
	OP_INVALID,
Packit c5a612
	OP_IMPLICIT,
Packit c5a612
	/* Unary operations */
Packit c5a612
	OP_HTON,
Packit c5a612
	OP_NTOH,
Packit c5a612
	/* Binary operations */
Packit c5a612
	OP_LSHIFT,
Packit c5a612
	OP_RSHIFT,
Packit c5a612
	OP_AND,
Packit c5a612
	OP_XOR,
Packit c5a612
	OP_OR,
Packit c5a612
	/* Relational operations */
Packit c5a612
	OP_EQ,
Packit c5a612
	OP_NEQ,
Packit c5a612
	OP_LT,
Packit c5a612
	OP_GT,
Packit c5a612
	OP_LTE,
Packit c5a612
	OP_GTE,
Packit c5a612
	__OP_MAX
Packit c5a612
};
Packit c5a612
#define OP_MAX		(__OP_MAX - 1)
Packit c5a612
Packit c5a612
extern const char *expr_op_symbols[];
Packit c5a612
Packit c5a612
enum symbol_types {
Packit c5a612
	SYMBOL_VALUE,
Packit c5a612
	SYMBOL_SET,
Packit c5a612
};
Packit c5a612
Packit c5a612
/**
Packit c5a612
 * struct expr_ctx - type context for symbol parsing during evaluation
Packit c5a612
 *
Packit c5a612
 * @dtype:	expected datatype
Packit c5a612
 * @byteorder:	expected byteorder
Packit c5a612
 * @len:	expected len
Packit c5a612
 * @maxval:	expected maximum value
Packit c5a612
 */
Packit c5a612
struct expr_ctx {
Packit c5a612
	const struct datatype	*dtype;
Packit c5a612
	enum byteorder		byteorder;
Packit c5a612
	unsigned int		len;
Packit c5a612
	unsigned int		maxval;
Packit c5a612
};
Packit c5a612
Packit c5a612
static inline void __expr_set_context(struct expr_ctx *ctx,
Packit c5a612
				      const struct datatype *dtype,
Packit c5a612
				      enum byteorder byteorder,
Packit c5a612
				      unsigned int len, unsigned int maxval)
Packit c5a612
{
Packit c5a612
	ctx->dtype	= dtype;
Packit c5a612
	ctx->byteorder	= byteorder;
Packit c5a612
	ctx->len	= len;
Packit c5a612
	ctx->maxval	= maxval;
Packit c5a612
}
Packit c5a612
Packit c5a612
static inline void expr_set_context(struct expr_ctx *ctx,
Packit c5a612
				    const struct datatype *dtype,
Packit c5a612
				    unsigned int len)
Packit c5a612
{
Packit c5a612
	__expr_set_context(ctx, dtype,
Packit c5a612
			   dtype ? dtype->byteorder : BYTEORDER_INVALID,
Packit c5a612
			   len, 0);
Packit c5a612
}
Packit c5a612
Packit c5a612
/**
Packit c5a612
 * struct expr_ops
Packit c5a612
 *
Packit c5a612
 * @type:	expression type
Packit c5a612
 * @name:	expression name for diagnostics
Packit c5a612
 * @clone:	function to clone type specific data
Packit c5a612
 * @destroy:	destructor, must release inner expressions
Packit c5a612
 * @set_type:	function to promote type and byteorder of inner types
Packit c5a612
 * @print:	function to print the expression
Packit c5a612
 * @cmp:	function to compare two expressions of the same types
Packit c5a612
 * @pctx_update:update protocol context
Packit c5a612
 */
Packit c5a612
struct proto_ctx;
Packit c5a612
struct expr_ops {
Packit c5a612
	enum expr_types		type;
Packit c5a612
	const char		*name;
Packit c5a612
	void			(*clone)(struct expr *new, const struct expr *expr);
Packit c5a612
	void			(*destroy)(struct expr *expr);
Packit c5a612
	void			(*set_type)(const struct expr *expr,
Packit c5a612
					    const struct datatype *dtype,
Packit c5a612
					    enum byteorder byteorder);
Packit c5a612
	void			(*print)(const struct expr *expr,
Packit c5a612
					 struct output_ctx *octx);
Packit c5a612
	json_t			*(*json)(const struct expr *expr,
Packit c5a612
					 struct output_ctx *octx);
Packit c5a612
	bool			(*cmp)(const struct expr *e1,
Packit c5a612
				       const struct expr *e2);
Packit c5a612
	void			(*pctx_update)(struct proto_ctx *ctx,
Packit c5a612
					       const struct expr *expr);
Packit c5a612
};
Packit c5a612
Packit c5a612
const struct expr_ops *expr_ops(const struct expr *e);
Packit c5a612
Packit c5a612
/**
Packit c5a612
 * enum expr_flags
Packit c5a612
 *
Packit c5a612
 * @EXPR_F_CONSTANT:		constant expression
Packit c5a612
 * @EXPR_F_SINGLETON:		singleton (implies primary and constant)
Packit c5a612
 * @EXPR_F_PROTOCOL:		expressions describes upper layer protocol
Packit c5a612
 * @EXPR_F_INTERVAL_END:	set member ends an open interval
Packit c5a612
 * @EXPR_F_BOOLEAN:		expression is boolean (set by relational expr on LHS)
Packit c5a612
 */
Packit c5a612
enum expr_flags {
Packit c5a612
	EXPR_F_CONSTANT		= 0x1,
Packit c5a612
	EXPR_F_SINGLETON	= 0x2,
Packit c5a612
	EXPR_F_PROTOCOL		= 0x4,
Packit c5a612
	EXPR_F_INTERVAL_END	= 0x8,
Packit c5a612
	EXPR_F_BOOLEAN		= 0x10,
Packit c5a612
};
Packit c5a612
Packit c5a612
#include <payload.h>
Packit c5a612
#include <exthdr.h>
Packit c5a612
#include <fib.h>
Packit c5a612
#include <numgen.h>
Packit c5a612
#include <meta.h>
Packit c5a612
#include <rt.h>
Packit c5a612
#include <hash.h>
Packit c5a612
#include <ct.h>
Packit c5a612
#include <socket.h>
Packit c5a612
#include <osf.h>
Packit c5a612
#include <xfrm.h>
Packit c5a612
Packit c5a612
/**
Packit c5a612
 * struct expr
Packit c5a612
 *
Packit c5a612
 * @list:	list node
Packit c5a612
 * @location:	location from parser
Packit c5a612
 * @refcnt:	reference count
Packit c5a612
 * @flags:	mask of enum expr_flags
Packit c5a612
 * @dtype:	data type of expression
Packit c5a612
 * @byteorder:	byteorder of expression
Packit c5a612
 * @etype:	expression type
Packit c5a612
 * @op:		operation for unary, binary and relational expressions
Packit c5a612
 * @len:	length of expression
Packit c5a612
 * @union:	type specific data
Packit c5a612
 */
Packit c5a612
struct expr {
Packit c5a612
	struct list_head	list;
Packit c5a612
	struct location		location;
Packit c5a612
Packit c5a612
	unsigned int		refcnt;
Packit c5a612
	unsigned int		flags;
Packit c5a612
Packit c5a612
	const struct datatype	*dtype;
Packit c5a612
	enum byteorder		byteorder:8;
Packit c5a612
	enum expr_types		etype:8;
Packit c5a612
	enum ops		op:8;
Packit c5a612
	unsigned int		len;
Packit c5a612
Packit c5a612
	union {
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_SYMBOL */
Packit c5a612
			const struct scope	*scope;
Packit c5a612
			const char		*identifier;
Packit c5a612
			enum symbol_types	symtype;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_VARIABLE */
Packit c5a612
			struct symbol		*sym;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_VERDICT */
Packit c5a612
			int			verdict;
Packit c5a612
			struct expr		*chain;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_VALUE */
Packit c5a612
			mpz_t			value;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_PREFIX */
Packit c5a612
			struct expr		*prefix;
Packit c5a612
			unsigned int		prefix_len;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_CONCAT, EXPR_LIST, EXPR_SET */
Packit c5a612
			struct list_head	expressions;
Packit c5a612
			unsigned int		size;
Packit c5a612
			uint32_t		set_flags;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_SET_REF */
Packit c5a612
			struct set		*set;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_SET_ELEM */
Packit c5a612
			struct expr		*key;
Packit c5a612
			uint64_t		timeout;
Packit c5a612
			uint64_t		expiration;
Packit c5a612
			const char		*comment;
Packit c5a612
			struct stmt		*stmt;
Packit c5a612
			uint32_t		elem_flags;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_UNARY */
Packit c5a612
			struct expr		*arg;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_RANGE, EXPR_BINOP, EXPR_MAPPING, EXPR_RELATIONAL */
Packit c5a612
			struct expr		*left;
Packit c5a612
			struct expr		*right;
Packit c5a612
		};
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_MAP */
Packit c5a612
			struct expr		*map;
Packit c5a612
			struct expr		*mappings;
Packit c5a612
		};
Packit c5a612
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_PAYLOAD */
Packit c5a612
			const struct proto_desc		*desc;
Packit c5a612
			const struct proto_hdr_template	*tmpl;
Packit c5a612
			enum proto_bases		base;
Packit c5a612
			unsigned int			offset;
Packit c5a612
			bool				is_raw;
Packit c5a612
		} payload;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_EXTHDR */
Packit c5a612
			const struct exthdr_desc	*desc;
Packit c5a612
			const struct proto_hdr_template	*tmpl;
Packit c5a612
			unsigned int			offset;
Packit c5a612
			enum nft_exthdr_op		op;
Packit c5a612
			unsigned int			flags;
Packit c5a612
		} exthdr;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_META */
Packit c5a612
			enum nft_meta_keys	key;
Packit c5a612
			enum proto_bases	base;
Packit c5a612
		} meta;
Packit c5a612
		struct {
Packit c5a612
			/* SOCKET */
Packit c5a612
			enum nft_socket_keys	key;
Packit c5a612
		} socket;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_RT */
Packit c5a612
			enum nft_rt_keys	key;
Packit c5a612
		} rt;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_CT */
Packit c5a612
			enum nft_ct_keys	key;
Packit c5a612
			enum proto_bases	base;
Packit c5a612
			int8_t			direction;
Packit c5a612
			uint8_t			nfproto;
Packit c5a612
		} ct;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_NUMGEN */
Packit c5a612
			enum nft_ng_types	type;
Packit c5a612
			uint32_t		mod;
Packit c5a612
			uint32_t		offset;
Packit c5a612
		} numgen;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_HASH */
Packit c5a612
			struct expr		*expr;
Packit c5a612
			uint32_t		mod;
Packit c5a612
			bool			seed_set;
Packit c5a612
			uint32_t		seed;
Packit c5a612
			uint32_t		offset;
Packit c5a612
			enum nft_hash_types	type;
Packit c5a612
		} hash;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_FIB */
Packit c5a612
			uint32_t		flags;
Packit c5a612
			uint32_t		result;
Packit c5a612
		} fib;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_XFRM */
Packit c5a612
			enum nft_xfrm_keys	key;
Packit c5a612
			uint8_t		direction;
Packit c5a612
			uint8_t		spnum;
Packit c5a612
		} xfrm;
Packit c5a612
		struct {
Packit c5a612
			/* EXPR_OSF */
Packit c5a612
			uint8_t			ttl;
Packit c5a612
			uint32_t		flags;
Packit c5a612
		} osf;
Packit c5a612
	};
Packit c5a612
};
Packit c5a612
Packit c5a612
extern struct expr *expr_alloc(const struct location *loc,
Packit c5a612
			       enum expr_types etype,
Packit c5a612
			       const struct datatype *dtype,
Packit c5a612
			       enum byteorder byteorder, unsigned int len);
Packit c5a612
extern struct expr *expr_clone(const struct expr *expr);
Packit c5a612
extern struct expr *expr_get(struct expr *expr);
Packit c5a612
extern void expr_free(struct expr *expr);
Packit c5a612
extern void expr_print(const struct expr *expr, struct output_ctx *octx);
Packit c5a612
extern bool expr_cmp(const struct expr *e1, const struct expr *e2);
Packit c5a612
extern void expr_describe(const struct expr *expr, struct output_ctx *octx);
Packit c5a612
Packit c5a612
extern const struct datatype *expr_basetype(const struct expr *expr);
Packit c5a612
extern void expr_set_type(struct expr *expr, const struct datatype *dtype,
Packit c5a612
			  enum byteorder byteorder);
Packit c5a612
Packit c5a612
struct eval_ctx;
Packit c5a612
extern int expr_binary_error(struct list_head *msgs,
Packit c5a612
			     const struct expr *e1, const struct expr *e2,
Packit c5a612
			     const char *fmt, ...) __gmp_fmtstring(4, 5);
Packit c5a612
Packit c5a612
#define expr_error(msgs, expr, fmt, args...) \
Packit c5a612
	expr_binary_error(msgs, expr, NULL, fmt, ## args)
Packit c5a612
Packit c5a612
static inline bool expr_is_constant(const struct expr *expr)
Packit c5a612
{
Packit c5a612
	return expr->flags & EXPR_F_CONSTANT ? true : false;
Packit c5a612
}
Packit c5a612
Packit c5a612
static inline bool expr_is_singleton(const struct expr *expr)
Packit c5a612
{
Packit c5a612
	return expr->flags & EXPR_F_SINGLETON ? true : false;
Packit c5a612
}
Packit c5a612
Packit c5a612
extern struct expr *unary_expr_alloc(const struct location *loc,
Packit c5a612
				     enum ops op, struct expr *arg);
Packit c5a612
Packit c5a612
extern struct expr *binop_expr_alloc(const struct location *loc, enum ops op,
Packit c5a612
				     struct expr *left, struct expr *right);
Packit c5a612
Packit c5a612
extern bool must_print_eq_op(const struct expr *expr);
Packit c5a612
Packit c5a612
extern struct expr *relational_expr_alloc(const struct location *loc, enum ops op,
Packit c5a612
					  struct expr *left, struct expr *right);
Packit c5a612
Packit c5a612
extern void relational_expr_pctx_update(struct proto_ctx *ctx,
Packit c5a612
					const struct expr *expr);
Packit c5a612
Packit c5a612
extern struct expr *verdict_expr_alloc(const struct location *loc,
Packit c5a612
				       int verdict, struct expr *chain);
Packit c5a612
Packit c5a612
extern struct expr *symbol_expr_alloc(const struct location *loc,
Packit c5a612
				      enum symbol_types type, struct scope *scope,
Packit c5a612
				      const char *identifier);
Packit c5a612
Packit c5a612
const char *expr_name(const struct expr *e);
Packit c5a612
Packit c5a612
static inline void symbol_expr_set_type(struct expr *expr,
Packit c5a612
					const struct datatype *dtype)
Packit c5a612
{
Packit c5a612
	if (expr->etype == EXPR_SYMBOL)
Packit c5a612
		datatype_set(expr, dtype);
Packit c5a612
}
Packit c5a612
Packit c5a612
struct expr *variable_expr_alloc(const struct location *loc,
Packit c5a612
				 struct scope *scope, struct symbol *sym);
Packit c5a612
Packit c5a612
extern struct expr *constant_expr_alloc(const struct location *loc,
Packit c5a612
					const struct datatype *dtype,
Packit c5a612
					enum byteorder byteorder,
Packit c5a612
					unsigned int len, const void *data);
Packit c5a612
extern struct expr *constant_expr_join(const struct expr *e1,
Packit c5a612
				       const struct expr *e2);
Packit c5a612
extern struct expr *constant_expr_splice(struct expr *expr, unsigned int len);
Packit c5a612
Packit c5a612
extern struct expr *flag_expr_alloc(const struct location *loc,
Packit c5a612
				    const struct datatype *dtype,
Packit c5a612
				    enum byteorder byteorder,
Packit c5a612
				    unsigned int len, unsigned long n);
Packit c5a612
extern struct expr *bitmask_expr_to_binops(struct expr *expr);
Packit c5a612
Packit c5a612
extern struct expr *prefix_expr_alloc(const struct location *loc,
Packit c5a612
				      struct expr *expr,
Packit c5a612
				      unsigned int prefix_len);
Packit c5a612
Packit c5a612
extern struct expr *range_expr_alloc(const struct location *loc,
Packit c5a612
				     struct expr *low, struct expr *high);
Packit c5a612
Packit c5a612
extern struct expr *compound_expr_alloc(const struct location *loc,
Packit c5a612
					enum expr_types etypes);
Packit c5a612
extern void compound_expr_add(struct expr *compound, struct expr *expr);
Packit c5a612
extern void compound_expr_remove(struct expr *compound, struct expr *expr);
Packit c5a612
extern void list_expr_sort(struct list_head *head);
Packit c5a612
Packit c5a612
extern struct expr *concat_expr_alloc(const struct location *loc);
Packit c5a612
Packit c5a612
extern struct expr *list_expr_alloc(const struct location *loc);
Packit c5a612
Packit c5a612
extern struct expr *set_expr_alloc(const struct location *loc,
Packit c5a612
				   const struct set *set);
Packit c5a612
extern int set_to_intervals(struct list_head *msgs, struct set *set,
Packit c5a612
			    struct expr *init, bool add,
Packit c5a612
			    unsigned int debug_mask, bool merge,
Packit c5a612
			    struct output_ctx *octx);
Packit c5a612
extern void interval_map_decompose(struct expr *set);
Packit c5a612
Packit c5a612
extern struct expr *get_set_intervals(const struct set *set,
Packit c5a612
				      const struct expr *init);
Packit c5a612
struct table;
Packit c5a612
extern int get_set_decompose(struct table *table, struct set *set);
Packit c5a612
Packit c5a612
extern struct expr *mapping_expr_alloc(const struct location *loc,
Packit c5a612
				       struct expr *from, struct expr *to);
Packit c5a612
extern struct expr *map_expr_alloc(const struct location *loc,
Packit c5a612
				   struct expr *arg, struct expr *list);
Packit c5a612
Packit c5a612
extern struct expr *set_ref_expr_alloc(const struct location *loc,
Packit c5a612
				       struct set *set);
Packit c5a612
Packit c5a612
extern struct expr *set_elem_expr_alloc(const struct location *loc,
Packit c5a612
					struct expr *key);
Packit c5a612
Packit c5a612
extern void range_expr_value_low(mpz_t rop, const struct expr *expr);
Packit c5a612
extern void range_expr_value_high(mpz_t rop, const struct expr *expr);
Packit c5a612
Packit c5a612
#endif /* NFTABLES_EXPRESSION_H */