Commit e4ae004b authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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: default avatarEric 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: default avatarHagen Paul Pfeifer <hagen@jauu.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 18d07000
...@@ -509,6 +509,7 @@ enum { ...@@ -509,6 +509,7 @@ enum {
TCA_NETEM_CORRUPT, TCA_NETEM_CORRUPT,
TCA_NETEM_LOSS, TCA_NETEM_LOSS,
TCA_NETEM_RATE, TCA_NETEM_RATE,
TCA_NETEM_ECN,
__TCA_NETEM_MAX, __TCA_NETEM_MAX,
}; };
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#include <net/inet_ecn.h>
#define VERSION "1.3" #define VERSION "1.3"
...@@ -78,6 +79,7 @@ struct netem_sched_data { ...@@ -78,6 +79,7 @@ struct netem_sched_data {
psched_tdiff_t jitter; psched_tdiff_t jitter;
u32 loss; u32 loss;
u32 ecn;
u32 limit; u32 limit;
u32 counter; u32 counter;
u32 gap; u32 gap;
...@@ -374,9 +376,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -374,9 +376,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
++count; ++count;
/* Drop packet? */ /* Drop packet? */
if (loss_event(q)) if (loss_event(q)) {
--count; if (q->ecn && INET_ECN_set_ce(skb))
sch->qstats.drops++; /* mark packet */
else
--count;
}
if (count == 0) { if (count == 0) {
sch->qstats.drops++; sch->qstats.drops++;
kfree_skb(skb); kfree_skb(skb);
...@@ -706,6 +711,7 @@ static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = { ...@@ -706,6 +711,7 @@ static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
[TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) }, [TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) },
[TCA_NETEM_RATE] = { .len = sizeof(struct tc_netem_rate) }, [TCA_NETEM_RATE] = { .len = sizeof(struct tc_netem_rate) },
[TCA_NETEM_LOSS] = { .type = NLA_NESTED }, [TCA_NETEM_LOSS] = { .type = NLA_NESTED },
[TCA_NETEM_ECN] = { .type = NLA_U32 },
}; };
static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, static 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,6 +782,9 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
if (tb[TCA_NETEM_RATE]) if (tb[TCA_NETEM_RATE])
get_rate(sch, tb[TCA_NETEM_RATE]); get_rate(sch, tb[TCA_NETEM_RATE]);
if (tb[TCA_NETEM_ECN])
q->ecn = nla_get_u32(tb[TCA_NETEM_ECN]);
q->loss_model = CLG_RANDOM; q->loss_model = CLG_RANDOM;
if (tb[TCA_NETEM_LOSS]) if (tb[TCA_NETEM_LOSS])
ret = get_loss_clg(sch, tb[TCA_NETEM_LOSS]); 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,6 +911,9 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
if (nla_put(skb, TCA_NETEM_RATE, sizeof(rate), &rate)) if (nla_put(skb, TCA_NETEM_RATE, sizeof(rate), &rate))
goto nla_put_failure; goto nla_put_failure;
if (q->ecn && nla_put_u32(skb, TCA_NETEM_ECN, q->ecn))
goto nla_put_failure;
if (dump_loss_model(q, skb) != 0) if (dump_loss_model(q, skb) != 0)
goto nla_put_failure; goto nla_put_failure;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment