diff options
author | Patrick McHardy <trash@kaber.net> | 2007-07-30 20:11:50 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-31 05:28:19 -0400 |
commit | ffc8fefaf289fa485bc5c33e71572e6ce559d569 (patch) | |
tree | d96daba747cb1da1d4b352a4572965d2788e2f0a /net | |
parent | bdba91ec70fb5ccbdeb1c7068319adc6ea9e1a7d (diff) |
[NET]: Fix sch_api to properly set sch->parent on the root.
Fix sch_api to correctly set sch->parent for both ingress and egress
qdiscs in qdisc_create().
Signed-off-by: Patrick McHardy <trash@kaber.net>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/sch_api.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 13c09bc32aa3..dee0d5fb39c5 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -380,6 +380,10 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
380 | return; | 380 | return; |
381 | while ((parentid = sch->parent)) { | 381 | while ((parentid = sch->parent)) { |
382 | sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid)); | 382 | sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid)); |
383 | if (sch == NULL) { | ||
384 | WARN_ON(parentid != TC_H_ROOT); | ||
385 | return; | ||
386 | } | ||
383 | cops = sch->ops->cl_ops; | 387 | cops = sch->ops->cl_ops; |
384 | if (cops->qlen_notify) { | 388 | if (cops->qlen_notify) { |
385 | cl = cops->get(sch, parentid); | 389 | cl = cops->get(sch, parentid); |
@@ -420,8 +424,6 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
420 | unsigned long cl = cops->get(parent, classid); | 424 | unsigned long cl = cops->get(parent, classid); |
421 | if (cl) { | 425 | if (cl) { |
422 | err = cops->graft(parent, cl, new, old); | 426 | err = cops->graft(parent, cl, new, old); |
423 | if (new) | ||
424 | new->parent = classid; | ||
425 | cops->put(parent, cl); | 427 | cops->put(parent, cl); |
426 | } | 428 | } |
427 | } | 429 | } |
@@ -436,7 +438,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, | |||
436 | */ | 438 | */ |
437 | 439 | ||
438 | static struct Qdisc * | 440 | static struct Qdisc * |
439 | qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) | 441 | qdisc_create(struct net_device *dev, u32 parent, u32 handle, |
442 | struct rtattr **tca, int *errp) | ||
440 | { | 443 | { |
441 | int err; | 444 | int err; |
442 | struct rtattr *kind = tca[TCA_KIND-1]; | 445 | struct rtattr *kind = tca[TCA_KIND-1]; |
@@ -482,6 +485,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) | |||
482 | goto err_out2; | 485 | goto err_out2; |
483 | } | 486 | } |
484 | 487 | ||
488 | sch->parent = parent; | ||
489 | |||
485 | if (handle == TC_H_INGRESS) { | 490 | if (handle == TC_H_INGRESS) { |
486 | sch->flags |= TCQ_F_INGRESS; | 491 | sch->flags |= TCQ_F_INGRESS; |
487 | sch->stats_lock = &dev->ingress_lock; | 492 | sch->stats_lock = &dev->ingress_lock; |
@@ -758,9 +763,11 @@ create_n_graft: | |||
758 | if (!(n->nlmsg_flags&NLM_F_CREATE)) | 763 | if (!(n->nlmsg_flags&NLM_F_CREATE)) |
759 | return -ENOENT; | 764 | return -ENOENT; |
760 | if (clid == TC_H_INGRESS) | 765 | if (clid == TC_H_INGRESS) |
761 | q = qdisc_create(dev, tcm->tcm_parent, tca, &err); | 766 | q = qdisc_create(dev, tcm->tcm_parent, tcm->tcm_parent, |
767 | tca, &err); | ||
762 | else | 768 | else |
763 | q = qdisc_create(dev, tcm->tcm_handle, tca, &err); | 769 | q = qdisc_create(dev, tcm->tcm_parent, tcm->tcm_handle, |
770 | tca, &err); | ||
764 | if (q == NULL) { | 771 | if (q == NULL) { |
765 | if (err == -EAGAIN) | 772 | if (err == -EAGAIN) |
766 | goto replay; | 773 | goto replay; |