From patchwork Sun Apr 22 09:05:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: nevola X-Patchwork-Id: 902586 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="XiXKjfYD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40TNx310FGz9s0t for ; Sun, 22 Apr 2018 19:05:59 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751612AbeDVJF6 (ORCPT ); Sun, 22 Apr 2018 05:05:58 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:37435 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751313AbeDVJF5 (ORCPT ); Sun, 22 Apr 2018 05:05:57 -0400 Received: by mail-wr0-f193.google.com with SMTP id f14-v6so33207407wre.4 for ; Sun, 22 Apr 2018 02:05:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=EEK9XikNqenr6pSQAcJ/fGS0GQYoXeFvEcFw8pkHcxc=; b=XiXKjfYDC7P1HGVK6skzq27Pvaq4qT/cgboIx9b6t/4eqgvcxp8MbT5vI403vYaVUj HUWTQsVdIQTi5pwy/OxIxxAdNjQs8t4cMkttg1mN9aWRZA0kL4RcH27DRK64Ac9bA5e/ cmWTt1keY8g8m84xQa93m5ySFbD/WKGiKZMaoljT5tKBJwFyKRcY7hM44pOqprSvA1DM kDShoo8Iunvqcz3xmoxntwwLzDgBIL8f9sl/ucdVCisQIWnvYCOrJJ4oqZ1ZJeq1WAF5 q4xeL/QaS0mOwL7Dd2aX1wFWQ3H7amQ/WRDb+mSKNgjUUI2r6wUbzZ0NmTslI9U+N+iw dSFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=EEK9XikNqenr6pSQAcJ/fGS0GQYoXeFvEcFw8pkHcxc=; b=HNDyFKJmrGUogLvqBG5BReEvipeIJJkuIoh/Tjgp2VMMcSYtjaX11oAQoXPwscKgBS r5XAVTS7pNOZGyxlVrvGp7OjLSbZCM7wNmEiGKUWtfFlFIaeXz6CKPnt3ppClP8nTo3P lx5BB8tQLLt8P2UalfWfpI5BPGCj5qZHFCKzsIZT5ZfRgM7QezBMMHtQrqZtHgokuGjF ps6fonV7g56nnN5yZgHquUI+jOnE/NKaw96nfZRvpf5alUuW1z5LIl7Z6GjZ1bwUhXU9 Q7ZZPMmEkGA9W6zI4JdQS3xtvDrTSqfGL615Hz5BR365hGzsZsrjaJG0tp+DL7TnvEF0 P1dQ== X-Gm-Message-State: ALQs6tD65CjUF5uEusPVj0VmOJwhnBhQdFGgb+PVn15Khx/4mCVg36Ri v7pybEkG/6BjqQuAPFZj1Qr2Ig== X-Google-Smtp-Source: AIpwx4+8yFvWW3pJAlQ538Rd/evKG9G0GxAmytWCdm0XTktoaFj5i2BlRIX6WozyQHk/FDSf+5jd+g== X-Received: by 2002:adf:b611:: with SMTP id f17-v6mr14247409wre.139.1524387955851; Sun, 22 Apr 2018 02:05:55 -0700 (PDT) Received: from nevthink ([91.126.75.228]) by smtp.gmail.com with ESMTPSA id p33-v6sm13770721wrc.14.2018.04.22.02.05.55 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 22 Apr 2018 02:05:55 -0700 (PDT) Date: Sun, 22 Apr 2018 11:05:53 +0200 From: Laura Garcia Liebana To: netfilter-devel@vger.kernel.org Subject: [PATCH nft] expr: add map lookups for numgen statements Message-ID: <20180422090553.fp3fsilh44evumls@nevthink> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This patch introduces a map as a numgen attribute, which permits to lookup a value based on the numgen result as the key. This approach only supports named maps. Signed-off-by: Laura Garcia Liebana --- include/expression.h | 1 + include/linux/netfilter/nf_tables.h | 4 ++++ include/numgen.h | 2 +- src/expression.c | 3 ++- src/netlink_delinearize.c | 18 ++++++++++++++++-- src/netlink_linearize.c | 8 ++++++++ src/numgen.c | 13 +++++++++++-- src/parser_bison.y | 16 ++++++++++++---- 8 files changed, 55 insertions(+), 10 deletions(-) diff --git a/include/expression.h b/include/expression.h index f0ba6fc..8158579 100644 --- a/include/expression.h +++ b/include/expression.h @@ -309,6 +309,7 @@ struct expr { enum nft_ng_types type; uint32_t mod; uint32_t offset; + struct expr *ng_map; } numgen; struct { /* EXPR_HASH */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 517a39a..8612fe1 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -1382,6 +1382,8 @@ enum nft_trace_types { * @NFTA_NG_MODULUS: maximum counter value (NLA_U32) * @NFTA_NG_TYPE: operation type (NLA_U32) * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32) + * @NFTA_NG_SET_NAME: name of the map to lookup (NLA_STRING) + * @NFTA_NG_SET_ID: if of the map (NLA_U32) */ enum nft_ng_attributes { NFTA_NG_UNSPEC, @@ -1389,6 +1391,8 @@ enum nft_ng_attributes { NFTA_NG_MODULUS, NFTA_NG_TYPE, NFTA_NG_OFFSET, + NFTA_NG_SET_NAME, + NFTA_NG_SET_ID, __NFTA_NG_MAX }; #define NFTA_NG_MAX (__NFTA_NG_MAX - 1) diff --git a/include/numgen.h b/include/numgen.h index b230620..60eaa37 100644 --- a/include/numgen.h +++ b/include/numgen.h @@ -3,6 +3,6 @@ extern struct expr *numgen_expr_alloc(const struct location *loc, enum nft_ng_types type, uint32_t until, - uint32_t offset); + uint32_t offset, struct expr *mappings); #endif /* NFTABLES_NUMGEN_H */ diff --git a/src/expression.c b/src/expression.c index e698b14..53393ec 100644 --- a/src/expression.c +++ b/src/expression.c @@ -945,7 +945,8 @@ static void map_expr_print(const struct expr *expr, struct output_ctx *octx) static void map_expr_clone(struct expr *new, const struct expr *expr) { - new->map = expr_clone(expr->map); + if (expr->map) + new->map = expr_clone(expr->map); new->mappings = expr_clone(expr->mappings); } diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 2126cf2..a270a92 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -668,13 +668,27 @@ static void netlink_parse_numgen(struct netlink_parse_ctx *ctx, { enum nft_registers dreg; uint32_t type, until, offset; - struct expr *expr; + const char *name; + struct expr *expr, *right, *map_expr = NULL; + struct set *map; type = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_TYPE); until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_MODULUS); offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_OFFSET); - expr = numgen_expr_alloc(loc, type, until, offset); + name = nftnl_expr_get_str(nle, NFTNL_EXPR_NG_SET_NAME); + if (name != NULL) { + map = set_lookup(ctx->table, name); + if (map == NULL) { + return netlink_error(ctx, loc, + "Unknown map '%s' in numgen expression", + name); + } + right = set_ref_expr_alloc(loc, map); + map_expr = map_expr_alloc(loc, NULL, right); + } + + expr = numgen_expr_alloc(loc, type, until, offset, map_expr); dreg = netlink_parse_register(nle, NFTNL_EXPR_NG_DREG); netlink_set_register(ctx, dreg, expr); } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 6c49969..6f8fdc7 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -218,6 +218,14 @@ static void netlink_gen_numgen(struct netlink_linearize_ctx *ctx, nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type); nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod); nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_OFFSET, expr->numgen.offset); + + if (expr->numgen.ng_map) { + nftnl_expr_set_str(nle, NFTNL_EXPR_NG_SET_NAME, + expr->numgen.ng_map->mappings->identifier); + nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_SET_ID, + expr->numgen.ng_map->mappings->set->handle.set_id); + } + nftnl_rule_add_expr(ctx->nlr, nle); } diff --git a/src/numgen.c b/src/numgen.c index aa6da49..cf35a407 100644 --- a/src/numgen.c +++ b/src/numgen.c @@ -35,13 +35,18 @@ static void numgen_expr_print(const struct expr *expr, struct output_ctx *octx) expr->numgen.mod); if (expr->numgen.offset) nft_print(octx, " offset %u", expr->numgen.offset); + if (expr->numgen.ng_map) { + nft_print(octx, " "); + expr_print(expr->numgen.ng_map->mappings, octx); + } } static bool numgen_expr_cmp(const struct expr *e1, const struct expr *e2) { return e1->numgen.type == e2->numgen.type && e1->numgen.mod == e2->numgen.mod && - e1->numgen.offset == e2->numgen.offset; + e1->numgen.offset == e2->numgen.offset && + expr_cmp(e1->numgen.ng_map, e2->numgen.ng_map); } static void numgen_expr_clone(struct expr *new, const struct expr *expr) @@ -49,6 +54,8 @@ static void numgen_expr_clone(struct expr *new, const struct expr *expr) new->numgen.type = expr->numgen.type; new->numgen.mod = expr->numgen.mod; new->numgen.offset = expr->numgen.offset; + if (expr->numgen.ng_map) + new->numgen.ng_map = expr_clone(expr->numgen.ng_map); } static const struct expr_ops numgen_expr_ops = { @@ -61,7 +68,7 @@ static const struct expr_ops numgen_expr_ops = { struct expr *numgen_expr_alloc(const struct location *loc, enum nft_ng_types type, uint32_t mod, - uint32_t offset) + uint32_t offset, struct expr *mappings) { struct expr *expr; @@ -70,6 +77,8 @@ struct expr *numgen_expr_alloc(const struct location *loc, expr->numgen.type = type; expr->numgen.mod = mod; expr->numgen.offset = offset; + if (mappings) + expr->numgen.ng_map = mappings; return expr; } diff --git a/src/parser_bison.y b/src/parser_bison.y index f546b9e..4a010e6 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -660,8 +660,8 @@ int nft_lex(void *, void *, void *); %type arp_hdr_expr %destructor { expr_free($$); } arp_hdr_expr %type arp_hdr_field -%type ip_hdr_expr icmp_hdr_expr numgen_expr hash_expr -%destructor { expr_free($$); } ip_hdr_expr icmp_hdr_expr numgen_expr hash_expr +%type ip_hdr_expr icmp_hdr_expr numgen_expr numgen_map_expr hash_expr +%destructor { expr_free($$); } ip_hdr_expr icmp_hdr_expr numgen_expr numgen_map_expr hash_expr %type ip_hdr_field icmp_hdr_field %type ip6_hdr_expr icmp6_hdr_expr %destructor { expr_free($$); } ip6_hdr_expr icmp6_hdr_expr @@ -3509,12 +3509,20 @@ numgen_type : INC { $$ = NFT_NG_INCREMENTAL; } | RANDOM { $$ = NFT_NG_RANDOM; } ; -numgen_expr : NUMGEN numgen_type MOD NUM offset_opt +numgen_map_expr : /* empty */ { $$ = NULL; } + | symbol_expr { - $$ = numgen_expr_alloc(&@$, $2, $4, $5); + $$ = map_expr_alloc(&@$, NULL, $1); + $$->flags |= NFT_SET_OBJECT; } ; +numgen_expr : NUMGEN numgen_type MOD NUM offset_opt numgen_map_expr + { + $$ = numgen_expr_alloc(&@$, $2, $4, $5, $6); + } + ; + hash_expr : JHASH expr MOD NUM SEED NUM offset_opt { $$ = hash_expr_alloc(&@$, $4, true, $6, $7, NFT_HASH_JENKINS);