aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/pkt_sched.h1
-rw-r--r--net/sched/sch_netem.c18
2 files changed, 16 insertions, 3 deletions
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 410b33d014d2..ffe975c3f1d8 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -509,6 +509,7 @@ enum {
509 TCA_NETEM_CORRUPT, 509 TCA_NETEM_CORRUPT,
510 TCA_NETEM_LOSS, 510 TCA_NETEM_LOSS,
511 TCA_NETEM_RATE, 511 TCA_NETEM_RATE,
512 TCA_NETEM_ECN,
512 __TCA_NETEM_MAX, 513 __TCA_NETEM_MAX,
513}; 514};
514 515
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