aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorstephen hemminger <shemminger@vyatta.com>2011-02-23 08:04:20 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-25 01:11:55 -0500
commit10f6dfcfde884441db89dc66b945d6c948e1d356 (patch)
treee88dbc0763faca774228cf9c2d42faa0cd0c8782 /net/sched
parentdf173bda2639ac744ccf596ec1f8f7e66fe4c343 (diff)
Revert "sch_netem: Remove classful functionality"
Many users have wanted the old functionality that was lost to be able to use pfifo as inner qdisc for netem. The reason that netem could not be classful with the older API was because of the limitations of the old dequeue/requeue interface; now that qdisc API has a peek function, there is no longer a problem with using any inner qdisc's. This reverts commit 02201464119334690fe209849843881b8e9cfa9f. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_netem.c87
1 files changed, 79 insertions, 8 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 289febd3cca..f176890eeef 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -238,14 +238,15 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
238 ret = NET_XMIT_SUCCESS; 238 ret = NET_XMIT_SUCCESS;
239 } 239 }
240 240
241 if (likely(ret == NET_XMIT_SUCCESS)) { 241 if (ret != NET_XMIT_SUCCESS) {
242 sch->q.qlen++; 242 if (net_xmit_drop_count(ret)) {
243 } else if (net_xmit_drop_count(ret)) { 243 sch->qstats.drops++;
244 sch->qstats.drops++; 244 return ret;
245 }
245 } 246 }
246 247
247 pr_debug("netem: enqueue ret %d\n", ret); 248 sch->q.qlen++;
248 return ret; 249 return NET_XMIT_SUCCESS;
249} 250}
250 251
251static unsigned int netem_drop(struct Qdisc *sch) 252static unsigned int netem_drop(struct Qdisc *sch)
@@ -287,9 +288,10 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
287 if (G_TC_FROM(skb->tc_verd) & AT_INGRESS) 288 if (G_TC_FROM(skb->tc_verd) & AT_INGRESS)
288 skb->tstamp.tv64 = 0; 289 skb->tstamp.tv64 = 0;
289#endif 290#endif
290 pr_debug("netem_dequeue: return skb=%p\n", skb); 291
291 qdisc_bstats_update(sch, skb);
292 sch->q.qlen--; 292 sch->q.qlen--;
293 qdisc_unthrottled(sch);
294 qdisc_bstats_update(sch, skb);
293 return skb; 295 return skb;
294 } 296 }
295 297
@@ -610,8 +612,77 @@ nla_put_failure:
610 return -1; 612 return -1;
611} 613}
612 614
615static int netem_dump_class(struct Qdisc *sch, unsigned long cl,
616 struct sk_buff *skb, struct tcmsg *tcm)
617{
618 struct netem_sched_data *q = qdisc_priv(sch);
619
620 if (cl != 1) /* only one class */
621 return -ENOENT;
622
623 tcm->tcm_handle |= TC_H_MIN(1);
624 tcm->tcm_info = q->qdisc->handle;
625
626 return 0;
627}
628
629static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
630 struct Qdisc **old)
631{
632 struct netem_sched_data *q = qdisc_priv(sch);
633
634 if (new == NULL)
635 new = &noop_qdisc;
636
637 sch_tree_lock(sch);
638 *old = q->qdisc;
639 q->qdisc = new;
640 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
641 qdisc_reset(*old);
642 sch_tree_unlock(sch);
643
644 return 0;
645}
646
647static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg)
648{
649 struct netem_sched_data *q = qdisc_priv(sch);
650 return q->qdisc;
651}
652
653static unsigned long netem_get(struct Qdisc *sch, u32 classid)
654{
655 return 1;
656}
657
658static void netem_put(struct Qdisc *sch, unsigned long arg)
659{
660}
661
662static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker)
663{
664 if (!walker->stop) {
665 if (walker->count >= walker->skip)
666 if (walker->fn(sch, 1, walker) < 0) {
667 walker->stop = 1;
668 return;
669 }
670 walker->count++;
671 }
672}
673
674static const struct Qdisc_class_ops netem_class_ops = {
675 .graft = netem_graft,
676 .leaf = netem_leaf,
677 .get = netem_get,
678 .put = netem_put,
679 .walk = netem_walk,
680 .dump = netem_dump_class,
681};
682
613static struct Qdisc_ops netem_qdisc_ops __read_mostly = { 683static struct Qdisc_ops netem_qdisc_ops __read_mostly = {
614 .id = "netem", 684 .id = "netem",
685 .cl_ops = &netem_class_ops,
615 .priv_size = sizeof(struct netem_sched_data), 686 .priv_size = sizeof(struct netem_sched_data),
616 .enqueue = netem_enqueue, 687 .enqueue = netem_enqueue,
617 .dequeue = netem_dequeue, 688 .dequeue = netem_dequeue,