9p/trans_fd: Annotate data-racy writes to file::f_flags
[platform/kernel/linux-starfive.git] / net / ipv4 / fou_bpf.c
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
15 struct bpf_fou_encap {
16         __be16 sport;
17         __be16 dport;
18 };
19
20 enum bpf_fou_encap_type {
21         FOU_BPF_ENCAP_FOU,
22         FOU_BPF_ENCAP_GUE,
23 };
24
25 __diag_push();
26 __diag_ignore_all("-Wmissing-prototypes",
27                   "Global functions as their definitions will be in BTF");
28
29 /* bpf_skb_set_fou_encap - Set FOU encap parameters
30  *
31  * This function allows for using GUE or FOU encapsulation together with an
32  * ipip device in collect-metadata mode.
33  *
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.
36  *
37  * Parameters:
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`.
42  *              Cannot be NULL
43  * @type        Encapsulation type for the packet. Their definitions are
44  *              specified in `enum bpf_fou_encap_type`
45  */
46 __bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
47                                       struct bpf_fou_encap *encap, int type)
48 {
49         struct sk_buff *skb = (struct sk_buff *)skb_ctx;
50         struct ip_tunnel_info *info = skb_tunnel_info(skb);
51
52         if (unlikely(!encap))
53                 return -EINVAL;
54
55         if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX)))
56                 return -EINVAL;
57
58         switch (type) {
59         case FOU_BPF_ENCAP_FOU:
60                 info->encap.type = TUNNEL_ENCAP_FOU;
61                 break;
62         case FOU_BPF_ENCAP_GUE:
63                 info->encap.type = TUNNEL_ENCAP_GUE;
64                 break;
65         default:
66                 info->encap.type = TUNNEL_ENCAP_NONE;
67         }
68
69         if (info->key.tun_flags & TUNNEL_CSUM)
70                 info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM;
71
72         info->encap.sport = encap->sport;
73         info->encap.dport = encap->dport;
74
75         return 0;
76 }
77
78 /* bpf_skb_get_fou_encap - Get FOU encap parameters
79  *
80  * This function allows for reading encap metadata from a packet received
81  * on an ipip device in collect-metadata mode.
82  *
83  * Parameters:
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
87  */
88 __bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
89                                       struct bpf_fou_encap *encap)
90 {
91         struct sk_buff *skb = (struct sk_buff *)skb_ctx;
92         struct ip_tunnel_info *info = skb_tunnel_info(skb);
93
94         if (unlikely(!info))
95                 return -EINVAL;
96
97         encap->sport = info->encap.sport;
98         encap->dport = info->encap.dport;
99
100         return 0;
101 }
102
103 __diag_pop()
104
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)
109
110 static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {
111         .owner = THIS_MODULE,
112         .set   = &fou_kfunc_set,
113 };
114
115 int register_fou_bpf(void)
116 {
117         return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
118                                          &fou_bpf_kfunc_set);
119 }