hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/sched/act_ife.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * net/sched/ife.c Inter-FE action based on ForCES WG InterFE LFB
34 *
....@@ -9,13 +10,7 @@
910 * Subsystem"
1011 * Authors: Jamal Hadi Salim and Damascene M. Joachimpillai
1112 *
12
- * This program is free software; you can redistribute it and/or
13
- * modify it under the terms of the GNU General Public License
14
- * as published by the Free Software Foundation; either version
15
- * 2 of the License, or (at your option) any later version.
16
- *
1713 * copyright Jamal Hadi Salim (2015)
18
- *
1914 */
2015
2116 #include <linux/types.h>
....@@ -29,6 +24,7 @@
2924 #include <net/net_namespace.h>
3025 #include <net/netlink.h>
3126 #include <net/pkt_sched.h>
27
+#include <net/pkt_cls.h>
3228 #include <uapi/linux/tc_act/tc_ife.h>
3329 #include <net/tc_act/tc_ife.h>
3430 #include <linux/etherdevice.h>
....@@ -386,7 +382,7 @@
386382 if (list_empty(&ife->metalist))
387383 return 0;
388384
389
- nest = nla_nest_start(skb, TCA_IFE_METALST);
385
+ nest = nla_nest_start_noflag(skb, TCA_IFE_METALST);
390386 if (!nest)
391387 goto out_nlmsg_trim;
392388
....@@ -440,6 +436,25 @@
440436 kfree_rcu(p, rcu);
441437 }
442438
439
+static int load_metalist(struct nlattr **tb, bool rtnl_held)
440
+{
441
+ int i;
442
+
443
+ for (i = 1; i < max_metacnt; i++) {
444
+ if (tb[i]) {
445
+ void *val = nla_data(tb[i]);
446
+ int len = nla_len(tb[i]);
447
+ int rc;
448
+
449
+ rc = load_metaops_and_vet(i, val, len, rtnl_held);
450
+ if (rc != 0)
451
+ return rc;
452
+ }
453
+ }
454
+
455
+ return 0;
456
+}
457
+
443458 static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
444459 bool exists, bool rtnl_held)
445460 {
....@@ -453,10 +468,6 @@
453468 val = nla_data(tb[i]);
454469 len = nla_len(tb[i]);
455470
456
- rc = load_metaops_and_vet(i, val, len, rtnl_held);
457
- if (rc != 0)
458
- return rc;
459
-
460471 rc = add_metainfo(ife, i, val, len, exists);
461472 if (rc)
462473 return rc;
....@@ -469,11 +480,13 @@
469480 static int tcf_ife_init(struct net *net, struct nlattr *nla,
470481 struct nlattr *est, struct tc_action **a,
471482 int ovr, int bind, bool rtnl_held,
483
+ struct tcf_proto *tp, u32 flags,
472484 struct netlink_ext_ack *extack)
473485 {
474486 struct tc_action_net *tn = net_generic(net, ife_net_id);
475487 struct nlattr *tb[TCA_IFE_MAX + 1];
476488 struct nlattr *tb2[IFE_META_MAX + 1];
489
+ struct tcf_chain *goto_ch = NULL;
477490 struct tcf_ife_params *p;
478491 struct tcf_ife_info *ife;
479492 u16 ife_type = ETH_P_IFE;
....@@ -490,7 +503,8 @@
490503 return -EINVAL;
491504 }
492505
493
- err = nla_parse_nested(tb, TCA_IFE_MAX, nla, ife_policy, NULL);
506
+ err = nla_parse_nested_deprecated(tb, TCA_IFE_MAX, nla, ife_policy,
507
+ NULL);
494508 if (err < 0)
495509 return err;
496510
....@@ -510,6 +524,21 @@
510524 if (!p)
511525 return -ENOMEM;
512526
527
+ if (tb[TCA_IFE_METALST]) {
528
+ err = nla_parse_nested_deprecated(tb2, IFE_META_MAX,
529
+ tb[TCA_IFE_METALST], NULL,
530
+ NULL);
531
+ if (err) {
532
+ kfree(p);
533
+ return err;
534
+ }
535
+ err = load_metalist(tb2, rtnl_held);
536
+ if (err) {
537
+ kfree(p);
538
+ return err;
539
+ }
540
+ }
541
+
513542 index = parm->index;
514543 err = tcf_idr_check_alloc(tn, &index, a, bind);
515544 if (err < 0) {
....@@ -524,7 +553,7 @@
524553
525554 if (!exists) {
526555 ret = tcf_idr_create(tn, index, est, a, &act_ife_ops,
527
- bind, true);
556
+ bind, true, flags);
528557 if (ret) {
529558 tcf_idr_cleanup(tn, index);
530559 kfree(p);
....@@ -538,6 +567,13 @@
538567 }
539568
540569 ife = to_ife(*a);
570
+ if (ret == ACT_P_CREATED)
571
+ INIT_LIST_HEAD(&ife->metalist);
572
+
573
+ err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
574
+ if (err < 0)
575
+ goto release_idr;
576
+
541577 p->flags = parm->flags;
542578
543579 if (parm->flags & IFE_ENCODE) {
....@@ -563,24 +599,10 @@
563599 p->eth_type = ife_type;
564600 }
565601
566
-
567
- if (ret == ACT_P_CREATED)
568
- INIT_LIST_HEAD(&ife->metalist);
569
-
570602 if (tb[TCA_IFE_METALST]) {
571
- err = nla_parse_nested(tb2, IFE_META_MAX, tb[TCA_IFE_METALST],
572
- NULL, NULL);
573
- if (err) {
574
-metadata_parse_err:
575
- tcf_idr_release(*a, bind);
576
- kfree(p);
577
- return err;
578
- }
579
-
580603 err = populate_metalist(ife, tb2, exists, rtnl_held);
581604 if (err)
582605 goto metadata_parse_err;
583
-
584606 } else {
585607 /* if no passed metadata allow list or passed allow-all
586608 * then here we process by adding as many supported metadatum
....@@ -588,28 +610,31 @@
588610 * going to bail out
589611 */
590612 err = use_all_metadata(ife, exists);
591
- if (err) {
592
- tcf_idr_release(*a, bind);
593
- kfree(p);
594
- return err;
595
- }
613
+ if (err)
614
+ goto metadata_parse_err;
596615 }
597616
598617 if (exists)
599618 spin_lock_bh(&ife->tcf_lock);
600
- ife->tcf_action = parm->action;
601619 /* protected by tcf_lock when modifying existing action */
602
- rcu_swap_protected(ife->params, p, 1);
620
+ goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
621
+ p = rcu_replace_pointer(ife->params, p, 1);
603622
604623 if (exists)
605624 spin_unlock_bh(&ife->tcf_lock);
625
+ if (goto_ch)
626
+ tcf_chain_put_by_act(goto_ch);
606627 if (p)
607628 kfree_rcu(p, rcu);
608629
609
- if (ret == ACT_P_CREATED)
610
- tcf_idr_insert(tn, *a);
611
-
612630 return ret;
631
+metadata_parse_err:
632
+ if (goto_ch)
633
+ tcf_chain_put_by_act(goto_ch);
634
+release_idr:
635
+ kfree(p);
636
+ tcf_idr_release(*a, bind);
637
+ return err;
613638 }
614639
615640 static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
....@@ -862,8 +887,7 @@
862887 return tcf_generic_walker(tn, skb, cb, type, ops, extack);
863888 }
864889
865
-static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index,
866
- struct netlink_ext_ack *extack)
890
+static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index)
867891 {
868892 struct tc_action_net *tn = net_generic(net, ife_net_id);
869893
....@@ -872,7 +896,7 @@
872896
873897 static struct tc_action_ops act_ife_ops = {
874898 .kind = "ife",
875
- .type = TCA_ACT_IFE,
899
+ .id = TCA_ID_IFE,
876900 .owner = THIS_MODULE,
877901 .act = tcf_ife_act,
878902 .dump = tcf_ife_dump,