Merge tag 'leds-next-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds
[sfrench/cifs-2.6.git] / include / net / lwtunnel.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __NET_LWTUNNEL_H
3 #define __NET_LWTUNNEL_H 1
4
5 #include <linux/lwtunnel.h>
6 #include <linux/netdevice.h>
7 #include <linux/skbuff.h>
8 #include <linux/types.h>
9 #include <net/route.h>
10
11 #define LWTUNNEL_HASH_BITS   7
12 #define LWTUNNEL_HASH_SIZE   (1 << LWTUNNEL_HASH_BITS)
13
14 /* lw tunnel state flags */
15 #define LWTUNNEL_STATE_OUTPUT_REDIRECT  BIT(0)
16 #define LWTUNNEL_STATE_INPUT_REDIRECT   BIT(1)
17 #define LWTUNNEL_STATE_XMIT_REDIRECT    BIT(2)
18
19 /* LWTUNNEL_XMIT_CONTINUE should be distinguishable from dst_output return
20  * values (NET_XMIT_xxx and NETDEV_TX_xxx in linux/netdevice.h) for safety.
21  */
22 enum {
23         LWTUNNEL_XMIT_DONE,
24         LWTUNNEL_XMIT_CONTINUE = 0x100,
25 };
26
27
28 struct lwtunnel_state {
29         __u16           type;
30         __u16           flags;
31         __u16           headroom;
32         atomic_t        refcnt;
33         int             (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb);
34         int             (*orig_input)(struct sk_buff *);
35         struct          rcu_head rcu;
36         __u8            data[];
37 };
38
39 struct lwtunnel_encap_ops {
40         int (*build_state)(struct net *net, struct nlattr *encap,
41                            unsigned int family, const void *cfg,
42                            struct lwtunnel_state **ts,
43                            struct netlink_ext_ack *extack);
44         void (*destroy_state)(struct lwtunnel_state *lws);
45         int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
46         int (*input)(struct sk_buff *skb);
47         int (*fill_encap)(struct sk_buff *skb,
48                           struct lwtunnel_state *lwtstate);
49         int (*get_encap_size)(struct lwtunnel_state *lwtstate);
50         int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
51         int (*xmit)(struct sk_buff *skb);
52
53         struct module *owner;
54 };
55
56 #ifdef CONFIG_LWTUNNEL
57
58 DECLARE_STATIC_KEY_FALSE(nf_hooks_lwtunnel_enabled);
59
60 void lwtstate_free(struct lwtunnel_state *lws);
61
62 static inline struct lwtunnel_state *
63 lwtstate_get(struct lwtunnel_state *lws)
64 {
65         if (lws)
66                 atomic_inc(&lws->refcnt);
67
68         return lws;
69 }
70
71 static inline void lwtstate_put(struct lwtunnel_state *lws)
72 {
73         if (!lws)
74                 return;
75
76         if (atomic_dec_and_test(&lws->refcnt))
77                 lwtstate_free(lws);
78 }
79
80 static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
81 {
82         if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT))
83                 return true;
84
85         return false;
86 }
87
88 static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
89 {
90         if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_INPUT_REDIRECT))
91                 return true;
92
93         return false;
94 }
95
96 static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
97 {
98         if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_XMIT_REDIRECT))
99                 return true;
100
101         return false;
102 }
103
104 static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
105                                              unsigned int mtu)
106 {
107         if ((lwtunnel_xmit_redirect(lwtstate) ||
108              lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu)
109                 return lwtstate->headroom;
110
111         return 0;
112 }
113
114 int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
115                            unsigned int num);
116 int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
117                            unsigned int num);
118 int lwtunnel_valid_encap_type(u16 encap_type,
119                               struct netlink_ext_ack *extack);
120 int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
121                                    struct netlink_ext_ack *extack);
122 int lwtunnel_build_state(struct net *net, u16 encap_type,
123                          struct nlattr *encap,
124                          unsigned int family, const void *cfg,
125                          struct lwtunnel_state **lws,
126                          struct netlink_ext_ack *extack);
127 int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
128                         int encap_attr, int encap_type_attr);
129 int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
130 struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
131 int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
132 int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
133 int lwtunnel_input(struct sk_buff *skb);
134 int lwtunnel_xmit(struct sk_buff *skb);
135 int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len,
136                           bool ingress);
137
138 static inline void lwtunnel_set_redirect(struct dst_entry *dst)
139 {
140         if (lwtunnel_output_redirect(dst->lwtstate)) {
141                 dst->lwtstate->orig_output = dst->output;
142                 dst->output = lwtunnel_output;
143         }
144         if (lwtunnel_input_redirect(dst->lwtstate)) {
145                 dst->lwtstate->orig_input = dst->input;
146                 dst->input = lwtunnel_input;
147         }
148 }
149 #else
150
151 static inline void lwtstate_free(struct lwtunnel_state *lws)
152 {
153 }
154
155 static inline struct lwtunnel_state *
156 lwtstate_get(struct lwtunnel_state *lws)
157 {
158         return lws;
159 }
160
161 static inline void lwtstate_put(struct lwtunnel_state *lws)
162 {
163 }
164
165 static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
166 {
167         return false;
168 }
169
170 static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
171 {
172         return false;
173 }
174
175 static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
176 {
177         return false;
178 }
179
180 static inline void lwtunnel_set_redirect(struct dst_entry *dst)
181 {
182 }
183
184 static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
185                                              unsigned int mtu)
186 {
187         return 0;
188 }
189
190 static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
191                                          unsigned int num)
192 {
193         return -EOPNOTSUPP;
194
195 }
196
197 static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
198                                          unsigned int num)
199 {
200         return -EOPNOTSUPP;
201 }
202
203 static inline int lwtunnel_valid_encap_type(u16 encap_type,
204                                             struct netlink_ext_ack *extack)
205 {
206         NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
207         return -EOPNOTSUPP;
208 }
209 static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
210                                                  struct netlink_ext_ack *extack)
211 {
212         /* return 0 since we are not walking attr looking for
213          * RTA_ENCAP_TYPE attribute on nexthops.
214          */
215         return 0;
216 }
217
218 static inline int lwtunnel_build_state(struct net *net, u16 encap_type,
219                                        struct nlattr *encap,
220                                        unsigned int family, const void *cfg,
221                                        struct lwtunnel_state **lws,
222                                        struct netlink_ext_ack *extack)
223 {
224         return -EOPNOTSUPP;
225 }
226
227 static inline int lwtunnel_fill_encap(struct sk_buff *skb,
228                                       struct lwtunnel_state *lwtstate,
229                                       int encap_attr, int encap_type_attr)
230 {
231         return 0;
232 }
233
234 static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate)
235 {
236         return 0;
237 }
238
239 static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len)
240 {
241         return NULL;
242 }
243
244 static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
245                                      struct lwtunnel_state *b)
246 {
247         return 0;
248 }
249
250 static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
251 {
252         return -EOPNOTSUPP;
253 }
254
255 static inline int lwtunnel_input(struct sk_buff *skb)
256 {
257         return -EOPNOTSUPP;
258 }
259
260 static inline int lwtunnel_xmit(struct sk_buff *skb)
261 {
262         return -EOPNOTSUPP;
263 }
264
265 #endif /* CONFIG_LWTUNNEL */
266
267 #define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
268
269 #endif /* __NET_LWTUNNEL_H */