Branch data 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[0];
34 : : };
35 : :
36 : : struct lwtunnel_encap_ops {
37 : : int (*build_state)(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(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 : 21 : lwtstate_get(struct lwtunnel_state *lws)
151 : : {
152 [ - + ]: 21 : return lws;
153 : : }
154 : :
155 : 168 : static inline void lwtstate_put(struct lwtunnel_state *lws)
156 : : {
157 [ + + ]: 168 : }
158 : :
159 : : static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
160 : : {
161 : : return false;
162 : : }
163 : :
164 : 0 : static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
165 : : {
166 : 0 : return false;
167 : : }
168 : :
169 : 0 : static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
170 : : {
171 : 0 : return false;
172 : : }
173 : :
174 : 63 : static inline void lwtunnel_set_redirect(struct dst_entry *dst)
175 : : {
176 : 63 : }
177 : :
178 : 0 : static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
179 : : unsigned int mtu)
180 : : {
181 [ # # ]: 0 : return 0;
182 : : }
183 : :
184 : 21 : static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
185 : : unsigned int num)
186 : : {
187 : 21 : 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(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 : 63 : static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
239 : : struct lwtunnel_state *b)
240 : : {
241 [ + - ]: 63 : 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 */
|