This patch adds extack handling for the tc_setup_cb_call function which is common used by TC classifier implementations.
Cc: David Ahern <dsah...@gmail.com> Signed-off-by: Alexander Aring <ar...@mojatatu.com> --- include/net/pkt_cls.h | 3 ++- net/sched/cls_api.c | 11 ++++++++--- net/sched/cls_bpf.c | 19 +++++++++++-------- net/sched/cls_flower.c | 11 ++++++----- net/sched/cls_matchall.c | 11 +++++++---- net/sched/cls_u32.c | 20 +++++++++++--------- 6 files changed, 45 insertions(+), 30 deletions(-) diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 2e4b8e436d25..7457232ae59f 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -585,7 +585,8 @@ tcf_match_indev(struct sk_buff *skb, int ifindex) #endif /* CONFIG_NET_CLS_IND */ int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts, - enum tc_setup_type type, void *type_data, bool err_stop); + enum tc_setup_type type, void *type_data, bool err_stop, + struct netlink_ext_ack *extack); enum tc_block_command { TC_BLOCK_BIND, diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 9f88107c29c5..e864ad523800 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -1566,21 +1566,26 @@ static int tc_exts_setup_cb_egdev_call(struct tcf_exts *exts, } int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts, - enum tc_setup_type type, void *type_data, bool err_stop) + enum tc_setup_type type, void *type_data, bool err_stop, + struct netlink_ext_ack *extack) { int ok_count; int ret; ret = tcf_block_cb_call(block, type, type_data, err_stop); - if (ret < 0) + if (ret < 0) { + NL_SET_ERR_MSG(extack, "Failed to initialize tcf block"); return ret; + } ok_count = ret; if (!exts) return ok_count; ret = tc_exts_setup_cb_egdev_call(exts, type, type_data, err_stop); - if (ret < 0) + if (ret < 0) { + NL_SET_ERR_MSG(extack, "Failed to initialize tcf block extensions"); return ret; + } ok_count += ret; return ok_count; diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index fc024fc3ec2f..566befb6ac71 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -147,7 +147,8 @@ static bool cls_bpf_is_ebpf(const struct cls_bpf_prog *prog) } static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, - struct cls_bpf_prog *oldprog) + struct cls_bpf_prog *oldprog, + struct netlink_ext_ack *extack) { struct tcf_block *block = tp->chain->block; struct tc_cls_bpf_offload cls_bpf = {}; @@ -170,10 +171,11 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, if (oldprog) tcf_block_offload_dec(block, &oldprog->gen_flags); - err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw); + err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw, + extack); if (prog) { if (err < 0) { - cls_bpf_offload_cmd(tp, oldprog, prog); + cls_bpf_offload_cmd(tp, oldprog, prog, NULL); return err; } else if (err > 0) { tcf_block_offload_inc(block, &prog->gen_flags); @@ -187,7 +189,8 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, } static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, - struct cls_bpf_prog *oldprog) + struct cls_bpf_prog *oldprog, + struct netlink_ext_ack *extack) { if (prog && oldprog && prog->gen_flags != oldprog->gen_flags) return -EINVAL; @@ -199,7 +202,7 @@ static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, if (!prog && !oldprog) return 0; - return cls_bpf_offload_cmd(tp, prog, oldprog); + return cls_bpf_offload_cmd(tp, prog, oldprog, extack); } static void cls_bpf_stop_offload(struct tcf_proto *tp, @@ -207,7 +210,7 @@ static void cls_bpf_stop_offload(struct tcf_proto *tp, { int err; - err = cls_bpf_offload_cmd(tp, NULL, prog); + err = cls_bpf_offload_cmd(tp, NULL, prog, NULL); if (err) pr_err("Stopping hardware offload failed: %d\n", err); } @@ -226,7 +229,7 @@ static void cls_bpf_offload_update_stats(struct tcf_proto *tp, cls_bpf.exts_integrated = prog->exts_integrated; cls_bpf.gen_flags = prog->gen_flags; - tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, false); + tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, false, NULL); } static int cls_bpf_init(struct tcf_proto *tp) @@ -507,7 +510,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, if (ret < 0) goto errout_idr; - ret = cls_bpf_offload(tp, prog, oldprog); + ret = cls_bpf_offload(tp, prog, oldprog, extack); if (ret) goto errout_parms; diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index c6ac4a612c4a..f160dbccf8a7 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -228,14 +228,15 @@ static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f) cls_flower.cookie = (unsigned long) f; tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER, - &cls_flower, false); + &cls_flower, false, NULL); tcf_block_offload_dec(block, &f->flags); } static int fl_hw_replace_filter(struct tcf_proto *tp, struct flow_dissector *dissector, struct fl_flow_key *mask, - struct cls_fl_filter *f) + struct cls_fl_filter *f, + struct netlink_ext_ack *extack) { struct tc_cls_flower_offload cls_flower = {}; struct tcf_block *block = tp->chain->block; @@ -252,7 +253,7 @@ static int fl_hw_replace_filter(struct tcf_proto *tp, cls_flower.classid = f->res.classid; err = tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER, - &cls_flower, skip_sw); + &cls_flower, skip_sw, extack); if (err < 0) { fl_hw_destroy_filter(tp, f); return err; @@ -278,7 +279,7 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f) cls_flower.classid = f->res.classid; tc_setup_cb_call(block, &f->exts, TC_SETUP_CLSFLOWER, - &cls_flower, false); + &cls_flower, false, NULL); } static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f) @@ -943,7 +944,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, err = fl_hw_replace_filter(tp, &head->dissector, &mask.key, - fnew); + fnew, extack); if (err) goto errout_idr; } diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index f67d3d7fcf40..03f5cd6b7cbd 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -80,13 +80,15 @@ static void mall_destroy_hw_filter(struct tcf_proto *tp, cls_mall.command = TC_CLSMATCHALL_DESTROY; cls_mall.cookie = cookie; - tc_setup_cb_call(block, NULL, TC_SETUP_CLSMATCHALL, &cls_mall, false); + tc_setup_cb_call(block, NULL, TC_SETUP_CLSMATCHALL, &cls_mall, false, + NULL); tcf_block_offload_dec(block, &head->flags); } static int mall_replace_hw_filter(struct tcf_proto *tp, struct cls_mall_head *head, - unsigned long cookie) + unsigned long cookie, + struct netlink_ext_ack *extack) { struct tc_cls_matchall_offload cls_mall = {}; struct tcf_block *block = tp->chain->block; @@ -99,7 +101,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp, cls_mall.cookie = cookie; err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSMATCHALL, - &cls_mall, skip_sw); + &cls_mall, skip_sw, extack); if (err < 0) { mall_destroy_hw_filter(tp, head, cookie); return err; @@ -205,7 +207,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, goto err_set_parms; if (!tc_skip_hw(new->flags)) { - err = mall_replace_hw_filter(tp, new, (unsigned long)new); + err = mall_replace_hw_filter(tp, new, (unsigned long)new, + extack); if (err) goto err_replace_hw_filter; } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index e8963ed35899..8840baa1b9b4 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -497,11 +497,11 @@ static void u32_clear_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h) cls_u32.hnode.handle = h->handle; cls_u32.hnode.prio = h->prio; - tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, false); + tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, false, NULL); } static int u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h, - u32 flags) + u32 flags, struct netlink_ext_ack *extack) { struct tcf_block *block = tp->chain->block; struct tc_cls_u32_offload cls_u32 = {}; @@ -515,7 +515,8 @@ static int u32_replace_hw_hnode(struct tcf_proto *tp, struct tc_u_hnode *h, cls_u32.hnode.handle = h->handle; cls_u32.hnode.prio = h->prio; - err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, skip_sw); + err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, skip_sw, + extack); if (err < 0) { u32_clear_hw_hnode(tp, h); return err; @@ -538,12 +539,12 @@ static void u32_remove_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n) cls_u32.command = TC_CLSU32_DELETE_KNODE; cls_u32.knode.handle = n->handle; - tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, false); + tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, false, NULL); tcf_block_offload_dec(block, &n->flags); } static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n, - u32 flags) + u32 flags, struct netlink_ext_ack *extack) { struct tcf_block *block = tp->chain->block; struct tc_cls_u32_offload cls_u32 = {}; @@ -566,7 +567,8 @@ static int u32_replace_hw_knode(struct tcf_proto *tp, struct tc_u_knode *n, if (n->ht_down) cls_u32.knode.link_handle = n->ht_down->handle; - err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, skip_sw); + err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSU32, &cls_u32, skip_sw, + extack); if (err < 0) { u32_remove_hw_knode(tp, n); return err; @@ -946,7 +948,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, return err; } - err = u32_replace_hw_knode(tp, new, flags); + err = u32_replace_hw_knode(tp, new, flags, extack); if (err) { u32_destroy_key(tp, new, false); return err; @@ -993,7 +995,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, ht->prio = tp->prio; idr_init(&ht->handle_idr); - err = u32_replace_hw_hnode(tp, ht, flags); + err = u32_replace_hw_hnode(tp, ht, flags, extack); if (err) { idr_remove_ext(&tp_c->handle_idr, handle); kfree(ht); @@ -1092,7 +1094,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, struct tc_u_knode __rcu **ins; struct tc_u_knode *pins; - err = u32_replace_hw_knode(tp, n, flags); + err = u32_replace_hw_knode(tp, n, flags, extack); if (err) goto errhw; -- 2.11.0