Commit e9bc3fa2 authored by Alexander Aring's avatar Alexander Aring Committed by David S. Miller

net: sch: api: add extack support in qdisc_get_rtab

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 <dsahern@gmail.com>
Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarAlexander Aring <aring@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 653d6fd6
...@@ -101,7 +101,8 @@ void qdisc_hash_del(struct Qdisc *q); ...@@ -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(struct net_device *dev, u32 handle);
struct Qdisc *qdisc_lookup_class(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 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_rtab(struct qdisc_rate_table *tab);
void qdisc_put_stab(struct qdisc_size_table *tab); void qdisc_put_stab(struct qdisc_size_table *tab);
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc); void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
......
...@@ -118,13 +118,13 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, ...@@ -118,13 +118,13 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
police = to_police(*a); police = to_police(*a);
if (parm->rate.rate) { if (parm->rate.rate) {
err = -ENOMEM; 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) if (R_tab == NULL)
goto failure; goto failure;
if (parm->peakrate.rate) { if (parm->peakrate.rate) {
P_tab = qdisc_get_rtab(&parm->peakrate, P_tab = qdisc_get_rtab(&parm->peakrate,
tb[TCA_POLICE_PEAKRATE]); tb[TCA_POLICE_PEAKRATE], NULL);
if (P_tab == NULL) if (P_tab == NULL)
goto failure; goto failure;
} }
......
...@@ -393,13 +393,16 @@ static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab) ...@@ -393,13 +393,16 @@ static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab)
static struct qdisc_rate_table *qdisc_rtab_list; static struct qdisc_rate_table *qdisc_rtab_list;
struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, 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; struct qdisc_rate_table *rtab;
if (tab == NULL || r->rate == 0 || r->cell_log == 0 || 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; return NULL;
}
for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) && if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
...@@ -418,6 +421,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, ...@@ -418,6 +421,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
r->linklayer = __detect_linklayer(r, rtab->data); r->linklayer = __detect_linklayer(r, rtab->data);
rtab->next = qdisc_rtab_list; rtab->next = qdisc_rtab_list;
qdisc_rtab_list = rtab; qdisc_rtab_list = rtab;
} else {
NL_SET_ERR_MSG(extack, "Failed to allocate new qdisc rate table");
} }
return rtab; return rtab;
} }
......
...@@ -1156,7 +1156,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt, ...@@ -1156,7 +1156,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
r = nla_data(tb[TCA_CBQ_RATE]); 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) if (!q->link.R_tab)
return -EINVAL; return -EINVAL;
...@@ -1484,7 +1484,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t ...@@ -1484,7 +1484,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
if (tb[TCA_CBQ_RATE]) { if (tb[TCA_CBQ_RATE]) {
rtab = qdisc_get_rtab(nla_data(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) if (rtab == NULL)
return -EINVAL; return -EINVAL;
} }
...@@ -1537,7 +1537,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t ...@@ -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]) if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT])
return -EINVAL; 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) if (rtab == NULL)
return -EINVAL; return -EINVAL;
......
...@@ -1357,10 +1357,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, ...@@ -1357,10 +1357,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
/* Keeping backward compatible with rate_table based iproute2 tc */ /* Keeping backward compatible with rate_table based iproute2 tc */
if (hopt->rate.linklayer == TC_LINKLAYER_UNAWARE) 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) 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 */ if (!cl) { /* new class */
struct Qdisc *new_q; struct Qdisc *new_q;
......
...@@ -327,11 +327,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt, ...@@ -327,11 +327,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
qopt = nla_data(tb[TCA_TBF_PARMS]); qopt = nla_data(tb[TCA_TBF_PARMS]);
if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE) if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
qdisc_put_rtab(qdisc_get_rtab(&qopt->rate, qdisc_put_rtab(qdisc_get_rtab(&qopt->rate,
tb[TCA_TBF_RTAB])); tb[TCA_TBF_RTAB],
NULL));
if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE) if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE)
qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate, 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); buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);
mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment