diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_api.c | 17 | ||||
-rw-r--r-- | net/sched/sch_ingress.c | 3 | ||||
-rw-r--r-- | net/sched/sch_prio.c | 13 |
3 files changed, 20 insertions, 13 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 13c09bc32a..dee0d5fb39 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; |
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 51f16b0af1..2d32fd2749 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c | |||
@@ -158,9 +158,8 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch) | |||
158 | break; | 158 | break; |
159 | case TC_ACT_RECLASSIFY: | 159 | case TC_ACT_RECLASSIFY: |
160 | case TC_ACT_OK: | 160 | case TC_ACT_OK: |
161 | case TC_ACT_UNSPEC: | ||
162 | default: | ||
163 | skb->tc_index = TC_H_MIN(res.classid); | 161 | skb->tc_index = TC_H_MIN(res.classid); |
162 | default: | ||
164 | result = TC_ACT_OK; | 163 | result = TC_ACT_OK; |
165 | break; | 164 | break; |
166 | } | 165 | } |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2d8c08493d..4a49db6577 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -38,9 +38,11 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
38 | struct prio_sched_data *q = qdisc_priv(sch); | 38 | struct prio_sched_data *q = qdisc_priv(sch); |
39 | u32 band = skb->priority; | 39 | u32 band = skb->priority; |
40 | struct tcf_result res; | 40 | struct tcf_result res; |
41 | int err; | ||
41 | 42 | ||
42 | *qerr = NET_XMIT_BYPASS; | 43 | *qerr = NET_XMIT_BYPASS; |
43 | if (TC_H_MAJ(skb->priority) != sch->handle) { | 44 | if (TC_H_MAJ(skb->priority) != sch->handle) { |
45 | err = tc_classify(skb, q->filter_list, &res); | ||
44 | #ifdef CONFIG_NET_CLS_ACT | 46 | #ifdef CONFIG_NET_CLS_ACT |
45 | switch (tc_classify(skb, q->filter_list, &res)) { | 47 | switch (tc_classify(skb, q->filter_list, &res)) { |
46 | case TC_ACT_STOLEN: | 48 | case TC_ACT_STOLEN: |
@@ -49,11 +51,8 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
49 | case TC_ACT_SHOT: | 51 | case TC_ACT_SHOT: |
50 | return NULL; | 52 | return NULL; |
51 | } | 53 | } |
52 | |||
53 | if (!q->filter_list ) { | ||
54 | #else | ||
55 | if (!q->filter_list || tc_classify(skb, q->filter_list, &res)) { | ||
56 | #endif | 54 | #endif |
55 | if (!q->filter_list || err < 0) { | ||
57 | if (TC_H_MAJ(band)) | 56 | if (TC_H_MAJ(band)) |
58 | band = 0; | 57 | band = 0; |
59 | band = q->prio2band[band&TC_PRIO_MAX]; | 58 | band = q->prio2band[band&TC_PRIO_MAX]; |
@@ -239,11 +238,13 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) | |||
239 | /* If we're multiqueue, make sure the number of incoming bands | 238 | /* If we're multiqueue, make sure the number of incoming bands |
240 | * matches the number of queues on the device we're associating with. | 239 | * matches the number of queues on the device we're associating with. |
241 | * If the number of bands requested is zero, then set q->bands to | 240 | * If the number of bands requested is zero, then set q->bands to |
242 | * dev->egress_subqueue_count. | 241 | * dev->egress_subqueue_count. Also, the root qdisc must be the |
242 | * only one that is enabled for multiqueue, since it's the only one | ||
243 | * that interacts with the underlying device. | ||
243 | */ | 244 | */ |
244 | q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]); | 245 | q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]); |
245 | if (q->mq) { | 246 | if (q->mq) { |
246 | if (sch->handle != TC_H_ROOT) | 247 | if (sch->parent != TC_H_ROOT) |
247 | return -EINVAL; | 248 | return -EINVAL; |
248 | if (netif_is_multiqueue(sch->dev)) { | 249 | if (netif_is_multiqueue(sch->dev)) { |
249 | if (q->bands == 0) | 250 | if (q->bands == 0) |