hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/act_tunnel_key.c
....@@ -1,11 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (c) 2016, Amir Vadai <amir@vadai.me>
34 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation; either version 2 of the License, or
8
- * (at your option) any later version.
95 */
106
117 #include <linux/module.h>
....@@ -14,9 +10,12 @@
1410 #include <linux/skbuff.h>
1511 #include <linux/rtnetlink.h>
1612 #include <net/geneve.h>
13
+#include <net/vxlan.h>
14
+#include <net/erspan.h>
1715 #include <net/netlink.h>
1816 #include <net/pkt_sched.h>
1917 #include <net/dst.h>
18
+#include <net/pkt_cls.h>
2019
2120 #include <linux/tc_act/tc_tunnel_key.h>
2221 #include <net/tc_act/tc_tunnel_key.h>
....@@ -34,7 +33,7 @@
3433 params = rcu_dereference_bh(t->params);
3534
3635 tcf_lastuse_update(&t->tcf_tm);
37
- bstats_cpu_update(this_cpu_ptr(t->common.cpu_bstats), skb);
36
+ tcf_action_update_bstats(&t->common, skb);
3837 action = READ_ONCE(t->tcf_action);
3938
4039 switch (params->tcft_action) {
....@@ -56,7 +55,11 @@
5655
5756 static const struct nla_policy
5857 enc_opts_policy[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1] = {
58
+ [TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC] = {
59
+ .strict_start_type = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN },
5960 [TCA_TUNNEL_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED },
61
+ [TCA_TUNNEL_KEY_ENC_OPTS_VXLAN] = { .type = NLA_NESTED },
62
+ [TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN] = { .type = NLA_NESTED },
6063 };
6164
6265 static const struct nla_policy
....@@ -67,6 +70,19 @@
6770 .len = 128 },
6871 };
6972
73
+static const struct nla_policy
74
+vxlan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1] = {
75
+ [TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP] = { .type = NLA_U32 },
76
+};
77
+
78
+static const struct nla_policy
79
+erspan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1] = {
80
+ [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER] = { .type = NLA_U8 },
81
+ [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX] = { .type = NLA_U32 },
82
+ [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR] = { .type = NLA_U8 },
83
+ [TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID] = { .type = NLA_U8 },
84
+};
85
+
7086 static int
7187 tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
7288 struct netlink_ext_ack *extack)
....@@ -75,8 +91,9 @@
7591 int err, data_len, opt_len;
7692 u8 *data;
7793
78
- err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
79
- nla, geneve_opt_policy, extack);
94
+ err = nla_parse_nested_deprecated(tb,
95
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
96
+ nla, geneve_opt_policy, extack);
8097 if (err < 0)
8198 return err;
8299
....@@ -118,20 +135,104 @@
118135 return opt_len;
119136 }
120137
138
+static int
139
+tunnel_key_copy_vxlan_opt(const struct nlattr *nla, void *dst, int dst_len,
140
+ struct netlink_ext_ack *extack)
141
+{
142
+ struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1];
143
+ int err;
144
+
145
+ err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX, nla,
146
+ vxlan_opt_policy, extack);
147
+ if (err < 0)
148
+ return err;
149
+
150
+ if (!tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]) {
151
+ NL_SET_ERR_MSG(extack, "Missing tunnel key vxlan option gbp");
152
+ return -EINVAL;
153
+ }
154
+
155
+ if (dst) {
156
+ struct vxlan_metadata *md = dst;
157
+
158
+ md->gbp = nla_get_u32(tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]);
159
+ md->gbp &= VXLAN_GBP_MASK;
160
+ }
161
+
162
+ return sizeof(struct vxlan_metadata);
163
+}
164
+
165
+static int
166
+tunnel_key_copy_erspan_opt(const struct nlattr *nla, void *dst, int dst_len,
167
+ struct netlink_ext_ack *extack)
168
+{
169
+ struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1];
170
+ int err;
171
+ u8 ver;
172
+
173
+ err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX, nla,
174
+ erspan_opt_policy, extack);
175
+ if (err < 0)
176
+ return err;
177
+
178
+ if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]) {
179
+ NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option ver");
180
+ return -EINVAL;
181
+ }
182
+
183
+ ver = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]);
184
+ if (ver == 1) {
185
+ if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]) {
186
+ NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index");
187
+ return -EINVAL;
188
+ }
189
+ } else if (ver == 2) {
190
+ if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR] ||
191
+ !tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]) {
192
+ NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid");
193
+ return -EINVAL;
194
+ }
195
+ } else {
196
+ NL_SET_ERR_MSG(extack, "Tunnel key erspan option ver is incorrect");
197
+ return -EINVAL;
198
+ }
199
+
200
+ if (dst) {
201
+ struct erspan_metadata *md = dst;
202
+
203
+ md->version = ver;
204
+ if (ver == 1) {
205
+ nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX];
206
+ md->u.index = nla_get_be32(nla);
207
+ } else {
208
+ nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR];
209
+ md->u.md2.dir = nla_get_u8(nla);
210
+ nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID];
211
+ set_hwid(&md->u.md2, nla_get_u8(nla));
212
+ }
213
+ }
214
+
215
+ return sizeof(struct erspan_metadata);
216
+}
217
+
121218 static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
122219 int dst_len, struct netlink_ext_ack *extack)
123220 {
124
- int err, rem, opt_len, len = nla_len(nla), opts_len = 0;
221
+ int err, rem, opt_len, len = nla_len(nla), opts_len = 0, type = 0;
125222 const struct nlattr *attr, *head = nla_data(nla);
126223
127
- err = nla_validate(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
128
- enc_opts_policy, extack);
224
+ err = nla_validate_deprecated(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
225
+ enc_opts_policy, extack);
129226 if (err)
130227 return err;
131228
132229 nla_for_each_attr(attr, head, len, rem) {
133230 switch (nla_type(attr)) {
134231 case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
232
+ if (type && type != TUNNEL_GENEVE_OPT) {
233
+ NL_SET_ERR_MSG(extack, "Duplicate type for geneve options");
234
+ return -EINVAL;
235
+ }
135236 opt_len = tunnel_key_copy_geneve_opt(attr, dst,
136237 dst_len, extack);
137238 if (opt_len < 0)
....@@ -145,6 +246,31 @@
145246 dst_len -= opt_len;
146247 dst += opt_len;
147248 }
249
+ type = TUNNEL_GENEVE_OPT;
250
+ break;
251
+ case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
252
+ if (type) {
253
+ NL_SET_ERR_MSG(extack, "Duplicate type for vxlan options");
254
+ return -EINVAL;
255
+ }
256
+ opt_len = tunnel_key_copy_vxlan_opt(attr, dst,
257
+ dst_len, extack);
258
+ if (opt_len < 0)
259
+ return opt_len;
260
+ opts_len += opt_len;
261
+ type = TUNNEL_VXLAN_OPT;
262
+ break;
263
+ case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
264
+ if (type) {
265
+ NL_SET_ERR_MSG(extack, "Duplicate type for erspan options");
266
+ return -EINVAL;
267
+ }
268
+ opt_len = tunnel_key_copy_erspan_opt(attr, dst,
269
+ dst_len, extack);
270
+ if (opt_len < 0)
271
+ return opt_len;
272
+ opts_len += opt_len;
273
+ type = TUNNEL_ERSPAN_OPT;
148274 break;
149275 }
150276 }
....@@ -181,6 +307,22 @@
181307 #else
182308 return -EAFNOSUPPORT;
183309 #endif
310
+ case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
311
+#if IS_ENABLED(CONFIG_INET)
312
+ info->key.tun_flags |= TUNNEL_VXLAN_OPT;
313
+ return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
314
+ opts_len, extack);
315
+#else
316
+ return -EAFNOSUPPORT;
317
+#endif
318
+ case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
319
+#if IS_ENABLED(CONFIG_INET)
320
+ info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
321
+ return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
322
+ opts_len, extack);
323
+#else
324
+ return -EAFNOSUPPORT;
325
+#endif
184326 default:
185327 NL_SET_ERR_MSG(extack, "Cannot set tunnel options for unknown tunnel type");
186328 return -EINVAL;
....@@ -207,25 +349,28 @@
207349 return;
208350 if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
209351 dst_release(&p->tcft_enc_metadata->dst);
352
+
210353 kfree_rcu(p, rcu);
211354 }
212355
213356 static int tunnel_key_init(struct net *net, struct nlattr *nla,
214357 struct nlattr *est, struct tc_action **a,
215358 int ovr, int bind, bool rtnl_held,
359
+ struct tcf_proto *tp, u32 act_flags,
216360 struct netlink_ext_ack *extack)
217361 {
218362 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
219363 struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
220364 struct tcf_tunnel_key_params *params_new;
221365 struct metadata_dst *metadata = NULL;
366
+ struct tcf_chain *goto_ch = NULL;
222367 struct tc_tunnel_key *parm;
223368 struct tcf_tunnel_key *t;
224369 bool exists = false;
225370 __be16 dst_port = 0;
371
+ __be64 key_id = 0;
226372 int opts_len = 0;
227
- __be64 key_id;
228
- __be16 flags;
373
+ __be16 flags = 0;
229374 u8 tos, ttl;
230375 int ret = 0;
231376 u32 index;
....@@ -236,8 +381,8 @@
236381 return -EINVAL;
237382 }
238383
239
- err = nla_parse_nested(tb, TCA_TUNNEL_KEY_MAX, nla, tunnel_key_policy,
240
- extack);
384
+ err = nla_parse_nested_deprecated(tb, TCA_TUNNEL_KEY_MAX, nla,
385
+ tunnel_key_policy, extack);
241386 if (err < 0) {
242387 NL_SET_ERR_MSG(extack, "Failed to parse nested tunnel key attributes");
243388 return err;
....@@ -261,15 +406,15 @@
261406 case TCA_TUNNEL_KEY_ACT_RELEASE:
262407 break;
263408 case TCA_TUNNEL_KEY_ACT_SET:
264
- if (!tb[TCA_TUNNEL_KEY_ENC_KEY_ID]) {
265
- NL_SET_ERR_MSG(extack, "Missing tunnel key id");
266
- ret = -EINVAL;
267
- goto err_out;
409
+ if (tb[TCA_TUNNEL_KEY_ENC_KEY_ID]) {
410
+ __be32 key32;
411
+
412
+ key32 = nla_get_be32(tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
413
+ key_id = key32_to_tunnel_id(key32);
414
+ flags = TUNNEL_KEY;
268415 }
269416
270
- key_id = key32_to_tunnel_id(nla_get_be32(tb[TCA_TUNNEL_KEY_ENC_KEY_ID]));
271
-
272
- flags = TUNNEL_KEY | TUNNEL_CSUM;
417
+ flags |= TUNNEL_CSUM;
273418 if (tb[TCA_TUNNEL_KEY_NO_CSUM] &&
274419 nla_get_u8(tb[TCA_TUNNEL_KEY_NO_CSUM]))
275420 flags &= ~TUNNEL_CSUM;
....@@ -327,6 +472,12 @@
327472 goto err_out;
328473 }
329474
475
+#ifdef CONFIG_DST_CACHE
476
+ ret = dst_cache_init(&metadata->u.tun_info.dst_cache, GFP_KERNEL);
477
+ if (ret)
478
+ goto release_tun_meta;
479
+#endif
480
+
330481 if (opts_len) {
331482 ret = tunnel_key_opts_set(tb[TCA_TUNNEL_KEY_ENC_OPTS],
332483 &metadata->u.tun_info,
....@@ -344,8 +495,9 @@
344495 }
345496
346497 if (!exists) {
347
- ret = tcf_idr_create(tn, index, est, a,
348
- &act_tunnel_key_ops, bind, true);
498
+ ret = tcf_idr_create_from_flags(tn, index, est, a,
499
+ &act_tunnel_key_ops, bind,
500
+ act_flags);
349501 if (ret) {
350502 NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
351503 goto release_tun_meta;
....@@ -358,6 +510,12 @@
358510 goto release_tun_meta;
359511 }
360512
513
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
514
+ if (err < 0) {
515
+ ret = err;
516
+ exists = true;
517
+ goto release_tun_meta;
518
+ }
361519 t = to_tunnel_key(*a);
362520
363521 params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
....@@ -365,22 +523,25 @@
365523 NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
366524 ret = -ENOMEM;
367525 exists = true;
368
- goto release_tun_meta;
526
+ goto put_chain;
369527 }
370528 params_new->tcft_action = parm->t_action;
371529 params_new->tcft_enc_metadata = metadata;
372530
373531 spin_lock_bh(&t->tcf_lock);
374
- t->tcf_action = parm->action;
375
- rcu_swap_protected(t->params, params_new,
376
- lockdep_is_held(&t->tcf_lock));
532
+ goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
533
+ params_new = rcu_replace_pointer(t->params, params_new,
534
+ lockdep_is_held(&t->tcf_lock));
377535 spin_unlock_bh(&t->tcf_lock);
378536 tunnel_key_release_params(params_new);
379
-
380
- if (ret == ACT_P_CREATED)
381
- tcf_idr_insert(tn, *a);
537
+ if (goto_ch)
538
+ tcf_chain_put_by_act(goto_ch);
382539
383540 return ret;
541
+
542
+put_chain:
543
+ if (goto_ch)
544
+ tcf_chain_put_by_act(goto_ch);
384545
385546 release_tun_meta:
386547 if (metadata)
....@@ -410,7 +571,7 @@
410571 u8 *src = (u8 *)(info + 1);
411572 struct nlattr *start;
412573
413
- start = nla_nest_start(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
574
+ start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
414575 if (!start)
415576 return -EMSGSIZE;
416577
....@@ -435,6 +596,56 @@
435596 return 0;
436597 }
437598
599
+static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
600
+ const struct ip_tunnel_info *info)
601
+{
602
+ struct vxlan_metadata *md = (struct vxlan_metadata *)(info + 1);
603
+ struct nlattr *start;
604
+
605
+ start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
606
+ if (!start)
607
+ return -EMSGSIZE;
608
+
609
+ if (nla_put_u32(skb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, md->gbp)) {
610
+ nla_nest_cancel(skb, start);
611
+ return -EMSGSIZE;
612
+ }
613
+
614
+ nla_nest_end(skb, start);
615
+ return 0;
616
+}
617
+
618
+static int tunnel_key_erspan_opts_dump(struct sk_buff *skb,
619
+ const struct ip_tunnel_info *info)
620
+{
621
+ struct erspan_metadata *md = (struct erspan_metadata *)(info + 1);
622
+ struct nlattr *start;
623
+
624
+ start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN);
625
+ if (!start)
626
+ return -EMSGSIZE;
627
+
628
+ if (nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER, md->version))
629
+ goto err;
630
+
631
+ if (md->version == 1 &&
632
+ nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX, md->u.index))
633
+ goto err;
634
+
635
+ if (md->version == 2 &&
636
+ (nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR,
637
+ md->u.md2.dir) ||
638
+ nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID,
639
+ get_hwid(&md->u.md2))))
640
+ goto err;
641
+
642
+ nla_nest_end(skb, start);
643
+ return 0;
644
+err:
645
+ nla_nest_cancel(skb, start);
646
+ return -EMSGSIZE;
647
+}
648
+
438649 static int tunnel_key_opts_dump(struct sk_buff *skb,
439650 const struct ip_tunnel_info *info)
440651 {
....@@ -444,12 +655,20 @@
444655 if (!info->options_len)
445656 return 0;
446657
447
- start = nla_nest_start(skb, TCA_TUNNEL_KEY_ENC_OPTS);
658
+ start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS);
448659 if (!start)
449660 return -EMSGSIZE;
450661
451662 if (info->key.tun_flags & TUNNEL_GENEVE_OPT) {
452663 err = tunnel_key_geneve_opts_dump(skb, info);
664
+ if (err)
665
+ goto err_out;
666
+ } else if (info->key.tun_flags & TUNNEL_VXLAN_OPT) {
667
+ err = tunnel_key_vxlan_opts_dump(skb, info);
668
+ if (err)
669
+ goto err_out;
670
+ } else if (info->key.tun_flags & TUNNEL_ERSPAN_OPT) {
671
+ err = tunnel_key_erspan_opts_dump(skb, info);
453672 if (err)
454673 goto err_out;
455674 } else {
....@@ -518,10 +737,13 @@
518737 struct ip_tunnel_key *key = &info->key;
519738 __be32 key_id = tunnel_id_to_key32(key->tun_id);
520739
521
- if (nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id) ||
740
+ if (((key->tun_flags & TUNNEL_KEY) &&
741
+ nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id)) ||
522742 tunnel_key_dump_addresses(skb,
523743 &params->tcft_enc_metadata->u.tun_info) ||
524
- nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT, key->tp_dst) ||
744
+ (key->tp_dst &&
745
+ nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT,
746
+ key->tp_dst)) ||
525747 nla_put_u8(skb, TCA_TUNNEL_KEY_NO_CSUM,
526748 !(key->tun_flags & TUNNEL_CSUM)) ||
527749 tunnel_key_opts_dump(skb, info))
....@@ -558,8 +780,7 @@
558780 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
559781 }
560782
561
-static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index,
562
- struct netlink_ext_ack *extack)
783
+static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index)
563784 {
564785 struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
565786
....@@ -568,7 +789,7 @@
568789
569790 static struct tc_action_ops act_tunnel_key_ops = {
570791 .kind = "tunnel_key",
571
- .type = TCA_ACT_TUNNEL_KEY,
792
+ .id = TCA_ID_TUNNEL_KEY,
572793 .owner = THIS_MODULE,
573794 .act = tunnel_key_act,
574795 .dump = tunnel_key_dump,