diff options
author | Patrick McHardy <kaber@trash.net> | 2015-04-12 20:17:52 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2015-04-14 07:56:51 +0100 |
commit | 5ea54b224a11358b6ae90b519979e09a655292e7 (patch) | |
tree | 69f2668544067e9bb91c78aed54df60abdeea2ba /src/rule.c | |
parent | 242978b5c98c98c125c73ae76abd76e0e672d769 (diff) |
expr: seperate expression parsing and building functions
The expression build function currently assumes to be only used from
rule context and actually builds rule attributes. Fix that and only
build the expression. Also it seems to have been exported by accident,
undo that.
Additionally, move the expression parsing function from rule parsing
and also remove any assumptions about being used in rule context.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'src/rule.c')
-rw-r--r-- | src/rule.c | 57 |
1 files changed, 9 insertions, 48 deletions
@@ -277,7 +277,7 @@ EXPORT_SYMBOL(nft_rule_attr_get_u8); void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *r) { struct nft_rule_expr *expr; - struct nlattr *nest; + struct nlattr *nest, *nest2; if (r->flags & (1 << NFT_RULE_ATTR_TABLE)) mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table); @@ -295,7 +295,9 @@ void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *r) if (!list_empty(&r->expr_list)) { nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS); list_for_each_entry(expr, &r->expr_list, head) { + nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM); nft_rule_expr_build_payload(nlh, expr); + mnl_attr_nest_end(nlh, nest2); } mnl_attr_nest_end(nlh, nest); } @@ -355,61 +357,20 @@ static int nft_rule_parse_attr_cb(const struct nlattr *attr, void *data) return MNL_CB_OK; } -static int nft_rule_parse_expr_cb(const struct nlattr *attr, void *data) -{ - const struct nlattr **tb = data; - int type = mnl_attr_get_type(attr); - - if (mnl_attr_type_valid(attr, NFTA_EXPR_MAX) < 0) - return MNL_CB_OK; - - switch(type) { - case NFTA_EXPR_NAME: - if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) - abi_breakage(); - break; - case NFTA_EXPR_DATA: - if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) - abi_breakage(); - break; - } - - tb[type] = attr; - return MNL_CB_OK; -} - -static int nft_rule_parse_expr2(struct nlattr *attr, struct nft_rule *r) -{ - struct nlattr *tb[NFTA_EXPR_MAX+1] = {}; - struct nft_rule_expr *expr; - - if (mnl_attr_parse_nested(attr, nft_rule_parse_expr_cb, tb) < 0) - return -1; - - expr = nft_rule_expr_alloc(mnl_attr_get_str(tb[NFTA_EXPR_NAME])); - if (expr == NULL) - return -1; - - if (tb[NFTA_EXPR_DATA]) { - if (expr->ops->parse(expr, tb[NFTA_EXPR_DATA]) < 0) { - xfree(expr); - return -1; - } - } - list_add_tail(&expr->head, &r->expr_list); - - return 0; -} - static int nft_rule_parse_expr(struct nlattr *nest, struct nft_rule *r) { + struct nft_rule_expr *expr; struct nlattr *attr; mnl_attr_for_each_nested(attr, nest) { if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM) return -1; - nft_rule_parse_expr2(attr, r); + expr = nft_rule_expr_parse(attr); + if (expr == NULL) + return -1; + + list_add_tail(&expr->head, &r->expr_list); } return 0; } |