From patchwork Wed May 3 12:56:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Sukholitko X-Patchwork-Id: 1776510 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=broadcom.com header.i=@broadcom.com header.a=rsa-sha256 header.s=google header.b=G90H7XjO; dkim-atps=neutral Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by legolas.ozlabs.org (Postfix) with ESMTP id 4QBH642pdwz1ydX for ; Wed, 3 May 2023 22:57:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229793AbjECM5O (ORCPT ); Wed, 3 May 2023 08:57:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57414 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229675AbjECM5O (ORCPT ); Wed, 3 May 2023 08:57:14 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6177140C4 for ; Wed, 3 May 2023 05:57:12 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-2f86ee42669so4943295f8f.2 for ; Wed, 03 May 2023 05:57:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1683118630; x=1685710630; h=mime-version:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=0jtA4SKuXa9FWRRn77Z6/kZv7eFwvZMyeb49r5csUgg=; b=G90H7XjO3GguinJnQfccM+N603SHbE96VZhu7C9RbyLy/PGX4ODOoXiFFUkgBFHGa3 1+gqb6VUxpIkqMxeZpSTjNKY/uElNL8pPTTWBMDEB3W3ChIvQ9aE5TiZzg+HZoMIMkCI P8iw2LTt19/L73K6lBlHVH1V4Fjzy9LAYTkq0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683118630; x=1685710630; h=mime-version:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=0jtA4SKuXa9FWRRn77Z6/kZv7eFwvZMyeb49r5csUgg=; b=D64l/VC4NCMt9NLMDme4l/9ua8DEK5ElMg/fBRGXMI1lxTJ9elq21HhsbLWRppf5kW IteNS8WqMOnfuVP/L2xTWNAyg3drRNCvyfnEOMpxI8P/AfHNtgjfmtHMXhayykCCOYOr zKL73ZZduSZTiLYzDNnqw8YGq2YCplxlAZnlcwJA33q0xtgaqShtsiRKwlsZxVb7G2dd 1SoLviNkZ01lfR/LazslxucTfPR4BrN3Fc+Lw4d2PEzI9RHTQs3MNdvq0WOCG5Psg7NH k6sQoUelBJx0/CNh/70laX52Fxn/NSWWcmFx6ITbV46fbGNVs3pwy+mQLMlJCj0EI+Pp JuSA== X-Gm-Message-State: AC+VfDxSl0oiPBIKqkvazuSU9aeW5mD8GyH3zC7DIBMkhyxUdL5hXLqK 9+CzYbyl1+3LVI2aWIzjE7XUBjZF8zZRxhx2OwV15yAZI+pdNU+9vXWo6tLH3aNoCOge3o5KMJR hZIOZLcSA7U2k0nIvMsBZ8PCoOI2eEqAXohsTnfa8mr8nbaas3c9i6VGSeXGU0t8mK1XRvDCV1W Go6UmgdEnxvpOa0ipbSyR6xQ== X-Google-Smtp-Source: ACHHUZ4cfixRfHjTAJK0HHY3BO+GbnX8XaFiJA/AfNY+KcdMV77ebq9y4nma0ehgPlW9LsILRrSa1Q== X-Received: by 2002:a5d:6606:0:b0:306:772:5c2e with SMTP id n6-20020a5d6606000000b0030607725c2emr9062272wru.70.1683118630546; Wed, 03 May 2023 05:57:10 -0700 (PDT) Received: from localhost.localdomain ([192.19.250.250]) by smtp.gmail.com with ESMTPSA id y11-20020adfe6cb000000b002f81b4227cesm33991436wrm.19.2023.05.03.05.57.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 May 2023 05:57:10 -0700 (PDT) From: Boris Sukholitko To: netfilter-devel@vger.kernel.org Cc: Ilya Lifshits , Boris Sukholitko Subject: [PATCH nft] payload: add offload flag to the statements Date: Wed, 3 May 2023 15:56:54 +0300 Message-Id: <20230503125654.41126-1-boris.sukholitko@broadcom.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MIME_NO_TEXT, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Payload modification statements such as: ip dscp set cs3 are not being executed by the flowtable fast path code the kernel. This commit adds ability to mark such statements for offload to fix this problem. For example the following configuration becomes correct (notice offload in the ip dscp clause): table inet filter { flowtable f1 { hook ingress priority filter devices = { veth0, veth1 } } chain forward { type filter hook forward priority filter; policy accept; ip dscp set cs3 offload ip protocol { tcp, udp, gre } flow add @f1 ct state established,related accept } } Signed-off-by: Boris Sukholitko --- include/linux/netfilter/nf_tables.h | 1 + include/statement.h | 3 ++- src/json.c | 9 ++++++++- src/netlink_delinearize.c | 5 +++-- src/netlink_linearize.c | 8 ++++++-- src/parser_bison.y | 9 ++++++--- src/parser_json.c | 2 +- src/payload.c | 5 ++++- 8 files changed, 31 insertions(+), 11 deletions(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index e4b739d5..ee12a884 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -778,6 +778,7 @@ enum nft_payload_csum_types { enum nft_payload_csum_flags { NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0), + NFT_PAYLOAD_CAN_OFFLOAD = (1 << 1), }; enum nft_inner_type { diff --git a/include/statement.h b/include/statement.h index e648fb13..fa1a048c 100644 --- a/include/statement.h +++ b/include/statement.h @@ -58,10 +58,11 @@ extern struct stmt *exthdr_stmt_alloc(const struct location *loc, struct payload_stmt { struct expr *expr; struct expr *val; + bool can_offload; }; extern struct stmt *payload_stmt_alloc(const struct location *loc, - struct expr *payload, struct expr *expr); + struct expr *payload, struct expr *expr, bool off); #include struct meta_stmt { diff --git a/src/json.c b/src/json.c index f57f2f77..df50962c 100644 --- a/src/json.c +++ b/src/json.c @@ -1163,9 +1163,16 @@ json_t *flow_offload_stmt_json(const struct stmt *stmt, struct output_ctx *octx) json_t *payload_stmt_json(const struct stmt *stmt, struct output_ctx *octx) { - return json_pack("{s: {s:o, s:o}}", "mangle", + json_t *root; + + root = json_pack("{s: {s:o, s:o}}", "mangle", "key", expr_print_json(stmt->payload.expr, octx), "value", expr_print_json(stmt->payload.val, octx)); + + if (stmt->payload.can_offload) + json_object_set_new(root, "offload", json_true()); + + return root; } json_t *exthdr_stmt_json(const struct stmt *stmt, struct output_ctx *octx) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 4cd6cc3a..48e2a520 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -713,13 +713,14 @@ static void netlink_parse_payload_stmt(struct netlink_parse_ctx *ctx, const struct nftnl_expr *nle) { enum nft_registers sreg; - uint32_t base, offset, len; + uint32_t base, offset, len, flags; struct expr *expr, *val; struct stmt *stmt; base = nftnl_expr_get_u32(nle, NFTNL_EXPR_PAYLOAD_BASE) + 1; offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_PAYLOAD_OFFSET) * BITS_PER_BYTE; len = nftnl_expr_get_u32(nle, NFTNL_EXPR_PAYLOAD_LEN) * BITS_PER_BYTE; + flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS); sreg = netlink_parse_register(nle, NFTNL_EXPR_PAYLOAD_SREG); val = netlink_get_register(ctx, loc, sreg); @@ -730,7 +731,7 @@ static void netlink_parse_payload_stmt(struct netlink_parse_ctx *ctx, expr = payload_expr_alloc(loc, NULL, 0); payload_init_raw(expr, base, offset, len); - stmt = payload_stmt_alloc(loc, expr, val); + stmt = payload_stmt_alloc(loc, expr, val, flags & NFT_PAYLOAD_CAN_OFFLOAD); rule_stmt_append(ctx->rule, stmt); } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 3da72f50..82c89b8c 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -1070,12 +1070,15 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx, const struct expr *expr; enum nft_registers sreg; unsigned int csum_off; + uint32_t flags = 0; sreg = get_register(ctx, stmt->payload.val); netlink_gen_expr(ctx, stmt->payload.val, sreg); release_register(ctx, stmt->payload.val); expr = stmt->payload.expr; + if (stmt->payload.can_offload) + flags |= NFT_PAYLOAD_CAN_OFFLOAD; csum_off = 0; desc = expr->payload.desc; @@ -1099,9 +1102,10 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx, if ((expr->payload.base == PROTO_BASE_NETWORK_HDR && desc && payload_needs_l4csum_update_pseudohdr(expr, desc)) || expr->payload.base == PROTO_BASE_INNER_HDR) - nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS, - NFT_PAYLOAD_L4CSUM_PSEUDOHDR); + flags |= NFT_PAYLOAD_L4CSUM_PSEUDOHDR; + if (flags) + nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS, flags); nft_rule_add_expr(ctx, nle, &expr->location); } diff --git a/src/parser_bison.y b/src/parser_bison.y index ccf07a30..8954eb4c 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -726,7 +726,7 @@ int nft_lex(void *, void *, void *); %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc %type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc %destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc -%type nf_nat_flags nf_nat_flag offset_opt +%type nf_nat_flags nf_nat_flag offset_opt set_offload %type tproxy_stmt %destructor { stmt_free($$); } tproxy_stmt %type synproxy_stmt synproxy_stmt_alloc @@ -5325,15 +5325,18 @@ ct_stmt : CT ct_key SET stmt_expr close_scope_ct } ; -payload_stmt : payload_expr SET stmt_expr +payload_stmt : payload_expr SET stmt_expr set_offload { if ($1->etype == EXPR_EXTHDR) $$ = exthdr_stmt_alloc(&@$, $1, $3); else - $$ = payload_stmt_alloc(&@$, $1, $3); + $$ = payload_stmt_alloc(&@$, $1, $3, $4); } ; +set_offload : OFFLOAD { $$ = true; } + | /* empty */ { $$ = false; } + payload_expr : payload_raw_expr | eth_hdr_expr | vlan_hdr_expr diff --git a/src/parser_json.c b/src/parser_json.c index ae683314..270dddeb 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1753,7 +1753,7 @@ static struct stmt *json_parse_mangle_stmt(struct json_ctx *ctx, case EXPR_EXTHDR: return exthdr_stmt_alloc(int_loc, key, value); case EXPR_PAYLOAD: - return payload_stmt_alloc(int_loc, key, value); + return payload_stmt_alloc(int_loc, key, value, false); case EXPR_META: stmt = meta_stmt_alloc(int_loc, key->meta.key, value); expr_free(key); diff --git a/src/payload.c b/src/payload.c index ed76623c..77390e02 100644 --- a/src/payload.c +++ b/src/payload.c @@ -373,6 +373,8 @@ static void payload_stmt_print(const struct stmt *stmt, struct output_ctx *octx) expr_print(stmt->payload.expr, octx); nft_print(octx, " set "); expr_print(stmt->payload.val, octx); + if (stmt->payload.can_offload) + nft_print(octx, " offload"); } static void payload_stmt_destroy(struct stmt *stmt) @@ -390,13 +392,14 @@ static const struct stmt_ops payload_stmt_ops = { }; struct stmt *payload_stmt_alloc(const struct location *loc, - struct expr *expr, struct expr *val) + struct expr *expr, struct expr *val, bool off) { struct stmt *stmt; stmt = stmt_alloc(loc, &payload_stmt_ops); stmt->payload.expr = expr; stmt->payload.val = val; + stmt->payload.can_offload = off; return stmt; }