Skip to content

Commit

Permalink
net_sched: make cls_ops->change and cls_ops->delete optional
Browse files Browse the repository at this point in the history
Some schedulers don't support creating, changing or deleting classes.
Make the respective callbacks optionally and consistently return
-EOPNOTSUPP for unsupported operations, instead of currently either
-EOPNOTSUPP, -ENOSYS or no error.

In case of sch_prio and sch_multiq, the removed operations additionally
checked for an invalid class. This is not necessary since the class
argument can only orginate from ->get() or in case of ->change is 0
for creation of new classes, in which case ->change() incorrectly
returned -ENOENT.

As a side-effect, this patch fixes a possible (root-only) NULL pointer
function call in sch_ingress, which didn't implement a so far mandatory
->delete() operation.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Sep 6, 2009
1 parent 71ebe5e commit de6d5cd
Show file tree
Hide file tree
Showing 7 changed files with 6 additions and 85 deletions.
8 changes: 6 additions & 2 deletions net/sched/sch_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1417,7 +1417,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
goto out;
break;
case RTM_DELTCLASS:
err = cops->delete(q, cl);
err = -EOPNOTSUPP;
if (cops->delete)
err = cops->delete(q, cl);
if (err == 0)
tclass_notify(skb, n, q, cl, RTM_DELTCLASS);
goto out;
Expand All @@ -1431,7 +1433,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
}

new_cl = cl;
err = cops->change(q, clid, pid, tca, &new_cl);
err = -EOPNOTSUPP;
if (cops->change)
err = cops->change(q, clid, pid, tca, &new_cl);
if (err == 0)
tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS);

Expand Down
7 changes: 0 additions & 7 deletions net/sched/sch_ingress.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ static void ingress_put(struct Qdisc *sch, unsigned long cl)
{
}

static int ingress_change(struct Qdisc *sch, u32 classid, u32 parent,
struct nlattr **tca, unsigned long *arg)
{
return 0;
}

static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{
return;
Expand Down Expand Up @@ -120,7 +114,6 @@ static const struct Qdisc_class_ops ingress_class_ops = {
.leaf = ingress_leaf,
.get = ingress_get,
.put = ingress_put,
.change = ingress_change,
.walk = ingress_walk,
.tcf_chain = ingress_find_tcf,
.bind_tcf = ingress_bind_filter,
Expand Down
22 changes: 0 additions & 22 deletions net/sched/sch_multiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,26 +348,6 @@ static void multiq_put(struct Qdisc *q, unsigned long cl)
return;
}

static int multiq_change(struct Qdisc *sch, u32 handle, u32 parent,
struct nlattr **tca, unsigned long *arg)
{
unsigned long cl = *arg;
struct multiq_sched_data *q = qdisc_priv(sch);

if (cl - 1 > q->bands)
return -ENOENT;
return 0;
}

static int multiq_delete(struct Qdisc *sch, unsigned long cl)
{
struct multiq_sched_data *q = qdisc_priv(sch);
if (cl - 1 > q->bands)
return -ENOENT;
return 0;
}


static int multiq_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm)
{
Expand Down Expand Up @@ -430,8 +410,6 @@ static const struct Qdisc_class_ops multiq_class_ops = {
.leaf = multiq_leaf,
.get = multiq_get,
.put = multiq_put,
.change = multiq_change,
.delete = multiq_delete,
.walk = multiq_walk,
.tcf_chain = multiq_find_tcf,
.bind_tcf = multiq_bind,
Expand Down
21 changes: 0 additions & 21 deletions net/sched/sch_prio.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,25 +311,6 @@ static void prio_put(struct Qdisc *q, unsigned long cl)
return;
}

static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct nlattr **tca, unsigned long *arg)
{
unsigned long cl = *arg;
struct prio_sched_data *q = qdisc_priv(sch);

if (cl - 1 > q->bands)
return -ENOENT;
return 0;
}

static int prio_delete(struct Qdisc *sch, unsigned long cl)
{
struct prio_sched_data *q = qdisc_priv(sch);
if (cl - 1 > q->bands)
return -ENOENT;
return 0;
}


static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb,
struct tcmsg *tcm)
{
Expand Down Expand Up @@ -392,8 +373,6 @@ static const struct Qdisc_class_ops prio_class_ops = {
.leaf = prio_leaf,
.get = prio_get,
.put = prio_put,
.change = prio_change,
.delete = prio_delete,
.walk = prio_walk,
.tcf_chain = prio_find_tcf,
.bind_tcf = prio_bind,
Expand Down
13 changes: 0 additions & 13 deletions net/sched/sch_red.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,17 +308,6 @@ static void red_put(struct Qdisc *sch, unsigned long arg)
return;
}

static int red_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
return -ENOSYS;
}

static int red_delete(struct Qdisc *sch, unsigned long cl)
{
return -ENOSYS;
}

static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{
if (!walker->stop) {
Expand All @@ -336,8 +325,6 @@ static const struct Qdisc_class_ops red_class_ops = {
.leaf = red_leaf,
.get = red_get,
.put = red_put,
.change = red_change_class,
.delete = red_delete,
.walk = red_walk,
.dump = red_dump_class,
};
Expand Down
7 changes: 0 additions & 7 deletions net/sched/sch_sfq.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,12 +496,6 @@ static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
return -1;
}

static int sfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
return -EOPNOTSUPP;
}

static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
{
return 0;
Expand Down Expand Up @@ -560,7 +554,6 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)

static const struct Qdisc_class_ops sfq_class_ops = {
.get = sfq_get,
.change = sfq_change_class,
.tcf_chain = sfq_find_tcf,
.dump = sfq_dump_class,
.dump_stats = sfq_dump_class_stats,
Expand Down
13 changes: 0 additions & 13 deletions net/sched/sch_tbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,17 +410,6 @@ static void tbf_put(struct Qdisc *sch, unsigned long arg)
{
}

static int tbf_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
return -ENOSYS;
}

static int tbf_delete(struct Qdisc *sch, unsigned long arg)
{
return -ENOSYS;
}

static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
{
if (!walker->stop) {
Expand All @@ -439,8 +428,6 @@ static const struct Qdisc_class_ops tbf_class_ops =
.leaf = tbf_leaf,
.get = tbf_get,
.put = tbf_put,
.change = tbf_change_class,
.delete = tbf_delete,
.walk = tbf_walk,
.dump = tbf_dump_class,
};
Expand Down

0 comments on commit de6d5cd

Please sign in to comment.