1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2016, Amir Vadai <amir@vadai.me>
4 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
5 */
6
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/skbuff.h>
11#include <linux/rtnetlink.h>
12#include <net/geneve.h>
13#include <net/vxlan.h>
14#include <net/erspan.h>
15#include <net/netlink.h>
16#include <net/pkt_sched.h>
17#include <net/dst.h>
18#include <net/pkt_cls.h>
19#include <net/tc_wrapper.h>
20
21#include <linux/tc_act/tc_tunnel_key.h>
22#include <net/tc_act/tc_tunnel_key.h>
23
24static struct tc_action_ops act_tunnel_key_ops;
25
26TC_INDIRECT_SCOPE int tunnel_key_act(struct sk_buff *skb,
27 const struct tc_action *a,
28 struct tcf_result *res)
29{
30 struct tcf_tunnel_key *t = to_tunnel_key(a);
31 struct tcf_tunnel_key_params *params;
32
33 params = rcu_dereference_bh(t->params);
34
35 tcf_lastuse_update(tm: &t->tcf_tm);
36 tcf_action_update_bstats(a: &t->common, skb);
37
38 switch (params->tcft_action) {
39 case TCA_TUNNEL_KEY_ACT_RELEASE:
40 skb_dst_drop(skb);
41 break;
42 case TCA_TUNNEL_KEY_ACT_SET:
43 skb_dst_drop(skb);
44 skb_dst_set(skb, dst: dst_clone(dst: &params->tcft_enc_metadata->dst));
45 break;
46 default:
47 WARN_ONCE(1, "Bad tunnel_key action %d.\n",
48 params->tcft_action);
49 break;
50 }
51
52 return params->action;
53}
54
55static const struct nla_policy
56enc_opts_policy[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1] = {
57 [TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC] = {
58 .strict_start_type = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN },
59 [TCA_TUNNEL_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED },
60 [TCA_TUNNEL_KEY_ENC_OPTS_VXLAN] = { .type = NLA_NESTED },
61 [TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN] = { .type = NLA_NESTED },
62};
63
64static const struct nla_policy
65geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
66 [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 },
67 [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 },
68 [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY,
69 .len = 127 },
70};
71
72static const struct nla_policy
73vxlan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1] = {
74 [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP] = { .type = NLA_U32 },
75};
76
77static const struct nla_policy
78erspan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1] = {
79 [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER] = { .type = NLA_U8 },
80 [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX] = { .type = NLA_U32 },
81 [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR] = { .type = NLA_U8 },
82 [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID] = { .type = NLA_U8 },
83};
84
85static int
86tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
87 struct netlink_ext_ack *extack)
88{
89 struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
90 int err, data_len, opt_len;
91 u8 *data;
92
93 err = nla_parse_nested_deprecated(tb,
94 TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
95 nla, policy: geneve_opt_policy, extack);
96 if (err < 0)
97 return err;
98
99 if (!tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] ||
100 !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] ||
101 !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]) {
102 NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data");
103 return -EINVAL;
104 }
105
106 data = nla_data(nla: tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
107 data_len = nla_len(nla: tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
108 if (data_len < 4) {
109 NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long");
110 return -ERANGE;
111 }
112 if (data_len % 4) {
113 NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long");
114 return -ERANGE;
115 }
116
117 opt_len = sizeof(struct geneve_opt) + data_len;
118 if (dst) {
119 struct geneve_opt *opt = dst;
120
121 WARN_ON(dst_len < opt_len);
122
123 opt->opt_class =
124 nla_get_be16(nla: tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
125 opt->type = nla_get_u8(nla: tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
126 opt->length = data_len / 4; /* length is in units of 4 bytes */
127 opt->r1 = 0;
128 opt->r2 = 0;
129 opt->r3 = 0;
130
131 memcpy(opt + 1, data, data_len);
132 }
133
134 return opt_len;
135}
136
137static int
138tunnel_key_copy_vxlan_opt(const struct nlattr *nla, void *dst, int dst_len,
139 struct netlink_ext_ack *extack)
140{
141 struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1];
142 int err;
143
144 err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX, nla,
145 policy: vxlan_opt_policy, extack);
146 if (err < 0)
147 return err;
148
149 if (!tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]) {
150 NL_SET_ERR_MSG(extack, "Missing tunnel key vxlan option gbp");
151 return -EINVAL;
152 }
153
154 if (dst) {
155 struct vxlan_metadata *md = dst;
156
157 md->gbp = nla_get_u32(nla: tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]);
158 md->gbp &= VXLAN_GBP_MASK;
159 }
160
161 return sizeof(struct vxlan_metadata);
162}
163
164static int
165tunnel_key_copy_erspan_opt(const struct nlattr *nla, void *dst, int dst_len,
166 struct netlink_ext_ack *extack)
167{
168 struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1];
169 int err;
170 u8 ver;
171
172 err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX, nla,
173 policy: erspan_opt_policy, extack);
174 if (err < 0)
175 return err;
176
177 if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]) {
178 NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option ver");
179 return -EINVAL;
180 }
181
182 ver = nla_get_u8(nla: tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]);
183 if (ver == 1) {
184 if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]) {
185 NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index");
186 return -EINVAL;
187 }
188 } else if (ver == 2) {
189 if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR] ||
190 !tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]) {
191 NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid");
192 return -EINVAL;
193 }
194 } else {
195 NL_SET_ERR_MSG(extack, "Tunnel key erspan option ver is incorrect");
196 return -EINVAL;
197 }
198
199 if (dst) {
200 struct erspan_metadata *md = dst;
201
202 md->version = ver;
203 if (ver == 1) {
204 nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX];
205 md->u.index = nla_get_be32(nla);
206 } else {
207 nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR];
208 md->u.md2.dir = nla_get_u8(nla);
209 nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID];
210 set_hwid(md2: &md->u.md2, hwid: nla_get_u8(nla));
211 }
212 }
213
214 return sizeof(struct erspan_metadata);
215}
216
217static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
218 int dst_len, struct netlink_ext_ack *extack)
219{
220 int err, rem, opt_len, len = nla_len(nla), opts_len = 0, type = 0;
221 const struct nlattr *attr, *head = nla_data(nla);
222
223 err = nla_validate_deprecated(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
224 policy: enc_opts_policy, extack);
225 if (err)
226 return err;
227
228 nla_for_each_attr(attr, head, len, rem) {
229 switch (nla_type(nla: attr)) {
230 case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
231 if (type && type != IP_TUNNEL_GENEVE_OPT_BIT) {
232 NL_SET_ERR_MSG(extack, "Duplicate type for geneve options");
233 return -EINVAL;
234 }
235 opt_len = tunnel_key_copy_geneve_opt(nla: attr, dst,
236 dst_len, extack);
237 if (opt_len < 0)
238 return opt_len;
239 opts_len += opt_len;
240 if (opts_len > IP_TUNNEL_OPTS_MAX) {
241 NL_SET_ERR_MSG(extack, "Tunnel options exceeds max size");
242 return -EINVAL;
243 }
244 if (dst) {
245 dst_len -= opt_len;
246 dst += opt_len;
247 }
248 type = IP_TUNNEL_GENEVE_OPT_BIT;
249 break;
250 case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
251 if (type) {
252 NL_SET_ERR_MSG(extack, "Duplicate type for vxlan options");
253 return -EINVAL;
254 }
255 opt_len = tunnel_key_copy_vxlan_opt(nla: attr, dst,
256 dst_len, extack);
257 if (opt_len < 0)
258 return opt_len;
259 opts_len += opt_len;
260 type = IP_TUNNEL_VXLAN_OPT_BIT;
261 break;
262 case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
263 if (type) {
264 NL_SET_ERR_MSG(extack, "Duplicate type for erspan options");
265 return -EINVAL;
266 }
267 opt_len = tunnel_key_copy_erspan_opt(nla: attr, dst,
268 dst_len, extack);
269 if (opt_len < 0)
270 return opt_len;
271 opts_len += opt_len;
272 type = IP_TUNNEL_ERSPAN_OPT_BIT;
273 break;
274 }
275 }
276
277 if (!opts_len) {
278 NL_SET_ERR_MSG(extack, "Empty list of tunnel options");
279 return -EINVAL;
280 }
281
282 if (rem > 0) {
283 NL_SET_ERR_MSG(extack, "Trailing data after parsing tunnel key options attributes");
284 return -EINVAL;
285 }
286
287 return opts_len;
288}
289
290static int tunnel_key_get_opts_len(struct nlattr *nla,
291 struct netlink_ext_ack *extack)
292{
293 return tunnel_key_copy_opts(nla, NULL, dst_len: 0, extack);
294}
295
296static int tunnel_key_opts_set(struct nlattr *nla, struct ip_tunnel_info *info,
297 int opts_len, struct netlink_ext_ack *extack)
298{
299 info->options_len = opts_len;
300 switch (nla_type(nla: nla_data(nla))) {
301 case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
302#if IS_ENABLED(CONFIG_INET)
303 __set_bit(IP_TUNNEL_GENEVE_OPT_BIT, info->key.tun_flags);
304 return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
305 dst_len: opts_len, extack);
306#else
307 return -EAFNOSUPPORT;
308#endif
309 case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
310#if IS_ENABLED(CONFIG_INET)
311 __set_bit(IP_TUNNEL_VXLAN_OPT_BIT, info->key.tun_flags);
312 return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
313 dst_len: opts_len, extack);
314#else
315 return -EAFNOSUPPORT;
316#endif
317 case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
318#if IS_ENABLED(CONFIG_INET)
319 __set_bit(IP_TUNNEL_ERSPAN_OPT_BIT, info->key.tun_flags);
320 return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
321 dst_len: opts_len, extack);
322#else
323 return -EAFNOSUPPORT;
324#endif
325 default:
326 NL_SET_ERR_MSG(extack, "Cannot set tunnel options for unknown tunnel type");
327 return -EINVAL;
328 }
329}
330
331static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
332 [TCA_TUNNEL_KEY_PARMS] = { .len = sizeof(struct tc_tunnel_key) },
333 [TCA_TUNNEL_KEY_ENC_IPV4_SRC] = { .type = NLA_U32 },
334 [TCA_TUNNEL_KEY_ENC_IPV4_DST] = { .type = NLA_U32 },
335 [TCA_TUNNEL_KEY_ENC_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
336 [TCA_TUNNEL_KEY_ENC_IPV6_DST] = { .len = sizeof(struct in6_addr) },
337 [TCA_TUNNEL_KEY_ENC_KEY_ID] = { .type = NLA_U32 },
338 [TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
339 [TCA_TUNNEL_KEY_NO_CSUM] = { .type = NLA_U8 },
340 [TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NLA_NESTED },
341 [TCA_TUNNEL_KEY_ENC_TOS] = { .type = NLA_U8 },
342 [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
343};
344
345static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
346{
347 if (!p)
348 return;
349 if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
350 dst_release(dst: &p->tcft_enc_metadata->dst);
351
352 kfree_rcu(p, rcu);
353}
354
355static int tunnel_key_init(struct net *net, struct nlattr *nla,
356 struct nlattr *est, struct tc_action **a,
357 struct tcf_proto *tp, u32 act_flags,
358 struct netlink_ext_ack *extack)
359{
360 struct tc_action_net *tn = net_generic(net, id: act_tunnel_key_ops.net_id);
361 bool bind = act_flags & TCA_ACT_FLAGS_BIND;
362 struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
363 struct tcf_tunnel_key_params *params_new;
364 IP_TUNNEL_DECLARE_FLAGS(flags) = { };
365 struct metadata_dst *metadata = NULL;
366 struct tcf_chain *goto_ch = NULL;
367 struct tc_tunnel_key *parm;
368 struct tcf_tunnel_key *t;
369 bool exists = false;
370 __be16 dst_port = 0;
371 __be64 key_id = 0;
372 int opts_len = 0;
373 u8 tos, ttl;
374 int ret = 0;
375 u32 index;
376 int err;
377
378 if (!nla) {
379 NL_SET_ERR_MSG(extack, "Tunnel requires attributes to be passed");
380 return -EINVAL;
381 }
382
383 err = nla_parse_nested_deprecated(tb, TCA_TUNNEL_KEY_MAX, nla,
384 policy: tunnel_key_policy, extack);
385 if (err < 0) {
386 NL_SET_ERR_MSG(extack, "Failed to parse nested tunnel key attributes");
387 return err;
388 }
389
390 if (!tb[TCA_TUNNEL_KEY_PARMS]) {
391 NL_SET_ERR_MSG(extack, "Missing tunnel key parameters");
392 return -EINVAL;
393 }
394
395 parm = nla_data(nla: tb[TCA_TUNNEL_KEY_PARMS]);
396 index = parm->index;
397 err = tcf_idr_check_alloc(tn, index: &index, a, bind);
398 if (err < 0)
399 return err;
400 exists = err;
401 if (exists && bind)
402 return ACT_P_BOUND;
403
404 switch (parm->t_action) {
405 case TCA_TUNNEL_KEY_ACT_RELEASE:
406 break;
407 case TCA_TUNNEL_KEY_ACT_SET:
408 if (tb[TCA_TUNNEL_KEY_ENC_KEY_ID]) {
409 __be32 key32;
410
411 key32 = nla_get_be32(nla: tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
412 key_id = key32_to_tunnel_id(key: key32);
413 __set_bit(IP_TUNNEL_KEY_BIT, flags);
414 }
415
416 __set_bit(IP_TUNNEL_CSUM_BIT, flags);
417 if (tb[TCA_TUNNEL_KEY_NO_CSUM] &&
418 nla_get_u8(nla: tb[TCA_TUNNEL_KEY_NO_CSUM]))
419 __clear_bit(IP_TUNNEL_CSUM_BIT, flags);
420
421 if (nla_get_flag(nla: tb[TCA_TUNNEL_KEY_NO_FRAG]))
422 __set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, flags);
423
424 if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
425 dst_port = nla_get_be16(nla: tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
426
427 if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
428 opts_len = tunnel_key_get_opts_len(nla: tb[TCA_TUNNEL_KEY_ENC_OPTS],
429 extack);
430 if (opts_len < 0) {
431 ret = opts_len;
432 goto err_out;
433 }
434 }
435
436 tos = 0;
437 if (tb[TCA_TUNNEL_KEY_ENC_TOS])
438 tos = nla_get_u8(nla: tb[TCA_TUNNEL_KEY_ENC_TOS]);
439 ttl = 0;
440 if (tb[TCA_TUNNEL_KEY_ENC_TTL])
441 ttl = nla_get_u8(nla: tb[TCA_TUNNEL_KEY_ENC_TTL]);
442
443 if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
444 tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
445 __be32 saddr;
446 __be32 daddr;
447
448 saddr = nla_get_in_addr(nla: tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC]);
449 daddr = nla_get_in_addr(nla: tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]);
450
451 metadata = __ip_tun_set_dst(saddr, daddr, tos, ttl,
452 tp_dst: dst_port, flags,
453 tunnel_id: key_id, md_size: opts_len);
454 } else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
455 tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
456 struct in6_addr saddr;
457 struct in6_addr daddr;
458
459 saddr = nla_get_in6_addr(nla: tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC]);
460 daddr = nla_get_in6_addr(nla: tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]);
461
462 metadata = __ipv6_tun_set_dst(saddr: &saddr, daddr: &daddr, tos, ttl, tp_dst: dst_port,
463 label: 0, flags,
464 tunnel_id: key_id, md_size: opts_len);
465 } else {
466 NL_SET_ERR_MSG(extack, "Missing either ipv4 or ipv6 src and dst");
467 ret = -EINVAL;
468 goto err_out;
469 }
470
471 if (!metadata) {
472 NL_SET_ERR_MSG(extack, "Cannot allocate tunnel metadata dst");
473 ret = -ENOMEM;
474 goto err_out;
475 }
476
477#ifdef CONFIG_DST_CACHE
478 ret = dst_cache_init(dst_cache: &metadata->u.tun_info.dst_cache, GFP_KERNEL);
479 if (ret)
480 goto release_tun_meta;
481#endif
482
483 if (opts_len) {
484 ret = tunnel_key_opts_set(nla: tb[TCA_TUNNEL_KEY_ENC_OPTS],
485 info: &metadata->u.tun_info,
486 opts_len, extack);
487 if (ret < 0)
488 goto release_tun_meta;
489 }
490
491 metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
492 break;
493 default:
494 NL_SET_ERR_MSG(extack, "Unknown tunnel key action");
495 ret = -EINVAL;
496 goto err_out;
497 }
498
499 if (!exists) {
500 ret = tcf_idr_create_from_flags(tn, index, est, a,
501 ops: &act_tunnel_key_ops, bind,
502 flags: act_flags);
503 if (ret) {
504 NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
505 goto release_tun_meta;
506 }
507
508 ret = ACT_P_CREATED;
509 } else if (!(act_flags & TCA_ACT_FLAGS_REPLACE)) {
510 NL_SET_ERR_MSG(extack, "TC IDR already exists");
511 ret = -EEXIST;
512 goto release_tun_meta;
513 }
514
515 err = tcf_action_check_ctrlact(action: parm->action, tp, handle: &goto_ch, newchain: extack);
516 if (err < 0) {
517 ret = err;
518 exists = true;
519 goto release_tun_meta;
520 }
521 t = to_tunnel_key(*a);
522
523 params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
524 if (unlikely(!params_new)) {
525 NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
526 ret = -ENOMEM;
527 exists = true;
528 goto put_chain;
529 }
530 params_new->tcft_action = parm->t_action;
531 params_new->tcft_enc_metadata = metadata;
532
533 params_new->action = parm->action;
534 spin_lock_bh(lock: &t->tcf_lock);
535 goto_ch = tcf_action_set_ctrlact(a: *a, action: parm->action, newchain: goto_ch);
536 params_new = rcu_replace_pointer(t->params, params_new,
537 lockdep_is_held(&t->tcf_lock));
538 spin_unlock_bh(lock: &t->tcf_lock);
539 tunnel_key_release_params(p: params_new);
540 if (goto_ch)
541 tcf_chain_put_by_act(chain: goto_ch);
542
543 return ret;
544
545put_chain:
546 if (goto_ch)
547 tcf_chain_put_by_act(chain: goto_ch);
548
549release_tun_meta:
550 if (metadata)
551 dst_release(dst: &metadata->dst);
552
553err_out:
554 if (exists)
555 tcf_idr_release(a: *a, bind);
556 else
557 tcf_idr_cleanup(tn, index);
558 return ret;
559}
560
561static void tunnel_key_release(struct tc_action *a)
562{
563 struct tcf_tunnel_key *t = to_tunnel_key(a);
564 struct tcf_tunnel_key_params *params;
565
566 params = rcu_dereference_protected(t->params, 1);
567 tunnel_key_release_params(p: params);
568}
569
570static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
571 const struct ip_tunnel_info *info)
572{
573 const u8 *src = ip_tunnel_info_opts(info);
574 int len = info->options_len;
575 struct nlattr *start;
576
577 start = nla_nest_start_noflag(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
578 if (!start)
579 return -EMSGSIZE;
580
581 while (len > 0) {
582 const struct geneve_opt *opt = (const struct geneve_opt *)src;
583
584 if (nla_put_be16(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS,
585 value: opt->opt_class) ||
586 nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE,
587 value: opt->type) ||
588 nla_put(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA,
589 attrlen: opt->length * 4, data: opt + 1)) {
590 nla_nest_cancel(skb, start);
591 return -EMSGSIZE;
592 }
593
594 len -= sizeof(struct geneve_opt) + opt->length * 4;
595 src += sizeof(struct geneve_opt) + opt->length * 4;
596 }
597
598 nla_nest_end(skb, start);
599 return 0;
600}
601
602static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
603 const struct ip_tunnel_info *info)
604{
605 const struct vxlan_metadata *md = ip_tunnel_info_opts(info);
606 struct nlattr *start;
607
608 start = nla_nest_start_noflag(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
609 if (!start)
610 return -EMSGSIZE;
611
612 if (nla_put_u32(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, value: md->gbp)) {
613 nla_nest_cancel(skb, start);
614 return -EMSGSIZE;
615 }
616
617 nla_nest_end(skb, start);
618 return 0;
619}
620
621static int tunnel_key_erspan_opts_dump(struct sk_buff *skb,
622 const struct ip_tunnel_info *info)
623{
624 const struct erspan_metadata *md = ip_tunnel_info_opts(info);
625 struct nlattr *start;
626
627 start = nla_nest_start_noflag(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN);
628 if (!start)
629 return -EMSGSIZE;
630
631 if (nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER, value: md->version))
632 goto err;
633
634 if (md->version == 1 &&
635 nla_put_be32(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX, value: md->u.index))
636 goto err;
637
638 if (md->version == 2 &&
639 (nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR,
640 value: md->u.md2.dir) ||
641 nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID,
642 value: get_hwid(md2: &md->u.md2))))
643 goto err;
644
645 nla_nest_end(skb, start);
646 return 0;
647err:
648 nla_nest_cancel(skb, start);
649 return -EMSGSIZE;
650}
651
652static int tunnel_key_opts_dump(struct sk_buff *skb,
653 const struct ip_tunnel_info *info)
654{
655 struct nlattr *start;
656 int err = -EINVAL;
657
658 if (!info->options_len)
659 return 0;
660
661 start = nla_nest_start_noflag(skb, attrtype: TCA_TUNNEL_KEY_ENC_OPTS);
662 if (!start)
663 return -EMSGSIZE;
664
665 if (test_bit(IP_TUNNEL_GENEVE_OPT_BIT, info->key.tun_flags)) {
666 err = tunnel_key_geneve_opts_dump(skb, info);
667 if (err)
668 goto err_out;
669 } else if (test_bit(IP_TUNNEL_VXLAN_OPT_BIT, info->key.tun_flags)) {
670 err = tunnel_key_vxlan_opts_dump(skb, info);
671 if (err)
672 goto err_out;
673 } else if (test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, info->key.tun_flags)) {
674 err = tunnel_key_erspan_opts_dump(skb, info);
675 if (err)
676 goto err_out;
677 } else {
678err_out:
679 nla_nest_cancel(skb, start);
680 return err;
681 }
682
683 nla_nest_end(skb, start);
684 return 0;
685}
686
687static int tunnel_key_dump_addresses(struct sk_buff *skb,
688 const struct ip_tunnel_info *info)
689{
690 unsigned short family = ip_tunnel_info_af(tun_info: info);
691
692 if (family == AF_INET) {
693 __be32 saddr = info->key.u.ipv4.src;
694 __be32 daddr = info->key.u.ipv4.dst;
695
696 if (!nla_put_in_addr(skb, attrtype: TCA_TUNNEL_KEY_ENC_IPV4_SRC, addr: saddr) &&
697 !nla_put_in_addr(skb, attrtype: TCA_TUNNEL_KEY_ENC_IPV4_DST, addr: daddr))
698 return 0;
699 }
700
701 if (family == AF_INET6) {
702 const struct in6_addr *saddr6 = &info->key.u.ipv6.src;
703 const struct in6_addr *daddr6 = &info->key.u.ipv6.dst;
704
705 if (!nla_put_in6_addr(skb,
706 attrtype: TCA_TUNNEL_KEY_ENC_IPV6_SRC, addr: saddr6) &&
707 !nla_put_in6_addr(skb,
708 attrtype: TCA_TUNNEL_KEY_ENC_IPV6_DST, addr: daddr6))
709 return 0;
710 }
711
712 return -EINVAL;
713}
714
715static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
716 int bind, int ref)
717{
718 unsigned char *b = skb_tail_pointer(skb);
719 struct tcf_tunnel_key *t = to_tunnel_key(a);
720 struct tcf_tunnel_key_params *params;
721 struct tc_tunnel_key opt = {
722 .index = t->tcf_index,
723 .refcnt = refcount_read(r: &t->tcf_refcnt) - ref,
724 .bindcnt = atomic_read(v: &t->tcf_bindcnt) - bind,
725 };
726 struct tcf_t tm;
727
728 rcu_read_lock();
729 params = rcu_dereference(t->params);
730 opt.action = params->action;
731 opt.t_action = params->tcft_action;
732
733 if (nla_put(skb, attrtype: TCA_TUNNEL_KEY_PARMS, attrlen: sizeof(opt), data: &opt))
734 goto nla_put_failure;
735
736 if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
737 struct ip_tunnel_info *info =
738 &params->tcft_enc_metadata->u.tun_info;
739 struct ip_tunnel_key *key = &info->key;
740 __be32 key_id = tunnel_id_to_key32(tun_id: key->tun_id);
741
742 if ((test_bit(IP_TUNNEL_KEY_BIT, key->tun_flags) &&
743 nla_put_be32(skb, attrtype: TCA_TUNNEL_KEY_ENC_KEY_ID, value: key_id)) ||
744 tunnel_key_dump_addresses(skb,
745 info: &params->tcft_enc_metadata->u.tun_info) ||
746 (key->tp_dst &&
747 nla_put_be16(skb, attrtype: TCA_TUNNEL_KEY_ENC_DST_PORT,
748 value: key->tp_dst)) ||
749 nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_NO_CSUM,
750 value: !test_bit(IP_TUNNEL_CSUM_BIT, key->tun_flags)) ||
751 (test_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, key->tun_flags) &&
752 nla_put_flag(skb, attrtype: TCA_TUNNEL_KEY_NO_FRAG)) ||
753 tunnel_key_opts_dump(skb, info))
754 goto nla_put_failure;
755
756 if (key->tos && nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_ENC_TOS, value: key->tos))
757 goto nla_put_failure;
758
759 if (key->ttl && nla_put_u8(skb, attrtype: TCA_TUNNEL_KEY_ENC_TTL, value: key->ttl))
760 goto nla_put_failure;
761 }
762
763 tcf_tm_dump(dtm: &tm, stm: &t->tcf_tm);
764 if (nla_put_64bit(skb, attrtype: TCA_TUNNEL_KEY_TM, attrlen: sizeof(tm),
765 data: &tm, padattr: TCA_TUNNEL_KEY_PAD))
766 goto nla_put_failure;
767 rcu_read_unlock();
768
769 return skb->len;
770
771nla_put_failure:
772 rcu_read_unlock();
773 nlmsg_trim(skb, mark: b);
774 return -1;
775}
776
777static void tcf_tunnel_encap_put_tunnel(void *priv)
778{
779 struct ip_tunnel_info *tunnel = priv;
780
781 kfree(objp: tunnel);
782}
783
784static int tcf_tunnel_encap_get_tunnel(struct flow_action_entry *entry,
785 const struct tc_action *act)
786{
787 entry->tunnel = tcf_tunnel_info_copy(a: act);
788 if (!entry->tunnel)
789 return -ENOMEM;
790 entry->destructor = tcf_tunnel_encap_put_tunnel;
791 entry->destructor_priv = entry->tunnel;
792 return 0;
793}
794
795static int tcf_tunnel_key_offload_act_setup(struct tc_action *act,
796 void *entry_data,
797 u32 *index_inc,
798 bool bind,
799 struct netlink_ext_ack *extack)
800{
801 int err;
802
803 if (bind) {
804 struct flow_action_entry *entry = entry_data;
805
806 if (is_tcf_tunnel_set(a: act)) {
807 entry->id = FLOW_ACTION_TUNNEL_ENCAP;
808 err = tcf_tunnel_encap_get_tunnel(entry, act);
809 if (err)
810 return err;
811 } else if (is_tcf_tunnel_release(a: act)) {
812 entry->id = FLOW_ACTION_TUNNEL_DECAP;
813 } else {
814 NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel key mode offload");
815 return -EOPNOTSUPP;
816 }
817 *index_inc = 1;
818 } else {
819 struct flow_offload_action *fl_action = entry_data;
820
821 if (is_tcf_tunnel_set(a: act))
822 fl_action->id = FLOW_ACTION_TUNNEL_ENCAP;
823 else if (is_tcf_tunnel_release(a: act))
824 fl_action->id = FLOW_ACTION_TUNNEL_DECAP;
825 else
826 return -EOPNOTSUPP;
827 }
828
829 return 0;
830}
831
832static struct tc_action_ops act_tunnel_key_ops = {
833 .kind = "tunnel_key",
834 .id = TCA_ID_TUNNEL_KEY,
835 .owner = THIS_MODULE,
836 .act = tunnel_key_act,
837 .dump = tunnel_key_dump,
838 .init = tunnel_key_init,
839 .cleanup = tunnel_key_release,
840 .offload_act_setup = tcf_tunnel_key_offload_act_setup,
841 .size = sizeof(struct tcf_tunnel_key),
842};
843MODULE_ALIAS_NET_ACT("tunnel_key");
844
845static __net_init int tunnel_key_init_net(struct net *net)
846{
847 struct tc_action_net *tn = net_generic(net, id: act_tunnel_key_ops.net_id);
848
849 return tc_action_net_init(net, tn, ops: &act_tunnel_key_ops);
850}
851
852static void __net_exit tunnel_key_exit_net(struct list_head *net_list)
853{
854 tc_action_net_exit(net_list, id: act_tunnel_key_ops.net_id);
855}
856
857static struct pernet_operations tunnel_key_net_ops = {
858 .init = tunnel_key_init_net,
859 .exit_batch = tunnel_key_exit_net,
860 .id = &act_tunnel_key_ops.net_id,
861 .size = sizeof(struct tc_action_net),
862};
863
864static int __init tunnel_key_init_module(void)
865{
866 return tcf_register_action(a: &act_tunnel_key_ops, ops: &tunnel_key_net_ops);
867}
868
869static void __exit tunnel_key_cleanup_module(void)
870{
871 tcf_unregister_action(a: &act_tunnel_key_ops, ops: &tunnel_key_net_ops);
872}
873
874module_init(tunnel_key_init_module);
875module_exit(tunnel_key_cleanup_module);
876
877MODULE_AUTHOR("Amir Vadai <amir@vadai.me>");
878MODULE_DESCRIPTION("ip tunnel manipulation actions");
879MODULE_LICENSE("GPL v2");
880

source code of linux/net/sched/act_tunnel_key.c