1// SPDX-License-Identifier: GPL-2.0-only
2/* Unstable Fou Helpers for TC-BPF hook
3 *
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.
7 */
8
9#include <linux/bpf.h>
10#include <linux/btf_ids.h>
11
12#include <net/dst_metadata.h>
13#include <net/fou.h>
14
15struct bpf_fou_encap {
16 __be16 sport;
17 __be16 dport;
18};
19
20enum bpf_fou_encap_type {
21 FOU_BPF_ENCAP_FOU,
22 FOU_BPF_ENCAP_GUE,
23};
24
25__bpf_kfunc_start_defs();
26
27/* bpf_skb_set_fou_encap - Set FOU encap parameters
28 *
29 * This function allows for using GUE or FOU encapsulation together with an
30 * ipip device in collect-metadata mode.
31 *
32 * It is meant to be used in BPF tc-hooks and after a call to the
33 * bpf_skb_set_tunnel_key helper, responsible for setting IP addresses.
34 *
35 * Parameters:
36 * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
37 * @encap Pointer to a `struct bpf_fou_encap` storing UDP src and
38 * dst ports. If sport is set to 0 the kernel will auto-assign a
39 * port. This is similar to using `encap-sport auto`.
40 * Cannot be NULL
41 * @type Encapsulation type for the packet. Their definitions are
42 * specified in `enum bpf_fou_encap_type`
43 */
44__bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
45 struct bpf_fou_encap *encap, int type)
46{
47 struct sk_buff *skb = (struct sk_buff *)skb_ctx;
48 struct ip_tunnel_info *info = skb_tunnel_info(skb);
49
50 if (unlikely(!encap))
51 return -EINVAL;
52
53 if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX)))
54 return -EINVAL;
55
56 switch (type) {
57 case FOU_BPF_ENCAP_FOU:
58 info->encap.type = TUNNEL_ENCAP_FOU;
59 break;
60 case FOU_BPF_ENCAP_GUE:
61 info->encap.type = TUNNEL_ENCAP_GUE;
62 break;
63 default:
64 info->encap.type = TUNNEL_ENCAP_NONE;
65 }
66
67 if (info->key.tun_flags & TUNNEL_CSUM)
68 info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM;
69
70 info->encap.sport = encap->sport;
71 info->encap.dport = encap->dport;
72
73 return 0;
74}
75
76/* bpf_skb_get_fou_encap - Get FOU encap parameters
77 *
78 * This function allows for reading encap metadata from a packet received
79 * on an ipip device in collect-metadata mode.
80 *
81 * Parameters:
82 * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
83 * @encap Pointer to a struct bpf_fou_encap storing UDP source and
84 * destination port. Cannot be NULL
85 */
86__bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
87 struct bpf_fou_encap *encap)
88{
89 struct sk_buff *skb = (struct sk_buff *)skb_ctx;
90 struct ip_tunnel_info *info = skb_tunnel_info(skb);
91
92 if (unlikely(!info))
93 return -EINVAL;
94
95 encap->sport = info->encap.sport;
96 encap->dport = info->encap.dport;
97
98 return 0;
99}
100
101__bpf_kfunc_end_defs();
102
103BTF_KFUNCS_START(fou_kfunc_set)
104BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)
105BTF_ID_FLAGS(func, bpf_skb_get_fou_encap)
106BTF_KFUNCS_END(fou_kfunc_set)
107
108static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {
109 .owner = THIS_MODULE,
110 .set = &fou_kfunc_set,
111};
112
113int register_fou_bpf(void)
114{
115 return register_btf_kfunc_id_set(prog_type: BPF_PROG_TYPE_SCHED_CLS,
116 s: &fou_bpf_kfunc_set);
117}
118

source code of linux/net/ipv4/fou_bpf.c