diff options
Diffstat (limited to '')
-rw-r--r-- | include/rule.h | 791 |
1 files changed, 791 insertions, 0 deletions
diff --git a/include/rule.h b/include/rule.h new file mode 100644 index 0000000..6236d29 --- /dev/null +++ b/include/rule.h @@ -0,0 +1,791 @@ +#ifndef NFTABLES_RULE_H +#define NFTABLES_RULE_H + +#include <nftables.h> +#include <list.h> +#include <netinet/in.h> +#include <libnftnl/object.h> /* For NFTNL_CTTIMEOUT_ARRAY_MAX. */ +#include <linux/netfilter/nf_tables.h> +#include <cache.h> + +/** + * struct handle_spec - handle ID + * + * @location: location this handle was defined at + * @id: handle ID value + */ +struct handle_spec { + struct location location; + uint64_t id; +}; + +/** + * struct position_spec - position ID + * + * @location: location this position was defined at + * @id: position ID value + */ +struct position_spec { + struct location location; + uint64_t id; +}; + +struct table_spec { + struct location location; + const char *name; +}; + +struct chain_spec { + struct location location; + const char *name; +}; + +struct set_spec { + struct location location; + const char *name; +}; + +struct flowtable_spec { + struct location location; + const char *name; +}; + +struct obj_spec { + struct location location; + const char *name; +}; + +/** + * struct handle - handle for tables, chains, rules and sets + * + * @family: protocol family + * @table: table name + * @chain: chain name (chains and rules only) + * @set: set name (sets only) + * @obj: stateful object name (stateful object only) + * @flowtable: flow table name (flow table only) + * @handle: rule handle (rules only) + * @position: rule position (rules only) + * @set_id: set ID (sets only) + */ +struct handle { + uint32_t family; + struct table_spec table; + struct chain_spec chain; + struct set_spec set; + struct obj_spec obj; + struct flowtable_spec flowtable; + struct handle_spec handle; + struct position_spec position; + struct position_spec index; + uint32_t set_id; + uint32_t chain_id; + uint32_t rule_id; + uint32_t position_id; +}; + +extern void handle_merge(struct handle *dst, const struct handle *src); +extern void handle_free(struct handle *h); + +/** + * struct scope + * + * @parent: pointer to parent scope + * @symbols: symbols bound in the scope + */ +struct scope { + const struct scope *parent; + struct list_head symbols; +}; + +extern struct scope *scope_alloc(void); +extern struct scope *scope_init(struct scope *scope, const struct scope *parent); +extern void scope_release(const struct scope *scope); +extern void scope_free(struct scope *scope); + +/** + * struct symbol + * + * @list: scope symbol list node + * @identifier: identifier + * @expr: initializer + * @refcnt: reference counter + */ +struct symbol { + struct list_head list; + const char *identifier; + struct expr *expr; + int refcnt; +}; + +extern void symbol_bind(struct scope *scope, const char *identifier, + struct expr *expr); +extern int symbol_unbind(const struct scope *scope, const char *identifier); +extern struct symbol *symbol_lookup(const struct scope *scope, + const char *identifier); +struct symbol *symbol_lookup_fuzzy(const struct scope *scope, + const char *identifier); +struct symbol *symbol_get(const struct scope *scope, const char *identifier); + +enum table_flags { + TABLE_F_DORMANT = (1 << 0), + TABLE_F_OWNER = (1 << 1), +}; +#define TABLE_FLAGS_MAX 2 + +const char *table_flag_name(uint32_t flag); + +/** + * struct table - nftables table + * + * @list: list node + * @handle: table handle + * @location: location the table was defined at + * @chains: chains contained in the table + * @sets: sets contained in the table + * @objs: stateful objects contained in the table + * @flowtables: flow tables contained in the table + * @flags: table flags + * @refcnt: table reference counter + */ +struct table { + struct list_head list; + struct cache_item cache; + struct handle handle; + struct location location; + struct scope scope; + struct cache chain_cache; + struct cache set_cache; + struct cache obj_cache; + struct cache ft_cache; + struct list_head chains; + struct list_head sets; + struct list_head objs; + struct list_head flowtables; + struct list_head chain_bindings; + enum table_flags flags; + unsigned int refcnt; + uint32_t owner; + const char *comment; + bool has_xt_stmts; +}; + +extern struct table *table_alloc(void); +extern struct table *table_get(struct table *table); +extern void table_free(struct table *table); +extern struct table *table_lookup_fuzzy(const struct handle *h, + const struct nft_cache *cache); + +/** + * enum chain_flags - chain flags + * + * @CHAIN_F_BASECHAIN: chain is a base chain + */ +enum chain_flags { + CHAIN_F_BASECHAIN = 0x1, + CHAIN_F_HW_OFFLOAD = 0x2, + CHAIN_F_BINDING = 0x4, +}; + +/** + * enum flowtable_flags - flowtable flags + * + */ +enum flowtable_flags { + FLOWTABLE_F_HW_OFFLOAD = 0x1, /* NF_FLOWTABLE_HW_OFFLOAD in linux nf_flow_table.h */ +}; + +/** + * struct prio_spec - extendend priority specification for mixed + * textual/numerical parsing. + * + * @expr: expr of the standard priority value + */ +struct prio_spec { + struct location loc; + struct expr *expr; +}; + +struct hook_spec { + struct location loc; + const char *name; + unsigned int num; +}; + +struct chain_type_spec { + struct location loc; + const char *str; +}; + +/** + * struct chain - nftables chain + * + * @list: list node in table list + * @handle: chain handle + * @location: location the chain was defined at + * @refcnt: reference counter + * @flags: chain flags + * @hookstr: unified and human readable hook name (base chains) + * @hooknum: hook number (base chains) + * @priority: hook priority (base chains) + * @policy: default chain policy (base chains) + * @type: chain type + * @dev: device (if any) + * @rules: rules contained in the chain + */ +struct chain { + struct list_head list; + struct cache_item cache; + struct handle handle; + struct location location; + unsigned int refcnt; + uint32_t flags; + const char *comment; + struct { + struct location loc; + struct prio_spec priority; + struct hook_spec hook; + struct expr *policy; + struct chain_type_spec type; + const char **dev_array; + struct expr *dev_expr; + int dev_array_len; + }; + struct scope scope; + struct list_head rules; +}; + +#define STD_PRIO_BUFSIZE 100 +extern int std_prio_lookup(const char *std_prio_name, int family, int hook); +extern const char *chain_type_name_lookup(const char *name); +extern const char *chain_hookname_lookup(const char *name); +extern struct chain *chain_alloc(void); +extern struct chain *chain_get(struct chain *chain); +extern void chain_free(struct chain *chain); +extern struct chain *chain_lookup_fuzzy(const struct handle *h, + const struct nft_cache *cache, + const struct table **table); +extern struct chain *chain_binding_lookup(const struct table *table, + const char *chain_name); + +extern const char *family2str(unsigned int family); +#define __NF_ARP_INGRESS 255 +extern const char *hooknum2str(unsigned int family, unsigned int hooknum); +extern const char *chain_policy2str(uint32_t policy); +extern void chain_print_plain(const struct chain *chain, + struct output_ctx *octx); +extern void chain_rules_print(const struct chain *chain, + struct output_ctx *octx, const char *indent); + +/** + * 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 + * @comment: comment + * @refcnt: rule reference counter + */ +struct rule { + struct list_head list; + struct handle handle; + struct location location; + struct list_head stmts; + unsigned int num_stmts; + const char *comment; + unsigned int refcnt; +}; + +extern struct rule *rule_alloc(const struct location *loc, + const struct handle *h); +extern struct rule *rule_get(struct rule *rule); +extern void rule_free(struct rule *rule); +extern void rule_print(const struct rule *rule, struct output_ctx *octx); +extern struct rule *rule_lookup(const struct chain *chain, uint64_t handle); +extern struct rule *rule_lookup_by_index(const struct chain *chain, + uint64_t index); +void rule_stmt_append(struct rule *rule, struct stmt *stmt); +void rule_stmt_insert_at(struct rule *rule, struct stmt *nstmt, + struct stmt *stmt); + +/** + * struct set - nftables set + * + * @list: table set list node + * @handle: set handle + * @location: location the set was defined/declared at + * @refcnt: reference count + * @flags: bitmask of set flags + * @gc_int: garbage collection interval + * @timeout: default timeout value + * @key: key expression (data type, length)) + * @data: mapping data expression + * @objtype: mapping object type + * @existing_set: reference to existing set in the kernel + * @init: initializer + * @rg_cache: cached range element (left) + * @policy: set mechanism policy + * @automerge: merge adjacents and overlapping elements, if possible + * @comment: comment + * @desc.size: count of set elements + * @desc.field_len: length of single concatenated fields, bytes + * @desc.field_count: count of concatenated fields + */ +struct set { + struct list_head list; + struct cache_item cache; + struct handle handle; + struct location location; + unsigned int refcnt; + uint32_t flags; + uint32_t gc_int; + uint64_t timeout; + struct expr *key; + struct expr *data; + uint32_t objtype; + struct set *existing_set; + struct expr *init; + struct expr *rg_cache; + uint32_t policy; + struct list_head stmt_list; + bool root; + bool automerge; + bool key_typeof_valid; + const char *comment; + struct { + uint32_t size; + uint8_t field_len[NFT_REG32_COUNT]; + uint8_t field_count; + } desc; +}; + +extern struct set *set_alloc(const struct location *loc); +extern struct set *set_get(struct set *set); +extern void set_free(struct set *set); +extern struct set *set_clone(const struct set *set); +extern struct set *set_lookup_global(uint32_t family, const char *table, + const char *name, struct nft_cache *cache); +extern struct set *set_lookup_fuzzy(const char *set_name, + const struct nft_cache *cache, + const struct table **table); +extern const char *set_policy2str(uint32_t policy); +extern void set_print(const struct set *set, struct output_ctx *octx); +extern void set_print_plain(const struct set *s, struct output_ctx *octx); + +static inline bool set_is_datamap(uint32_t set_flags) +{ + return set_flags & NFT_SET_MAP; +} + +static inline bool set_is_objmap(uint32_t set_flags) +{ + return set_flags & NFT_SET_OBJECT; +} + +static inline bool set_is_map(uint32_t set_flags) +{ + return set_is_datamap(set_flags) || set_is_objmap(set_flags); +} + +static inline bool set_is_anonymous(uint32_t set_flags) +{ + return set_flags & NFT_SET_ANONYMOUS; +} + +static inline bool set_is_literal(uint32_t set_flags) +{ + return !(set_is_anonymous(set_flags) || set_is_map(set_flags)); +} + +static inline bool map_is_literal(uint32_t set_flags) +{ + return !(set_is_anonymous(set_flags) || !set_is_map(set_flags)); +} + +static inline bool set_is_meter(uint32_t set_flags) +{ + return set_is_anonymous(set_flags) && (set_flags & NFT_SET_EVAL); +} + +static inline bool set_is_interval(uint32_t set_flags) +{ + return set_flags & NFT_SET_INTERVAL; +} + +static inline bool set_is_non_concat_range(struct set *s) +{ + return (s->flags & NFT_SET_INTERVAL) && s->desc.field_count <= 1; +} + +#include <statement.h> + +struct counter { + uint64_t packets; + uint64_t bytes; +}; + +struct quota { + uint64_t bytes; + uint64_t used; + uint32_t flags; +}; + +struct ct_helper { + char name[16]; + uint16_t l3proto; + uint8_t l4proto; +}; + +struct timeout_state { + struct list_head head; + struct location location; + uint8_t timeout_index; + const char *timeout_str; + unsigned int timeout_value; +}; + +struct ct_timeout { + uint16_t l3proto; + uint8_t l4proto; + uint32_t timeout[NFTNL_CTTIMEOUT_ARRAY_MAX]; + struct list_head timeout_list; +}; + +struct ct_expect { + uint16_t l3proto; + uint8_t l4proto; + uint16_t dport; + uint32_t timeout; + uint8_t size; +}; + +struct limit { + uint64_t rate; + uint64_t unit; + uint32_t burst; + uint32_t type; + uint32_t flags; +}; + +struct synproxy { + uint16_t mss; + uint8_t wscale; + uint32_t flags; +}; + +struct secmark { + char ctx[NFT_SECMARK_CTX_MAXLEN]; +}; + +/** + * struct obj - nftables stateful object statement + * + * @list: table set list node + * @location: location the stateful object was defined/declared at + * @handle: counter handle + * @type: type of stateful object + * @refcnt: object reference counter + */ +struct obj { + struct list_head list; + struct cache_item cache; + struct location location; + struct handle handle; + uint32_t type; + unsigned int refcnt; + const char *comment; + union { + struct counter counter; + struct quota quota; + struct ct_helper ct_helper; + struct limit limit; + struct ct_timeout ct_timeout; + struct secmark secmark; + struct ct_expect ct_expect; + struct synproxy synproxy; + }; +}; + +struct obj *obj_alloc(const struct location *loc); +extern struct obj *obj_get(struct obj *obj); +void obj_free(struct obj *obj); +struct obj *obj_lookup_fuzzy(const char *obj_name, + const struct nft_cache *cache, + const struct table **t); +void obj_print(const struct obj *n, struct output_ctx *octx); +void obj_print_plain(const struct obj *obj, struct output_ctx *octx); +const char *obj_type_name(uint32_t type); +enum cmd_obj obj_type_to_cmd(uint32_t type); + +struct flowtable { + struct list_head list; + struct cache_item cache; + struct handle handle; + struct scope scope; + struct location location; + struct hook_spec hook; + struct prio_spec priority; + const char **dev_array; + struct expr *dev_expr; + int dev_array_len; + uint32_t flags; + unsigned int refcnt; +}; + +extern struct flowtable *flowtable_alloc(const struct location *loc); +extern struct flowtable *flowtable_get(struct flowtable *flowtable); +extern void flowtable_free(struct flowtable *flowtable); +extern struct flowtable *flowtable_lookup_fuzzy(const char *ft_name, + const struct nft_cache *cache, + const struct table **table); + +void flowtable_print(const struct flowtable *n, struct output_ctx *octx); + +/** + * enum cmd_ops - command operations + * + * @CMD_INVALID: invalid + * @CMD_ADD: add object (non-exclusive) + * @CMD_REPLACE, replace object + * @CMD_CREATE: create object (exclusive) + * @CMD_INSERT: insert object + * @CMD_DELETE: delete object + * @CMD_GET: get object + * @CMD_LIST: list container + * @CMD_RESET: reset container + * @CMD_FLUSH: flush container + * @CMD_RENAME: rename object + * @CMD_IMPORT: import a ruleset in a given format + * @CMD_EXPORT: export the ruleset in a given format + * @CMD_MONITOR: event listener + * @CMD_DESCRIBE: describe an expression + * @CMD_DESTROY: destroy object + */ +enum cmd_ops { + CMD_INVALID, + CMD_ADD, + CMD_REPLACE, + CMD_CREATE, + CMD_INSERT, + CMD_DELETE, + CMD_GET, + CMD_LIST, + CMD_RESET, + CMD_FLUSH, + CMD_RENAME, + CMD_IMPORT, + CMD_EXPORT, + CMD_MONITOR, + CMD_DESCRIBE, + CMD_DESTROY, +}; + +/** + * enum cmd_obj - command objects + * + * @CMD_OBJ_INVALID: invalid + * @CMD_OBJ_ELEMENTS: set element(s) + * @CMD_OBJ_SET: set + * @CMD_OBJ_SETS: multiple sets + * @CMD_OBJ_SETELEMS: set elements + * @CMD_OBJ_RULE: rule + * @CMD_OBJ_CHAIN: chain + * @CMD_OBJ_CHAINS: multiple chains + * @CMD_OBJ_TABLE: table + * @CMD_OBJ_FLOWTABLE: flowtable + * @CMD_OBJ_FLOWTABLES: flowtables + * @CMD_OBJ_RULESET: ruleset + * @CMD_OBJ_EXPR: expression + * @CMD_OBJ_MONITOR: monitor + * @CMD_OBJ_MARKUP: import/export + * @CMD_OBJ_METER: meter + * @CMD_OBJ_METERS: meters + * @CMD_OBJ_COUNTER: counter + * @CMD_OBJ_COUNTERS: multiple counters + * @CMD_OBJ_QUOTA: quota + * @CMD_OBJ_QUOTAS: multiple quotas + * @CMD_OBJ_LIMIT: limit + * @CMD_OBJ_LIMITS: multiple limits + * @CMD_OBJ_SECMARK: secmark + * @CMD_OBJ_SECMARKS: multiple secmarks + * @CMD_OBJ_SYNPROXY: synproxy + * @CMD_OBJ_SYNPROXYS: multiple synproxys + */ +enum cmd_obj { + CMD_OBJ_INVALID, + CMD_OBJ_ELEMENTS, + CMD_OBJ_SET, + CMD_OBJ_SETELEMS, + CMD_OBJ_SETS, + CMD_OBJ_RULE, + CMD_OBJ_RULES, + CMD_OBJ_CHAIN, + CMD_OBJ_CHAINS, + CMD_OBJ_TABLE, + CMD_OBJ_RULESET, + CMD_OBJ_EXPR, + CMD_OBJ_MONITOR, + CMD_OBJ_MARKUP, + CMD_OBJ_METER, + CMD_OBJ_METERS, + CMD_OBJ_MAP, + CMD_OBJ_MAPS, + CMD_OBJ_COUNTER, + CMD_OBJ_COUNTERS, + CMD_OBJ_QUOTA, + CMD_OBJ_QUOTAS, + CMD_OBJ_CT_HELPER, + CMD_OBJ_CT_HELPERS, + CMD_OBJ_LIMIT, + CMD_OBJ_LIMITS, + CMD_OBJ_FLOWTABLE, + CMD_OBJ_FLOWTABLES, + CMD_OBJ_CT_TIMEOUT, + CMD_OBJ_CT_TIMEOUTS, + CMD_OBJ_SECMARK, + CMD_OBJ_SECMARKS, + CMD_OBJ_CT_EXPECT, + CMD_OBJ_CT_EXPECTATIONS, + CMD_OBJ_SYNPROXY, + CMD_OBJ_SYNPROXYS, + CMD_OBJ_HOOKS, +}; + +struct markup { + uint32_t format; +}; + +struct markup *markup_alloc(uint32_t format); +void markup_free(struct markup *m); + +enum { + CMD_MONITOR_OBJ_ANY, + CMD_MONITOR_OBJ_TABLES, + CMD_MONITOR_OBJ_CHAINS, + CMD_MONITOR_OBJ_RULES, + CMD_MONITOR_OBJ_SETS, + CMD_MONITOR_OBJ_ELEMS, + CMD_MONITOR_OBJ_RULESET, + CMD_MONITOR_OBJ_TRACE, + CMD_MONITOR_OBJ_MAX +}; + +struct monitor { + struct location location; + uint32_t format; + uint32_t flags; + uint32_t type; + const char *event; +}; + +struct monitor *monitor_alloc(uint32_t format, uint32_t type, const char *event); +void monitor_free(struct monitor *m); + +#define NFT_NLATTR_LOC_MAX 32 + +struct nlerr_loc { + uint16_t offset; + const struct location *location; +}; + +/** + * 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 + * @seqnum: sequence number to match netlink errors + * @union: object + * @arg: argument data + */ +struct cmd { + struct list_head list; + struct location location; + enum cmd_ops op; + enum cmd_obj obj; + struct handle handle; + uint32_t seqnum; + struct list_head collapse_list; + union { + void *data; + struct expr *expr; + struct set *set; + struct { + struct expr *expr; /* same offset as cmd->expr */ + struct set *set; + } elem; + struct rule *rule; + struct chain *chain; + struct table *table; + struct flowtable *flowtable; + struct monitor *monitor; + struct markup *markup; + struct obj *object; + }; + struct nlerr_loc *attr; + uint32_t attr_array_len; + uint32_t num_attrs; + const void *arg; +}; + +extern struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj, + const struct handle *h, const struct location *loc, + void *data); +extern struct cmd *cmd_alloc_obj_ct(enum cmd_ops op, int type, + const struct handle *h, + const struct location *loc, struct obj *obj); +extern void cmd_free(struct cmd *cmd); + +#include <payload.h> +#include <expression.h> + +/** + * struct eval_ctx - evaluation context + * + * @nft: nftables context + * @msgs: message queue + * @cmd: current command + * @table: current table + * @rule: current rule + * @set: current set + * @stmt: current statement + * @cache: cache context + * @debug_mask: debugging bitmask + * @ectx: expression context + * @pctx: payload context + */ +struct eval_ctx { + struct nft_ctx *nft; + struct list_head *msgs; + struct cmd *cmd; + struct table *table; + struct rule *rule; + struct set *set; + struct stmt *stmt; + uint32_t stmt_len; + struct expr_ctx ectx; + struct proto_ctx _pctx[2]; + const struct proto_desc *inner_desc; +}; + +extern int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd); + +extern struct error_record *rule_postprocess(struct rule *rule); + +struct netlink_ctx; +extern int do_command(struct netlink_ctx *ctx, struct cmd *cmd); + +struct timeout_protocol { + uint32_t array_size; + const char *const *state_to_name; + uint32_t *dflt_timeout; +}; + +extern struct timeout_protocol timeout_protocol[UINT8_MAX + 1]; +extern int timeout_str2num(uint16_t l4proto, struct timeout_state *ts); + +#endif /* NFTABLES_RULE_H */ |