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

Reply via email to