hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/cls_bpf.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Berkeley Packet Filter based traffic classifier
34 *
....@@ -6,10 +7,6 @@
67 * ematches.
78 *
89 * (C) 2013 Daniel Borkmann <dborkman@redhat.com>
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License version 2 as
12
- * published by the Free Software Foundation.
1310 */
1411
1512 #include <linux/module.h>
....@@ -157,8 +154,7 @@
157154 skip_sw = prog && tc_skip_sw(prog->gen_flags);
158155 obj = prog ?: oldprog;
159156
160
- tc_cls_common_offload_init(&cls_bpf.common, tp, obj->gen_flags,
161
- extack);
157
+ tc_cls_common_offload_init(&cls_bpf.common, tp, obj->gen_flags, extack);
162158 cls_bpf.command = TC_CLSBPF_OFFLOAD;
163159 cls_bpf.exts = &obj->exts;
164160 cls_bpf.prog = prog ? prog->filter : NULL;
....@@ -166,18 +162,24 @@
166162 cls_bpf.name = obj->bpf_name;
167163 cls_bpf.exts_integrated = obj->exts_integrated;
168164
169
- if (oldprog)
170
- tcf_block_offload_dec(block, &oldprog->gen_flags);
165
+ if (oldprog && prog)
166
+ err = tc_setup_cb_replace(block, tp, TC_SETUP_CLSBPF, &cls_bpf,
167
+ skip_sw, &oldprog->gen_flags,
168
+ &oldprog->in_hw_count,
169
+ &prog->gen_flags, &prog->in_hw_count,
170
+ true);
171
+ else if (prog)
172
+ err = tc_setup_cb_add(block, tp, TC_SETUP_CLSBPF, &cls_bpf,
173
+ skip_sw, &prog->gen_flags,
174
+ &prog->in_hw_count, true);
175
+ else
176
+ err = tc_setup_cb_destroy(block, tp, TC_SETUP_CLSBPF, &cls_bpf,
177
+ skip_sw, &oldprog->gen_flags,
178
+ &oldprog->in_hw_count, true);
171179
172
- err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw);
173
- if (prog) {
174
- if (err < 0) {
175
- cls_bpf_offload_cmd(tp, oldprog, prog, extack);
176
- return err;
177
- } else if (err > 0) {
178
- prog->in_hw_count = err;
179
- tcf_block_offload_inc(block, &prog->gen_flags);
180
- }
180
+ if (prog && err) {
181
+ cls_bpf_offload_cmd(tp, oldprog, prog, extack);
182
+ return err;
181183 }
182184
183185 if (prog && skip_sw && !(prog->gen_flags & TCA_CLS_FLAGS_IN_HW))
....@@ -234,7 +236,7 @@
234236 cls_bpf.name = prog->bpf_name;
235237 cls_bpf.exts_integrated = prog->exts_integrated;
236238
237
- tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, false);
239
+ tc_setup_cb_call(block, TC_SETUP_CLSBPF, &cls_bpf, false, true);
238240 }
239241
240242 static int cls_bpf_init(struct tcf_proto *tp)
....@@ -298,7 +300,7 @@
298300 }
299301
300302 static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last,
301
- struct netlink_ext_ack *extack)
303
+ bool rtnl_held, struct netlink_ext_ack *extack)
302304 {
303305 struct cls_bpf_head *head = rtnl_dereference(tp->root);
304306
....@@ -307,7 +309,7 @@
307309 return 0;
308310 }
309311
310
-static void cls_bpf_destroy(struct tcf_proto *tp,
312
+static void cls_bpf_destroy(struct tcf_proto *tp, bool rtnl_held,
311313 struct netlink_ext_ack *extack)
312314 {
313315 struct cls_bpf_head *head = rtnl_dereference(tp->root);
....@@ -417,7 +419,8 @@
417419 if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
418420 return -EINVAL;
419421
420
- ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr, extack);
422
+ ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr, true,
423
+ extack);
421424 if (ret < 0)
422425 return ret;
423426
....@@ -455,7 +458,8 @@
455458 static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
456459 struct tcf_proto *tp, unsigned long base,
457460 u32 handle, struct nlattr **tca,
458
- void **arg, bool ovr, struct netlink_ext_ack *extack)
461
+ void **arg, bool ovr, bool rtnl_held,
462
+ struct netlink_ext_ack *extack)
459463 {
460464 struct cls_bpf_head *head = rtnl_dereference(tp->root);
461465 struct cls_bpf_prog *oldprog = *arg;
....@@ -466,8 +470,8 @@
466470 if (tca[TCA_OPTIONS] == NULL)
467471 return -EINVAL;
468472
469
- ret = nla_parse_nested(tb, TCA_BPF_MAX, tca[TCA_OPTIONS], bpf_policy,
470
- NULL);
473
+ ret = nla_parse_nested_deprecated(tb, TCA_BPF_MAX, tca[TCA_OPTIONS],
474
+ bpf_policy, NULL);
471475 if (ret < 0)
472476 return ret;
473477
....@@ -475,7 +479,7 @@
475479 if (!prog)
476480 return -ENOBUFS;
477481
478
- ret = tcf_exts_init(&prog->exts, TCA_BPF_ACT, TCA_BPF_POLICE);
482
+ ret = tcf_exts_init(&prog->exts, net, TCA_BPF_ACT, TCA_BPF_POLICE);
479483 if (ret < 0)
480484 goto errout;
481485
....@@ -575,7 +579,7 @@
575579 }
576580
577581 static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, void *fh,
578
- struct sk_buff *skb, struct tcmsg *tm)
582
+ struct sk_buff *skb, struct tcmsg *tm, bool rtnl_held)
579583 {
580584 struct cls_bpf_prog *prog = fh;
581585 struct nlattr *nest;
....@@ -589,7 +593,7 @@
589593
590594 cls_bpf_offload_update_stats(tp, prog);
591595
592
- nest = nla_nest_start(skb, TCA_OPTIONS);
596
+ nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
593597 if (nest == NULL)
594598 goto nla_put_failure;
595599
....@@ -640,7 +644,8 @@
640644 }
641645 }
642646
643
-static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg)
647
+static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg,
648
+ bool rtnl_held)
644649 {
645650 struct cls_bpf_head *head = rtnl_dereference(tp->root);
646651 struct cls_bpf_prog *prog;
....@@ -657,7 +662,7 @@
657662 }
658663 }
659664
660
-static int cls_bpf_reoffload(struct tcf_proto *tp, bool add, tc_setup_cb_t *cb,
665
+static int cls_bpf_reoffload(struct tcf_proto *tp, bool add, flow_setup_cb_t *cb,
661666 void *cb_priv, struct netlink_ext_ack *extack)
662667 {
663668 struct cls_bpf_head *head = rtnl_dereference(tp->root);
....@@ -679,15 +684,11 @@
679684 cls_bpf.name = prog->bpf_name;
680685 cls_bpf.exts_integrated = prog->exts_integrated;
681686
682
- err = cb(TC_SETUP_CLSBPF, &cls_bpf, cb_priv);
683
- if (err) {
684
- if (add && tc_skip_sw(prog->gen_flags))
685
- return err;
686
- continue;
687
- }
688
-
689
- tc_cls_offload_cnt_update(block, &prog->in_hw_count,
690
- &prog->gen_flags, add);
687
+ err = tc_setup_cb_reoffload(block, tp, add, cb, TC_SETUP_CLSBPF,
688
+ &cls_bpf, cb_priv, &prog->gen_flags,
689
+ &prog->in_hw_count);
690
+ if (err)
691
+ return err;
691692 }
692693
693694 return 0;