// 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, }; __bpf_kfunc_start_defs(); /* 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; } __bpf_kfunc_end_defs(); 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); }