// SPDX-License-Identifier: GPL-2.0-only1/* Unstable Fou Helpers for TC-BPF hook2*3* These are called from SCHED_CLS BPF programs. Note that it is4* allowed to break compatibility for these functions since the interface they5* are exposed through to BPF programs is explicitly unstable.6*/78#include <linux/bpf.h>9#include <linux/btf_ids.h>1011#include <net/dst_metadata.h>12#include <net/fou.h>1314struct bpf_fou_encap {15__be16 sport;16__be16 dport;17};1819enum bpf_fou_encap_type {20FOU_BPF_ENCAP_FOU,21FOU_BPF_ENCAP_GUE,22};2324__bpf_kfunc_start_defs();2526/* bpf_skb_set_fou_encap - Set FOU encap parameters27*28* This function allows for using GUE or FOU encapsulation together with an29* ipip device in collect-metadata mode.30*31* It is meant to be used in BPF tc-hooks and after a call to the32* bpf_skb_set_tunnel_key helper, responsible for setting IP addresses.33*34* Parameters:35* @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL36* @encap Pointer to a `struct bpf_fou_encap` storing UDP src and37* dst ports. If sport is set to 0 the kernel will auto-assign a38* port. This is similar to using `encap-sport auto`.39* Cannot be NULL40* @type Encapsulation type for the packet. Their definitions are41* specified in `enum bpf_fou_encap_type`42*/43__bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,44struct bpf_fou_encap *encap, int type)45{46struct sk_buff *skb = (struct sk_buff *)skb_ctx;47struct ip_tunnel_info *info = skb_tunnel_info(skb);4849if (unlikely(!encap))50return -EINVAL;5152if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX)))53return -EINVAL;5455switch (type) {56case FOU_BPF_ENCAP_FOU:57info->encap.type = TUNNEL_ENCAP_FOU;58break;59case FOU_BPF_ENCAP_GUE:60info->encap.type = TUNNEL_ENCAP_GUE;61break;62default:63info->encap.type = TUNNEL_ENCAP_NONE;64}6566if (test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags))67info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM;6869info->encap.sport = encap->sport;70info->encap.dport = encap->dport;7172return 0;73}7475/* bpf_skb_get_fou_encap - Get FOU encap parameters76*77* This function allows for reading encap metadata from a packet received78* on an ipip device in collect-metadata mode.79*80* Parameters:81* @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL82* @encap Pointer to a struct bpf_fou_encap storing UDP source and83* destination port. Cannot be NULL84*/85__bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,86struct bpf_fou_encap *encap)87{88struct sk_buff *skb = (struct sk_buff *)skb_ctx;89struct ip_tunnel_info *info = skb_tunnel_info(skb);9091if (unlikely(!info))92return -EINVAL;9394encap->sport = info->encap.sport;95encap->dport = info->encap.dport;9697return 0;98}99100__bpf_kfunc_end_defs();101102BTF_KFUNCS_START(fou_kfunc_set)103BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)104BTF_ID_FLAGS(func, bpf_skb_get_fou_encap)105BTF_KFUNCS_END(fou_kfunc_set)106107static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {108.owner = THIS_MODULE,109.set = &fou_kfunc_set,110};111112int register_fou_bpf(void)113{114return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,115&fou_bpf_kfunc_set);116}117118119