* [PATCH] Add support for negated lookup operator @ 2014-07-17 15:17 Yuxuan Shui 2014-07-17 15:17 ` [PATCH] nftables: Add a flags attribute for " Yuxuan Shui ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Yuxuan Shui @ 2014-07-17 15:17 UTC (permalink / raw) To: netfilter-devel; +Cc: pablo, tomasz.bursztyka Following patches add support for negated lookup operator, and use it to fix bug #888 kernel: nftables: Add a flags attribute for lookup operator libnftnl: lookup: Add support for the flag attribute nftables: expr: Interpret OP_NEQ against a set as OP_LOOKUP ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] nftables: Add a flags attribute for lookup operator 2014-07-17 15:17 [PATCH] Add support for negated lookup operator Yuxuan Shui @ 2014-07-17 15:17 ` Yuxuan Shui 2014-07-17 15:17 ` [libnftnl PATCH] lookup: Add support for the flag attribute Yuxuan Shui 2014-07-17 15:17 ` [nftables PATCH] expr: Interpret OP_NEQ against a set as OP_LOOKUP Yuxuan Shui 2 siblings, 0 replies; 6+ messages in thread From: Yuxuan Shui @ 2014-07-17 15:17 UTC (permalink / raw) To: netfilter-devel; +Cc: pablo, tomasz.bursztyka, Yuxuan Shui So that we could modify the behaviour of the lookup operator using flags. The only flag available now is a negation flag which negates the result of lookup operation. v2: Rename the flags, reorder members in struct nft_lookup, check for invaild flags. v3: Fix checking for invaild flags. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com> --- include/uapi/linux/netfilter/nf_tables.h | 10 ++++++++++ net/netfilter/nft_lookup.c | 22 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index d41880f..9e6617e 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -479,6 +479,15 @@ enum nft_cmp_attributes { #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) /** + * enum nft_lookup_flags - flags for nft_lookup operator + * + * @NFT_LOOKUP_FLAG_NEGATE: negate the result + */ +enum nft_lookup_flags { + NFT_LOOKUP_F_NEG = 1, +}; + +/** * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes * * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING) @@ -490,6 +499,7 @@ enum nft_lookup_attributes { NFTA_LOOKUP_SET, NFTA_LOOKUP_SREG, NFTA_LOOKUP_DREG, + NFTA_LOOKUP_FLAG, __NFTA_LOOKUP_MAX }; #define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1) diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index 7fd2bea..0702f73 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -22,6 +22,8 @@ struct nft_lookup { struct nft_set *set; enum nft_registers sreg:8; enum nft_registers dreg:8; + s8 match_verdict; + s8 no_match_verdict; struct nft_set_binding binding; }; @@ -32,15 +34,18 @@ static void nft_lookup_eval(const struct nft_expr *expr, const struct nft_lookup *priv = nft_expr_priv(expr); const struct nft_set *set = priv->set; - if (set->ops->lookup(set, &data[priv->sreg], &data[priv->dreg])) + if (set->ops->lookup(set, &data[priv->sreg], &data[priv->dreg])) { + data[NFT_REG_VERDICT].verdict = priv->match_verdict; return; - data[NFT_REG_VERDICT].verdict = NFT_BREAK; + } + data[NFT_REG_VERDICT].verdict = priv->no_match_verdict; } static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = { [NFTA_LOOKUP_SET] = { .type = NLA_STRING }, [NFTA_LOOKUP_SREG] = { .type = NLA_U32 }, [NFTA_LOOKUP_DREG] = { .type = NLA_U32 }, + [NFTA_LOOKUP_FLAG] = { .type = NLA_U32 }, }; static int nft_lookup_init(const struct nft_ctx *ctx, @@ -49,12 +54,23 @@ static int nft_lookup_init(const struct nft_ctx *ctx, { struct nft_lookup *priv = nft_expr_priv(expr); struct nft_set *set; - int err; + int err, flags; if (tb[NFTA_LOOKUP_SET] == NULL || tb[NFTA_LOOKUP_SREG] == NULL) return -EINVAL; + priv->match_verdict = NFT_CONTINUE; + priv->no_match_verdict = NFT_BREAK; + + flags = ntohl(nla_get_be32(tb[NFTA_LOOKUP_FLAG])); + if (flags & ~NFT_LOOKUP_F_NEG) + return -EINVAL; + if (flags & NFT_LOOKUP_F_NEG) { + priv->match_verdict = NFT_BREAK; + priv->no_match_verdict = NFT_CONTINUE; + } + set = nf_tables_set_lookup(ctx->table, tb[NFTA_LOOKUP_SET]); if (IS_ERR(set)) return PTR_ERR(set); -- 2.0.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [libnftnl PATCH] lookup: Add support for the flag attribute 2014-07-17 15:17 [PATCH] Add support for negated lookup operator Yuxuan Shui 2014-07-17 15:17 ` [PATCH] nftables: Add a flags attribute for " Yuxuan Shui @ 2014-07-17 15:17 ` Yuxuan Shui 2014-07-17 15:40 ` Pablo Neira Ayuso 2014-07-17 15:17 ` [nftables PATCH] expr: Interpret OP_NEQ against a set as OP_LOOKUP Yuxuan Shui 2 siblings, 1 reply; 6+ messages in thread From: Yuxuan Shui @ 2014-07-17 15:17 UTC (permalink / raw) To: netfilter-devel; +Cc: pablo, tomasz.bursztyka, Yuxuan Shui Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com> --- include/libnftnl/expr.h | 1 + include/linux/netfilter/nf_tables.h | 10 +++++++++ src/expr/lookup.c | 44 +++++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h index cfa5c66..e3c045b 100644 --- a/include/libnftnl/expr.h +++ b/include/libnftnl/expr.h @@ -107,6 +107,7 @@ enum { NFT_EXPR_LOOKUP_DREG, NFT_EXPR_LOOKUP_SET, NFT_EXPR_LOOKUP_SET_ID, + NFT_EXPR_LOOKUP_FLAG, }; enum { diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index cea17d4..008022c 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -483,6 +483,15 @@ enum nft_cmp_attributes { #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) /** + * enum nft_lookup_flags - flags for nft_lookup operator + * + * @NFT_LOOKUP_FLAG_NEGATE: negate the result + */ +enum nft_lookup_flags { + NFT_LOOKUP_F_NEG = 1, +}; + +/** * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes * * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING) @@ -496,6 +505,7 @@ enum nft_lookup_attributes { NFTA_LOOKUP_SREG, NFTA_LOOKUP_DREG, NFTA_LOOKUP_SET_ID, + NFTA_LOOKUP_FLAG, __NFTA_LOOKUP_MAX }; #define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1) diff --git a/src/expr/lookup.c b/src/expr/lookup.c index 3f77228..ba0df64 100644 --- a/src/expr/lookup.c +++ b/src/expr/lookup.c @@ -32,6 +32,7 @@ struct nft_expr_lookup { enum nft_registers dreg; char set_name[IFNAMSIZ]; uint32_t set_id; + uint32_t flag; }; static int @@ -54,6 +55,9 @@ nft_rule_expr_lookup_set(struct nft_rule_expr *e, uint16_t type, case NFT_EXPR_LOOKUP_SET_ID: lookup->set_id = *((uint32_t *)data); break; + case NFT_EXPR_LOOKUP_FLAG: + lookup->flag = *((uint32_t *)data); + break; default: return -1; } @@ -77,6 +81,8 @@ nft_rule_expr_lookup_get(const struct nft_rule_expr *e, uint16_t type, return lookup->set_name; case NFT_EXPR_LOOKUP_SET_ID: return &lookup->set_id; + case NFT_EXPR_LOOKUP_FLAG: + return &lookup->flag; } return NULL; } @@ -104,6 +110,12 @@ static int nft_rule_expr_lookup_cb(const struct nlattr *attr, void *data) return MNL_CB_ERROR; } break; + case NFTA_LOOKUP_FLAG: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { + perror("mnl_attr_validate"); + return MNL_CB_ERROR; + } + break; } tb[type] = attr; @@ -121,6 +133,8 @@ nft_rule_expr_lookup_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) mnl_attr_put_u32(nlh, NFTA_LOOKUP_DREG, htonl(lookup->dreg)); if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) mnl_attr_put_strz(nlh, NFTA_LOOKUP_SET, lookup->set_name); + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAG)) + mnl_attr_put_u32(nlh, NFTA_LOOKUP_FLAG, htonl(lookup->flag)); if (e->flags & (1 << NFT_EXPR_LOOKUP_SET_ID)) { mnl_attr_put_u32(nlh, NFTA_LOOKUP_SET_ID, htonl(lookup->set_id)); @@ -154,6 +168,11 @@ nft_rule_expr_lookup_parse(struct nft_rule_expr *e, struct nlattr *attr) ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID])); e->flags |= (1 << NFT_EXPR_LOOKUP_SET_ID); } + if (tb[NFTA_LOOKUP_FLAG]) { + lookup->flag = + ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_FLAG])); + e->flags |= (1 << NFT_EXPR_LOOKUP_FLAG); + } return ret; } @@ -164,7 +183,7 @@ nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root, { #ifdef JSON_PARSING const char *set_name; - uint32_t sreg, dreg; + uint32_t sreg, dreg, flag; set_name = nft_jansson_parse_str(root, "set", err); if (set_name != NULL) @@ -176,6 +195,9 @@ nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root, if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &dreg, err) == 0) nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, dreg); + if (nft_jansson_parse_val(root, "flag", NFT_TYPE_U32, &flag, err) == 0) + nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_FLAG, flag); + return 0; #else errno = EOPNOTSUPP; @@ -189,7 +211,7 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, { #ifdef XML_PARSING const char *set_name; - uint32_t sreg, dreg; + uint32_t sreg, dreg, flag; set_name = nft_mxml_str_parse(tree, "set", MXML_DESCEND_FIRST, NFT_XML_MAND, err); @@ -204,6 +226,10 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, err) == 0) nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, dreg); + if (nft_mxml_num_parse(root, "flag", MXML_DESCEND, 10, &flag, + NFT_TYPE_U32, NFT_XML_OPT, err) == 0) { + nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_FLAG, flag); + return 0; #else errno = EOPNOTSUPP; @@ -230,6 +256,10 @@ nft_rule_expr_lookup_snprintf_json(char *buf, size_t size, ret = snprintf(buf + offset, len, "\"dreg\":%u,", l->dreg); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAG)) { + ret = snprintf(buf + offset, len, "\"flag\":%u,", l->flag); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } /* Remove the last comma characther */ if (offset > 0) offset--; @@ -257,6 +287,11 @@ nft_rule_expr_lookup_snprintf_xml(char *buf, size_t size, SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAG)) { + ret = snprintf(buf + offset, len, "<flag>%u</flag>", l->flag); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + return offset; } @@ -276,6 +311,11 @@ nft_rule_expr_lookup_snprintf_default(char *buf, size_t size, SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAG)) { + ret = snprintf(buf+offset, len, "flag %u", l->flag); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + return offset; } -- 2.0.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [libnftnl PATCH] lookup: Add support for the flag attribute 2014-07-17 15:17 ` [libnftnl PATCH] lookup: Add support for the flag attribute Yuxuan Shui @ 2014-07-17 15:40 ` Pablo Neira Ayuso 0 siblings, 0 replies; 6+ messages in thread From: Pablo Neira Ayuso @ 2014-07-17 15:40 UTC (permalink / raw) To: Yuxuan Shui; +Cc: netfilter-devel, tomasz.bursztyka On Thu, Jul 17, 2014 at 11:17:29PM +0800, Yuxuan Shui wrote: > Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com> > --- > include/libnftnl/expr.h | 1 + > include/linux/netfilter/nf_tables.h | 10 +++++++++ > src/expr/lookup.c | 44 +++++++++++++++++++++++++++++++++++-- > 3 files changed, 53 insertions(+), 2 deletions(-) > > diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h > index cfa5c66..e3c045b 100644 > --- a/include/libnftnl/expr.h > +++ b/include/libnftnl/expr.h > @@ -107,6 +107,7 @@ enum { > NFT_EXPR_LOOKUP_DREG, > NFT_EXPR_LOOKUP_SET, > NFT_EXPR_LOOKUP_SET_ID, > + NFT_EXPR_LOOKUP_FLAG, I didn't notice so far, please rename this to NFT_EXPR_LOOKUP_FLAGS. Thanks. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [nftables PATCH] expr: Interpret OP_NEQ against a set as OP_LOOKUP 2014-07-17 15:17 [PATCH] Add support for negated lookup operator Yuxuan Shui 2014-07-17 15:17 ` [PATCH] nftables: Add a flags attribute for " Yuxuan Shui 2014-07-17 15:17 ` [libnftnl PATCH] lookup: Add support for the flag attribute Yuxuan Shui @ 2014-07-17 15:17 ` Yuxuan Shui 2 siblings, 0 replies; 6+ messages in thread From: Yuxuan Shui @ 2014-07-17 15:17 UTC (permalink / raw) To: netfilter-devel; +Cc: pablo, tomasz.bursztyka, Yuxuan Shui Fixes bug 888. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com> --- include/linux/netfilter/nf_tables.h | 9 +++++++++ src/evaluate.c | 12 ++++++++++++ src/netlink_delinearize.c | 7 +++++++ src/netlink_linearize.c | 5 +++++ 4 files changed, 33 insertions(+) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index dfdb251..3177b77 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -449,6 +449,15 @@ enum nft_cmp_attributes { #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) /** + * enum nft_lookup_flags - flags for nft_lookup operator + * + * @NFT_LOOKUP_FLAG_NEGATE: negate the result + */ +enum nft_lookup_flags { + NFT_LOOKUP_F_NEG = 1, +}; + +/** * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes * * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING) diff --git a/src/evaluate.c b/src/evaluate.c index e05473a..a0af0f7 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -972,6 +972,18 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) if (byteorder_conversion(ctx, &rel->right, left->byteorder) < 0) return -1; break; + case EXPR_SET: + assert(rel->op == OP_NEQ); + right = rel->right = + implicit_set_declaration(ctx, left->dtype, left->len, right); + if (right->set->flags & SET_F_INTERVAL && + byteorder_conversion(ctx, &rel->left, + BYTEORDER_BIG_ENDIAN) < 0) + return -1; + break; + case EXPR_SET_REF: + assert(rel->op == OP_NEQ); + break; default: BUG("invalid expression type %s\n", right->ops->name); } diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 5c6ca80..46e0ab6 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -160,6 +160,7 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx, struct expr *expr, *left, *right; struct set *set; enum nft_registers dreg; + uint32_t flag; left = netlink_get_register(ctx, loc, nft_rule_expr_get_u32(nle, NFT_EXPR_LOOKUP_SREG)); @@ -185,6 +186,12 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx, expr = relational_expr_alloc(loc, OP_LOOKUP, left, right); } + if (nft_rule_expr_is_set(nle, NFT_EXPR_LOOKUP_FLAG)) { + flag = nft_rule_expr_get_u32(nle, NFT_EXPR_LOOKUP_FLAG); + if (flag & NFT_LOOKUP_F_NEG) + expr->op = OP_NEQ; + } + stmt = expr_stmt_alloc(loc, expr); list_add_tail(&stmt->list, &ctx->rule->stmts); } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 5c1b46d..49e705b 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -157,6 +157,8 @@ static void netlink_gen_lookup(struct netlink_linearize_ctx *ctx, expr->right->set->handle.set); nft_rule_expr_set_u32(nle, NFT_EXPR_LOOKUP_SET_ID, expr->right->set->handle.set_id); + if (expr->op == OP_NEQ) + nft_rule_expr_set_u32(nle, NFT_EXPR_LOOKUP_FLAG, NFT_LOOKUP_F_NEG); release_register(ctx); nft_rule_add_expr(ctx->nlr, nle); @@ -225,6 +227,9 @@ static void netlink_gen_cmp(struct netlink_linearize_ctx *ctx, } case EXPR_RANGE: return netlink_gen_range(ctx, expr, dreg); + case EXPR_SET: + case EXPR_SET_REF: + return netlink_gen_lookup(ctx, expr, dreg); default: right = expr->right; } -- 2.0.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] nftables: Add a flags attribute for lookup operator @ 2014-07-31 16:40 Yuxuan Shui 2014-07-31 16:40 ` [libnftnl PATCH] lookup: Add support for the flag attribute Yuxuan Shui 0 siblings, 1 reply; 6+ messages in thread From: Yuxuan Shui @ 2014-07-31 16:40 UTC (permalink / raw) To: pablo; +Cc: tomasz.bursztyka, netfilter-devel, Yuxuan Shui So that we could modify the behaviour of the lookup operator using flags. The only flag available now is a negation flag which negates the result of lookup operation. v2: Rename the flags, reorder members in struct nft_lookup, check for invaild flags. v3: Fix checking for invaild flags. v4: Fix macro naming. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com> --- include/uapi/linux/netfilter/nf_tables.h | 10 ++++++++++ net/netfilter/nft_lookup.c | 22 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index d41880f..9e6617e 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -479,6 +479,15 @@ enum nft_cmp_attributes { #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) /** + * enum nft_lookup_flags - flags for nft_lookup operator + * + * @NFT_LOOKUP_F_NEG: negate the result + */ +enum nft_lookup_flags { + NFT_LOOKUP_F_NEG = 1, +}; + +/** * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes * * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING) @@ -490,6 +499,7 @@ enum nft_lookup_attributes { NFTA_LOOKUP_SET, NFTA_LOOKUP_SREG, NFTA_LOOKUP_DREG, + NFTA_LOOKUP_FLAGS, __NFTA_LOOKUP_MAX }; #define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1) diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index 7fd2bea..0702f73 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -22,6 +22,8 @@ struct nft_lookup { struct nft_set *set; enum nft_registers sreg:8; enum nft_registers dreg:8; + s8 match_verdict; + s8 no_match_verdict; struct nft_set_binding binding; }; @@ -32,15 +34,18 @@ static void nft_lookup_eval(const struct nft_expr *expr, const struct nft_lookup *priv = nft_expr_priv(expr); const struct nft_set *set = priv->set; - if (set->ops->lookup(set, &data[priv->sreg], &data[priv->dreg])) + if (set->ops->lookup(set, &data[priv->sreg], &data[priv->dreg])) { + data[NFT_REG_VERDICT].verdict = priv->match_verdict; return; - data[NFT_REG_VERDICT].verdict = NFT_BREAK; + } + data[NFT_REG_VERDICT].verdict = priv->no_match_verdict; } static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = { [NFTA_LOOKUP_SET] = { .type = NLA_STRING }, [NFTA_LOOKUP_SREG] = { .type = NLA_U32 }, [NFTA_LOOKUP_DREG] = { .type = NLA_U32 }, + [NFTA_LOOKUP_FLAGS] = { .type = NLA_U32 }, }; static int nft_lookup_init(const struct nft_ctx *ctx, @@ -49,12 +54,23 @@ static int nft_lookup_init(const struct nft_ctx *ctx, { struct nft_lookup *priv = nft_expr_priv(expr); struct nft_set *set; - int err; + int err, flags; if (tb[NFTA_LOOKUP_SET] == NULL || tb[NFTA_LOOKUP_SREG] == NULL) return -EINVAL; + priv->match_verdict = NFT_CONTINUE; + priv->no_match_verdict = NFT_BREAK; + + flags = ntohl(nla_get_be32(tb[NFTA_LOOKUP_FLAGS])); + if (flags & ~NFT_LOOKUP_F_NEG) + return -EINVAL; + if (flags & NFT_LOOKUP_F_NEG) { + priv->match_verdict = NFT_BREAK; + priv->no_match_verdict = NFT_CONTINUE; + } + set = nf_tables_set_lookup(ctx->table, tb[NFTA_LOOKUP_SET]); if (IS_ERR(set)) return PTR_ERR(set); -- 2.0.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [libnftnl PATCH] lookup: Add support for the flag attribute 2014-07-31 16:40 [PATCH] nftables: Add a flags attribute for lookup operator Yuxuan Shui @ 2014-07-31 16:40 ` Yuxuan Shui 0 siblings, 0 replies; 6+ messages in thread From: Yuxuan Shui @ 2014-07-31 16:40 UTC (permalink / raw) To: pablo; +Cc: tomasz.bursztyka, netfilter-devel, Yuxuan Shui v2: Fix macro naming. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com> --- include/libnftnl/expr.h | 1 + include/linux/netfilter/nf_tables.h | 10 +++++++++ src/expr/lookup.c | 44 +++++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h index cfa5c66..e3c045b 100644 --- a/include/libnftnl/expr.h +++ b/include/libnftnl/expr.h @@ -107,6 +107,7 @@ enum { NFT_EXPR_LOOKUP_DREG, NFT_EXPR_LOOKUP_SET, NFT_EXPR_LOOKUP_SET_ID, + NFT_EXPR_LOOKUP_FLAGS, }; enum { diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index cea17d4..008022c 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -483,6 +483,15 @@ enum nft_cmp_attributes { #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1) /** + * enum nft_lookup_flags - flags for nft_lookup operator + * + * @NFT_LOOKUP_F_NEG: negate the result + */ +enum nft_lookup_flags { + NFT_LOOKUP_F_NEG = 1, +}; + +/** * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes * * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING) @@ -496,6 +505,7 @@ enum nft_lookup_attributes { NFTA_LOOKUP_SREG, NFTA_LOOKUP_DREG, NFTA_LOOKUP_SET_ID, + NFTA_LOOKUP_FLAGS, __NFTA_LOOKUP_MAX }; #define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1) diff --git a/src/expr/lookup.c b/src/expr/lookup.c index 3f77228..ba0df64 100644 --- a/src/expr/lookup.c +++ b/src/expr/lookup.c @@ -32,6 +32,7 @@ struct nft_expr_lookup { enum nft_registers dreg; char set_name[IFNAMSIZ]; uint32_t set_id; + uint32_t flags; }; static int @@ -54,6 +55,9 @@ nft_rule_expr_lookup_set(struct nft_rule_expr *e, uint16_t type, case NFT_EXPR_LOOKUP_SET_ID: lookup->set_id = *((uint32_t *)data); break; + case NFT_EXPR_LOOKUP_FLAGS: + lookup->flags = *((uint32_t *)data); + break; default: return -1; } @@ -77,6 +81,8 @@ nft_rule_expr_lookup_get(const struct nft_rule_expr *e, uint16_t type, return lookup->set_name; case NFT_EXPR_LOOKUP_SET_ID: return &lookup->set_id; + case NFT_EXPR_LOOKUP_FLAGS: + return &lookup->flags; } return NULL; } @@ -104,6 +110,12 @@ static int nft_rule_expr_lookup_cb(const struct nlattr *attr, void *data) return MNL_CB_ERROR; } break; + case NFTA_LOOKUP_FLAGS: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) { + perror("mnl_attr_validate"); + return MNL_CB_ERROR; + } + break; } tb[type] = attr; @@ -121,6 +133,8 @@ nft_rule_expr_lookup_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) mnl_attr_put_u32(nlh, NFTA_LOOKUP_DREG, htonl(lookup->dreg)); if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) mnl_attr_put_strz(nlh, NFTA_LOOKUP_SET, lookup->set_name); + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAGS)) + mnl_attr_put_u32(nlh, NFTA_LOOKUP_FLAGS, htonl(lookup->flags)); if (e->flags & (1 << NFT_EXPR_LOOKUP_SET_ID)) { mnl_attr_put_u32(nlh, NFTA_LOOKUP_SET_ID, htonl(lookup->set_id)); @@ -154,6 +168,11 @@ nft_rule_expr_lookup_parse(struct nft_rule_expr *e, struct nlattr *attr) ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID])); e->flags |= (1 << NFT_EXPR_LOOKUP_SET_ID); } + if (tb[NFTA_LOOKUP_FLAGS]) { + lookup->flags = + ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_FLAGS])); + e->flags |= (1 << NFT_EXPR_LOOKUP_FLAGS); + } return ret; } @@ -164,7 +183,7 @@ nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root, { #ifdef JSON_PARSING const char *set_name; - uint32_t sreg, dreg; + uint32_t sreg, dreg, flags; set_name = nft_jansson_parse_str(root, "set", err); if (set_name != NULL) @@ -176,6 +195,9 @@ nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root, if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &dreg, err) == 0) nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, dreg); + if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &flags, err) == 0) + nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_FLAGS, flags); + return 0; #else errno = EOPNOTSUPP; @@ -189,7 +211,7 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, { #ifdef XML_PARSING const char *set_name; - uint32_t sreg, dreg; + uint32_t sreg, dreg, flags; set_name = nft_mxml_str_parse(tree, "set", MXML_DESCEND_FIRST, NFT_XML_MAND, err); @@ -204,6 +226,10 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, err) == 0) nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, dreg); + if (nft_mxml_num_parse(root, "flags", MXML_DESCEND, 10, &flags, + NFT_TYPE_U32, NFT_XML_OPT, err) == 0) { + nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_FLAGS, flags); + return 0; #else errno = EOPNOTSUPP; @@ -230,6 +256,10 @@ nft_rule_expr_lookup_snprintf_json(char *buf, size_t size, ret = snprintf(buf + offset, len, "\"dreg\":%u,", l->dreg); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAGS)) { + ret = snprintf(buf + offset, len, "\"flags\":%u,", l->flags); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } /* Remove the last comma characther */ if (offset > 0) offset--; @@ -257,6 +287,11 @@ nft_rule_expr_lookup_snprintf_xml(char *buf, size_t size, SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAGS)) { + ret = snprintf(buf + offset, len, "<flags>%u</flags>", l->flags); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + return offset; } @@ -276,6 +311,11 @@ nft_rule_expr_lookup_snprintf_default(char *buf, size_t size, SNPRINTF_BUFFER_SIZE(ret, size, len, offset); } + if (e->flags & (1 << NFT_EXPR_LOOKUP_FLAGS)) { + ret = snprintf(buf+offset, len, "flags %u", l->flags); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + return offset; } -- 2.0.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-07-31 16:40 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-17 15:17 [PATCH] Add support for negated lookup operator Yuxuan Shui 2014-07-17 15:17 ` [PATCH] nftables: Add a flags attribute for " Yuxuan Shui 2014-07-17 15:17 ` [libnftnl PATCH] lookup: Add support for the flag attribute Yuxuan Shui 2014-07-17 15:40 ` Pablo Neira Ayuso 2014-07-17 15:17 ` [nftables PATCH] expr: Interpret OP_NEQ against a set as OP_LOOKUP Yuxuan Shui -- strict thread matches above, loose matches on Subject: below -- 2014-07-31 16:40 [PATCH] nftables: Add a flags attribute for lookup operator Yuxuan Shui 2014-07-31 16:40 ` [libnftnl PATCH] lookup: Add support for the flag attribute Yuxuan Shui
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).