| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // 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 <linux/bpf.h>
- #include <linux/btf_ids.h>
- #include <net/dst_metadata.h>
- #include <net/fou.h>
- 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 (test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags))
- 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_KFUNCS_START(fou_kfunc_set)
- BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)
- BTF_ID_FLAGS(func, bpf_skb_get_fou_encap)
- BTF_KFUNCS_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);
- }
|