1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Unstable Fou Helpers for TC-BPF hook
4 * These are called from SCHED_CLS BPF programs. Note that it is
5 * allowed to break compatibility for these functions since the interface they
6 * are exposed through to BPF programs is explicitly unstable.
10 #include <linux/btf_ids.h>
12 #include <net/dst_metadata.h>
15 struct bpf_fou_encap {
20 enum bpf_fou_encap_type {
26 __diag_ignore_all("-Wmissing-prototypes",
27 "Global functions as their definitions will be in BTF");
29 /* bpf_skb_set_fou_encap - Set FOU encap parameters
31 * This function allows for using GUE or FOU encapsulation together with an
32 * ipip device in collect-metadata mode.
34 * It is meant to be used in BPF tc-hooks and after a call to the
35 * bpf_skb_set_tunnel_key helper, responsible for setting IP addresses.
38 * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
39 * @encap Pointer to a `struct bpf_fou_encap` storing UDP src and
40 * dst ports. If sport is set to 0 the kernel will auto-assign a
41 * port. This is similar to using `encap-sport auto`.
43 * @type Encapsulation type for the packet. Their definitions are
44 * specified in `enum bpf_fou_encap_type`
46 __bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
47 struct bpf_fou_encap *encap, int type)
49 struct sk_buff *skb = (struct sk_buff *)skb_ctx;
50 struct ip_tunnel_info *info = skb_tunnel_info(skb);
55 if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX)))
59 case FOU_BPF_ENCAP_FOU:
60 info->encap.type = TUNNEL_ENCAP_FOU;
62 case FOU_BPF_ENCAP_GUE:
63 info->encap.type = TUNNEL_ENCAP_GUE;
66 info->encap.type = TUNNEL_ENCAP_NONE;
69 if (info->key.tun_flags & TUNNEL_CSUM)
70 info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM;
72 info->encap.sport = encap->sport;
73 info->encap.dport = encap->dport;
78 /* bpf_skb_get_fou_encap - Get FOU encap parameters
80 * This function allows for reading encap metadata from a packet received
81 * on an ipip device in collect-metadata mode.
84 * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
85 * @encap Pointer to a struct bpf_fou_encap storing UDP source and
86 * destination port. Cannot be NULL
88 __bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
89 struct bpf_fou_encap *encap)
91 struct sk_buff *skb = (struct sk_buff *)skb_ctx;
92 struct ip_tunnel_info *info = skb_tunnel_info(skb);
97 encap->sport = info->encap.sport;
98 encap->dport = info->encap.dport;
105 BTF_SET8_START(fou_kfunc_set)
106 BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)
107 BTF_ID_FLAGS(func, bpf_skb_get_fou_encap)
108 BTF_SET8_END(fou_kfunc_set)
110 static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {
111 .owner = THIS_MODULE,
112 .set = &fou_kfunc_set,
115 int register_fou_bpf(void)
117 return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,