This patch adds extack support for the function qdisc_get_rtab which is
a common used function in the tc subsystem. Callers which are interested
in the receiving error can assign extack to get a more detailed
information why qdisc_get_rtab failed.

Cc: David Ahern <dsah...@gmail.com>
Acked-by: Jamal Hadi Salim <j...@mojatatu.com>
Signed-off-by: Alexander Aring <ar...@mojatatu.com>
---
 include/net/pkt_sched.h | 3 ++-
 net/sched/act_police.c  | 4 ++--
 net/sched/sch_api.c     | 9 +++++++--
 net/sched/sch_cbq.c     | 7 ++++---
 net/sched/sch_htb.c     | 6 ++++--
 net/sched/sch_tbf.c     | 6 ++++--
 6 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 240469228851..a4f21c0b4a43 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -101,7 +101,8 @@ void qdisc_hash_del(struct Qdisc *q);
 struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
 struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
-                                       struct nlattr *tab);
+                                       struct nlattr *tab,
+                                       struct netlink_ext_ack *extack);
 void qdisc_put_rtab(struct qdisc_rate_table *tab);
 void qdisc_put_stab(struct qdisc_size_table *tab);
 void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index bf483db993a1..95d3c9097b25 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -118,13 +118,13 @@ static int tcf_act_police_init(struct net *net, struct 
nlattr *nla,
        police = to_police(*a);
        if (parm->rate.rate) {
                err = -ENOMEM;
-               R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]);
+               R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE], NULL);
                if (R_tab == NULL)
                        goto failure;
 
                if (parm->peakrate.rate) {
                        P_tab = qdisc_get_rtab(&parm->peakrate,
-                                              tb[TCA_POLICE_PEAKRATE]);
+                                              tb[TCA_POLICE_PEAKRATE], NULL);
                        if (P_tab == NULL)
                                goto failure;
                }
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 4b950d72d13b..79a9fdf9471d 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -393,13 +393,16 @@ static __u8 __detect_linklayer(struct tc_ratespec *r, 
__u32 *rtab)
 static struct qdisc_rate_table *qdisc_rtab_list;
 
 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
-                                       struct nlattr *tab)
+                                       struct nlattr *tab,
+                                       struct netlink_ext_ack *extack)
 {
        struct qdisc_rate_table *rtab;
 
        if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
-           nla_len(tab) != TC_RTAB_SIZE)
+           nla_len(tab) != TC_RTAB_SIZE) {
+               NL_SET_ERR_MSG(extack, "Invalid rate table parameters for 
searching");
                return NULL;
+       }
 
        for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
                if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
@@ -418,6 +421,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec 
*r,
                        r->linklayer = __detect_linklayer(r, rtab->data);
                rtab->next = qdisc_rtab_list;
                qdisc_rtab_list = rtab;
+       } else {
+               NL_SET_ERR_MSG(extack, "Failed to allocate new qdisc rate 
table");
        }
        return rtab;
 }
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index bb7e4ccd7caf..79f081eb6bb0 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1156,7 +1156,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
 
        r = nla_data(tb[TCA_CBQ_RATE]);
 
-       q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB]);
+       q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB], extack);
        if (!q->link.R_tab)
                return -EINVAL;
 
@@ -1484,7 +1484,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 
parentid, struct nlattr **t
 
                if (tb[TCA_CBQ_RATE]) {
                        rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]),
-                                             tb[TCA_CBQ_RTAB]);
+                                             tb[TCA_CBQ_RTAB], extack);
                        if (rtab == NULL)
                                return -EINVAL;
                }
@@ -1537,7 +1537,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 
parentid, struct nlattr **t
        if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT])
                return -EINVAL;
 
-       rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
+       rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB],
+                             extack);
        if (rtab == NULL)
                return -EINVAL;
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 65762d57a70d..51be1b756e4e 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1357,10 +1357,12 @@ static int htb_change_class(struct Qdisc *sch, u32 
classid,
 
        /* Keeping backward compatible with rate_table based iproute2 tc */
        if (hopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
-               qdisc_put_rtab(qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]));
+               qdisc_put_rtab(qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB],
+                                             NULL));
 
        if (hopt->ceil.linklayer == TC_LINKLAYER_UNAWARE)
-               qdisc_put_rtab(qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]));
+               qdisc_put_rtab(qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB],
+                                             NULL));
 
        if (!cl) {              /* new class */
                struct Qdisc *new_q;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index db6bd23530d4..1ab53ff80f46 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -327,11 +327,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr 
*opt,
        qopt = nla_data(tb[TCA_TBF_PARMS]);
        if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
                qdisc_put_rtab(qdisc_get_rtab(&qopt->rate,
-                                             tb[TCA_TBF_RTAB]));
+                                             tb[TCA_TBF_RTAB],
+                                             NULL));
 
        if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE)
                        qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate,
-                                                     tb[TCA_TBF_PTAB]));
+                                                     tb[TCA_TBF_PTAB],
+                                                     NULL));
 
        buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);
        mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U);
-- 
2.11.0

Reply via email to