This patch adds the generic infrastructure is used to describe the transformation from abstract syntax tree to target internal representation. The target has to define the transformation callbacks: struct nft_ast_xfrm_desc { const struct nft_ast_proto_desc *proto_desc; const struct nft_ast_meta_desc *meta_desc; }; The protocol and meta description structure provide the callback to transform internal representation to the corresponding target. struct nft_ast_{proto,meta}_desc { int (*xfrm)(const struct nft_ast_expr *dlexpr, struct nft_ast_xfrm_state *state, void *data); }; Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- include/net/netfilter/nf_tables_jit.h | 39 +++++++++++++++++++ net/netfilter/nf_tables_jit.c | 71 +++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/include/net/netfilter/nf_tables_jit.h b/include/net/netfilter/nf_tables_jit.h index 124d3da91b0d..dff3af7ad420 100644 --- a/include/net/netfilter/nf_tables_jit.h +++ b/include/net/netfilter/nf_tables_jit.h @@ -81,4 +81,43 @@ void nft_ast_stmt_list_print(struct list_head *stmt_list); int nft_delinearize(struct list_head *ast_stmt_list, struct nft_rule *rule); +/* + * Tree of transformation callback definitions. + */ +struct nft_ast_xfrm_state; + +/** + * struct nft_ast_proto_desc - nf_tables protocol transformation description + * + * @xfrm: transformation callback + */ +struct nft_ast_proto_desc { + int (*xfrm)(const struct nft_ast_expr *dlexpr, + struct nft_ast_xfrm_state *state, void *data); +}; + +/** + * struct nft_ast_meta_desc - nf_tables meta transformation description + * + * @xfrm: transformation callback + */ +struct nft_ast_meta_desc { + int (*xfrm)(const struct nft_ast_expr *dlexpr, + struct nft_ast_xfrm_state *state, void *data); +}; + +/** + * struct nft_ast_xfrm_desc - nf_tables generic transformation description + * + * @key: meta key + * @xfrm: transformation callback + */ +struct nft_ast_xfrm_desc { + const struct nft_ast_proto_desc *proto_desc; + const struct nft_ast_meta_desc *meta_desc; +}; + +int nft_ast_xfrm(const struct list_head *ast_stmt_list, + const struct nft_ast_xfrm_desc *base_desc, void *data); + #endif diff --git a/net/netfilter/nf_tables_jit.c b/net/netfilter/nf_tables_jit.c index e971b94bbc69..63673ea42be8 100644 --- a/net/netfilter/nf_tables_jit.c +++ b/net/netfilter/nf_tables_jit.c @@ -134,3 +134,74 @@ void nft_ast_stmt_list_print(struct list_head *stmt_list) } } EXPORT_SYMBOL_GPL(nft_ast_stmt_list_print); + +struct nft_ast_xfrm_state { + const struct nft_ast_xfrm_desc *xfrm_desc; + void *data; +}; + +static int nft_ast_xfrm_relational(const struct nft_ast_expr *dlexpr, + struct nft_ast_xfrm_state *state) +{ + const struct nft_ast_expr *left = dlexpr->relational.left; + const struct nft_ast_expr *right = dlexpr->relational.right; + const struct nft_ast_xfrm_desc *xfrm_desc = state->xfrm_desc; + int err; + + if (right->type != NFT_AST_EXPR_VALUE) + return -EOPNOTSUPP; + + switch (left->type) { + case NFT_AST_EXPR_META: + err = xfrm_desc->meta_desc->xfrm(dlexpr, state, state->data); + break; + case NFT_AST_EXPR_PAYLOAD: + err = xfrm_desc->proto_desc->xfrm(dlexpr, state, state->data); + break; + default: + return -EOPNOTSUPP; + } + + return err; +} + +static int nft_ast_xfrm_expr(const struct nft_ast_expr *dlexpr, + struct nft_ast_xfrm_state *state) +{ + int err; + + switch (dlexpr->type) { + case NFT_AST_EXPR_RELATIONAL: + err = nft_ast_xfrm_relational(dlexpr, state); + break; + default: + return -EOPNOTSUPP; + } + + return err; +} + +int nft_ast_xfrm(const struct list_head *ast_stmt_list, + const struct nft_ast_xfrm_desc *xfrm_desc, void *data) +{ + struct nft_ast_xfrm_state state = { + .xfrm_desc = xfrm_desc, + .data = data, + }; + struct nft_ast_stmt *stmt; + int err = 0; + + list_for_each_entry(stmt, ast_stmt_list, list) { + switch (stmt->type) { + case NFT_AST_STMT_EXPR: + err = nft_ast_xfrm_expr(stmt->expr, &state); + if (err < 0) + return err; + break; + default: + return -EOPNOTSUPP; + } + } + return err; +} +EXPORT_SYMBOL_GPL(nft_ast_xfrm); -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html