Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp4377686rwl; Mon, 3 Apr 2023 04:15:30 -0700 (PDT) X-Google-Smtp-Source: AKy350ZJi3F4VWU6Eim8wnxiR8cpnMostSGB5i2QBHQZgL21dyPKHq33efMgmkvBvkp9ID3zvXf3 X-Received: by 2002:aa7:c65a:0:b0:501:c3de:dc5c with SMTP id z26-20020aa7c65a000000b00501c3dedc5cmr32322263edr.18.1680520530671; Mon, 03 Apr 2023 04:15:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680520530; cv=none; d=google.com; s=arc-20160816; b=sEfZ0aW21p15kaG5k69RRk64hgLjcdfVzrM5I+ssG0MSVwMxEhiKBUJyjuXw3n1pYY Dy0dVmOET1BSCdQfsuioQy7oHZANTx2T7x2xhjAtcciRDqLQSkfMfiLbg7n0kAxzU5Ch qhk91Nk9p3tpAc50db2XjrxyBoELxmtlBWXx/WVfLcCznyYVnAhZJ0zTWVee3Vq9t32I 3ofpRAVrDsCktfw4mtacg6r82FujQ37PeOzJeJCIjxjz85TTJVyPtn946CZK5xYEcxYR Jg5FxVW1hEUmAY1xtgzeo5u7oZSOGL38HIO9vA85n09GkVAsH5dYxxVjHhfKPjpGiic8 C32g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=PZLNuzKtLWlgs6Y6X1IWZZsYIByhDy9cqzVY3QztvD8=; b=wPR3+sAfghG0RVAhqM2xm932p4Tfa8C29+Rs8O5Q0HfbjjRjU27dCMF0T2OYoagmMf FVli+Te3Ja87ioTrQQB7fnkY5fsD0rjnqtI921eiW8+fLr5XEGpyWMkMKZ9CHwsT1QW6 p0mbKpRqmdNdbul6l0HkHNr9/B4ug8+OBbaJjTbcnMobIoEMmqeOpCR/aYGBZJ/CqklS hnPzBHjQ9S/UhcomScP6ivdnp8IW/K4uFFk2c0ow2+A/RM7svSV5r07vNcNH68ZgYgZy L4ATXOR06U/dwfJqv2+XiQkpg0SN8Nrf0B00pY6I7XOh9sfNc97pnmygUM1V26DZ1P1e JAmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cloudflare.com header.s=google header.b=jy4FFCj4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cloudflare.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k3-20020a1709063e0300b0092451ed6ef8si4036547eji.932.2023.04.03.04.15.06; Mon, 03 Apr 2023 04:15:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@cloudflare.com header.s=google header.b=jy4FFCj4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cloudflare.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232366AbjDCLN2 (ORCPT + 99 others); Mon, 3 Apr 2023 07:13:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232263AbjDCLNK (ORCPT ); Mon, 3 Apr 2023 07:13:10 -0400 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 521A71A956 for ; Mon, 3 Apr 2023 04:12:40 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id e18so28916519wra.9 for ; Mon, 03 Apr 2023 04:12:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; t=1680520358; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PZLNuzKtLWlgs6Y6X1IWZZsYIByhDy9cqzVY3QztvD8=; b=jy4FFCj4W1GPd4u8mxyCmg4yJi77U4RIvAPJDqPUF6xM2iipbQVCdxInK0RyZQL1jC YNCS9mjeGD+40sd3I2njZqs0B0FrJL+6HH4/5l5Fhu7r3F+yESzWaovZ5i35jvNq/BcZ RMqREAWTYHZX6CDc5Gq7Wv9BzcwemCDUcYkc0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680520358; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PZLNuzKtLWlgs6Y6X1IWZZsYIByhDy9cqzVY3QztvD8=; b=331dqxgaS1XxyidgWUQ+GYoJt71jtnqi8bQ8suVztw1xQYb/Y9tNxbsZlEg0B7lJuu h2cOd29RJWBYfPHxHcM0UyapHhaWG14zWk2Ymn3hFIxq+ITs1zjztd5O5VLKd0m216NT wDuWgghpRnjCqLwmhUlWMXF2k42iz+L4BsUheDOmi8+SRt/MOPp8OQU2NKpAXotVJYkG pXIouLw1L2BZWvmNx3hae8D8Bo1u3aLNV93ydaBvLTzrX2oX18T4gqtnFFSbzsc9FBHE e52YFlBksQSUkGUcb55GjJH9CawUJ9DcoNoyTQalZDr6Oao2sdBmPCIKFdzDCYi4424F Z5/w== X-Gm-Message-State: AAQBX9dwDzDgz8GlZf5Ig8/87UZWi940tRKFqgtPn2GJgbvXIKiZx5YX w91pTp1vQzklbBBD5U7GPZMadQ== X-Received: by 2002:a5d:4ecc:0:b0:2d1:9ce9:2b99 with SMTP id s12-20020a5d4ecc000000b002d19ce92b99mr25187273wrv.18.1680520358383; Mon, 03 Apr 2023 04:12:38 -0700 (PDT) Received: from workstation.ehrig.io (tmo-066-125.customers.d1-online.com. [80.187.66.125]) by smtp.gmail.com with ESMTPSA id y11-20020adffa4b000000b002c7066a6f77sm9505517wrr.31.2023.04.03.04.12.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 04:12:37 -0700 (PDT) From: Christian Ehrig To: bpf@vger.kernel.org Cc: cehrig@cloudflare.com, kernel-team@cloudflare.com, kernel test robot , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH bpf-next v2 2/3] bpf,fou: Add bpf_skb_{set,get}_fou_encap kfuncs Date: Mon, 3 Apr 2023 14:12:08 +0200 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE autolearn=unavailable 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: linux-kernel@vger.kernel.org Add two new kfuncs that allow a BPF tc-hook, installed on an ipip device in collect-metadata mode, to control FOU encap parameters on a per-packet level. The set of kfuncs is registered with the fou module. The bpf_skb_set_fou_encap kfunc is supposed to be used in tandem and after a successful call to the bpf_skb_set_tunnel_key bpf-helper. UDP source and destination ports can be controlled by passing a struct bpf_fou_encap. A source port of zero will auto-assign a source port. enum bpf_fou_encap_type is used to specify if the egress path should FOU or GUE encap the packet. On the ingress path bpf_skb_get_fou_encap can be used to read UDP source and destination ports from the receiver's point of view and allows for packet multiplexing across different destination ports within a single BPF program and ipip device. Reported-by: kernel test robot Link: https://lore.kernel.org/oe-kbuild-all/202304020425.L8MwfV5h-lkp@intel.com/ Signed-off-by: Christian Ehrig --- include/net/fou.h | 2 + net/ipv4/Makefile | 2 +- net/ipv4/fou_bpf.c | 119 ++++++++++++++++++++++++++++++++++++++++++++ net/ipv4/fou_core.c | 5 ++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 net/ipv4/fou_bpf.c diff --git a/include/net/fou.h b/include/net/fou.h index 80f56e275b08..824eb4b231fd 100644 --- a/include/net/fou.h +++ b/include/net/fou.h @@ -17,4 +17,6 @@ int __fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e, int __gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e, u8 *protocol, __be16 *sport, int type); +int register_fou_bpf(void); + #endif diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 880277c9fd07..b18ba8ef93ad 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_IP_MROUTE_COMMON) += ipmr_base.o obj-$(CONFIG_NET_IPIP) += ipip.o gre-y := gre_demux.o -fou-y := fou_core.o fou_nl.o +fou-y := fou_core.o fou_nl.o fou_bpf.o obj-$(CONFIG_NET_FOU) += fou.o obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o diff --git a/net/ipv4/fou_bpf.c b/net/ipv4/fou_bpf.c new file mode 100644 index 000000000000..3760a14b6b57 --- /dev/null +++ b/net/ipv4/fou_bpf.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Unstable Fou Helpers for TC-BPF hook + * + * These are called from SCHED_CLS BPF programs. Note that it is + * allowed to break compatibility for these functions since the interface they + * are exposed through to BPF programs is explicitly unstable. + */ + +#include +#include + +#include +#include + +struct bpf_fou_encap { + __be16 sport; + __be16 dport; +}; + +enum bpf_fou_encap_type { + FOU_BPF_ENCAP_FOU, + FOU_BPF_ENCAP_GUE, +}; + +__diag_push(); +__diag_ignore_all("-Wmissing-prototypes", + "Global functions as their definitions will be in BTF"); + +/* bpf_skb_set_fou_encap - Set FOU encap parameters + * + * This function allows for using GUE or FOU encapsulation together with an + * ipip device in collect-metadata mode. + * + * It is meant to be used in BPF tc-hooks and after a call to the + * bpf_skb_set_tunnel_key helper, responsible for setting IP addresses. + * + * Parameters: + * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL + * @encap Pointer to a `struct bpf_fou_encap` storing UDP src and + * dst ports. If sport is set to 0 the kernel will auto-assign a + * port. This is similar to using `encap-sport auto`. + * Cannot be NULL + * @type Encapsulation type for the packet. Their definitions are + * specified in `enum bpf_fou_encap_type` + */ +__bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx, + struct bpf_fou_encap *encap, int type) +{ + struct sk_buff *skb = (struct sk_buff *)skb_ctx; + struct ip_tunnel_info *info = skb_tunnel_info(skb); + + if (unlikely(!encap)) + return -EINVAL; + + if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) + return -EINVAL; + + switch (type) { + case FOU_BPF_ENCAP_FOU: + info->encap.type = TUNNEL_ENCAP_FOU; + break; + case FOU_BPF_ENCAP_GUE: + info->encap.type = TUNNEL_ENCAP_GUE; + break; + default: + info->encap.type = TUNNEL_ENCAP_NONE; + } + + if (info->key.tun_flags & TUNNEL_CSUM) + info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM; + + info->encap.sport = encap->sport; + info->encap.dport = encap->dport; + + return 0; +} + +/* bpf_skb_get_fou_encap - Get FOU encap parameters + * + * This function allows for reading encap metadata from a packet received + * on an ipip device in collect-metadata mode. + * + * Parameters: + * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL + * @encap Pointer to a struct bpf_fou_encap storing UDP source and + * destination port. Cannot be NULL + */ +__bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx, + struct bpf_fou_encap *encap) +{ + struct sk_buff *skb = (struct sk_buff *)skb_ctx; + struct ip_tunnel_info *info = skb_tunnel_info(skb); + + if (unlikely(!info)) + return -EINVAL; + + encap->sport = info->encap.sport; + encap->dport = info->encap.dport; + + return 0; +} + +__diag_pop() + +BTF_SET8_START(fou_kfunc_set) +BTF_ID_FLAGS(func, bpf_skb_set_fou_encap) +BTF_ID_FLAGS(func, bpf_skb_get_fou_encap) +BTF_SET8_END(fou_kfunc_set) + +static const struct btf_kfunc_id_set fou_bpf_kfunc_set = { + .owner = THIS_MODULE, + .set = &fou_kfunc_set, +}; + +int register_fou_bpf(void) +{ + return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, + &fou_bpf_kfunc_set); +} diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index cafec9b4eee0..0c41076e31ed 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -1236,10 +1236,15 @@ static int __init fou_init(void) if (ret < 0) goto unregister; + ret = register_fou_bpf(); + if (ret < 0) + goto kfunc_failed; + ret = ip_tunnel_encap_add_fou_ops(); if (ret == 0) return 0; +kfunc_failed: genl_unregister_family(&fou_nl_family); unregister: unregister_pernet_device(&fou_net_ops); -- 2.39.2