aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_netem.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-04-30 19:11:05 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-01 09:39:48 -0400
commite4ae004b84b315dd4b762e474f97403eac70f76a (patch)
treec1f514987070e02c4792a84d0d5417dfa288a8cb /net/sched/sch_netem.c
parent18d0700024d68a075c507b845d85eda2abb5aee7 (diff)
netem: add ECN capability
Add ECN (Explicit Congestion Notification) marking capability to netem tc qdisc add dev eth0 root netem drop 0.5 ecn Instead of dropping packets, try to ECN mark them. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Neal Cardwell <ncardwell@google.com> Cc: Tom Herbert <therbert@google.com> Cc: Hagen Paul Pfeifer <hagen@jauu.net> Cc: Stephen Hemminger <shemminger@vyatta.com> Acked-by: Hagen Paul Pfeifer <hagen@jauu.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_netem.c')
-rw-r--r--net/sched/sch_netem.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 110973145a4b..231cd11aa6e2 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -26,6 +26,7 @@
26 26
27#include <net/netlink.h> 27#include <net/netlink.h>
28#include <net/pkt_sched.h> 28#include <net/pkt_sched.h>
29#include <net/inet_ecn.h>
29 30
30#define VERSION "1.3" 31#define VERSION "1.3"
31 32
@@ -78,6 +79,7 @@ struct netem_sched_data {
78 psched_tdiff_t jitter; 79 psched_tdiff_t jitter;
79 80
80 u32 loss; 81 u32 loss;
82 u32 ecn;
81 u32 limit; 83 u32 limit;
82 u32 counter; 84 u32 counter;
83 u32 gap; 85 u32 gap;
@@ -374,9 +376,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
374 ++count; 376 ++count;
375 377
376 /* Drop packet? */ 378 /* Drop packet? */
377 if (loss_event(q)) 379 if (loss_event(q)) {
378 --count; 380 if (q->ecn && INET_ECN_set_ce(skb))
379 381 sch->qstats.drops++; /* mark packet */
382 else
383 --count;
384 }
380 if (count == 0) { 385 if (count == 0) {
381 sch->qstats.drops++; 386 sch->qstats.drops++;
382 kfree_skb(skb); 387 kfree_skb(skb);
@@ -706,6 +711,7 @@ static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
706 [TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) }, 711 [TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) },
707 [TCA_NETEM_RATE] = { .len = sizeof(struct tc_netem_rate) }, 712 [TCA_NETEM_RATE] = { .len = sizeof(struct tc_netem_rate) },
708 [TCA_NETEM_LOSS] = { .type = NLA_NESTED }, 713 [TCA_NETEM_LOSS] = { .type = NLA_NESTED },
714 [TCA_NETEM_ECN] = { .type = NLA_U32 },
709}; 715};
710 716
711static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, 717static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
@@ -776,6 +782,9 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
776 if (tb[TCA_NETEM_RATE]) 782 if (tb[TCA_NETEM_RATE])
777 get_rate(sch, tb[TCA_NETEM_RATE]); 783 get_rate(sch, tb[TCA_NETEM_RATE]);
778 784
785 if (tb[TCA_NETEM_ECN])
786 q->ecn = nla_get_u32(tb[TCA_NETEM_ECN]);
787
779 q->loss_model = CLG_RANDOM; 788 q->loss_model = CLG_RANDOM;
780 if (tb[TCA_NETEM_LOSS]) 789 if (tb[TCA_NETEM_LOSS])
781 ret = get_loss_clg(sch, tb[TCA_NETEM_LOSS]); 790 ret = get_loss_clg(sch, tb[TCA_NETEM_LOSS]);
@@ -902,6 +911,9 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
902 if (nla_put(skb, TCA_NETEM_RATE, sizeof(rate), &rate)) 911 if (nla_put(skb, TCA_NETEM_RATE, sizeof(rate), &rate))
903 goto nla_put_failure; 912 goto nla_put_failure;
904 913
914 if (q->ecn && nla_put_u32(skb, TCA_NETEM_ECN, q->ecn))
915 goto nla_put_failure;
916
905 if (dump_loss_model(q, skb) != 0) 917 if (dump_loss_model(q, skb) != 0)
906 goto nla_put_failure; 918 goto nla_put_failure;
907 919