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