diff options
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; } |