Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278306
b: refs/heads/master
c: 7bc0f28
h: refs/heads/master
v: v3
  • Loading branch information
Hagen Paul Pfeifer authored and David S. Miller committed Dec 1, 2011
1 parent 4fc37df commit 1ded314
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 99d2f47aa9d3ad40daa6ee0770e91b95b71082f0
refs/heads/master: 7bc0f28c7a0cd19f40e5a6e4d0a117db9a4e4cd5
5 changes: 5 additions & 0 deletions trunk/include/linux/pkt_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ enum {
TCA_NETEM_REORDER,
TCA_NETEM_CORRUPT,
TCA_NETEM_LOSS,
TCA_NETEM_RATE,
__TCA_NETEM_MAX,
};

Expand Down Expand Up @@ -495,6 +496,10 @@ struct tc_netem_corrupt {
__u32 correlation;
};

struct tc_netem_rate {
__u32 rate; /* byte/s */
};

enum {
NETEM_LOSS_UNSPEC,
NETEM_LOSS_GI, /* General Intuitive - 4 state model */
Expand Down
40 changes: 40 additions & 0 deletions trunk/net/sched/sch_netem.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct netem_sched_data {
u32 duplicate;
u32 reorder;
u32 corrupt;
u32 rate;

struct crndstate {
u32 last;
Expand Down Expand Up @@ -298,6 +299,11 @@ static psched_tdiff_t tabledist(psched_tdiff_t mu, psched_tdiff_t sigma,
return x / NETEM_DIST_SCALE + (sigma / NETEM_DIST_SCALE) * t + mu;
}

static psched_time_t packet_len_2_sched_time(unsigned int len, u32 rate)
{
return PSCHED_NS2TICKS((u64)len * NSEC_PER_SEC / rate);
}

/*
* Insert one skb into qdisc.
* Note: parent depends on return value to account for queue length.
Expand Down Expand Up @@ -371,6 +377,24 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
&q->delay_cor, q->delay_dist);

now = psched_get_time();

if (q->rate) {
struct sk_buff_head *list = &q->qdisc->q;

delay += packet_len_2_sched_time(skb->len, q->rate);

if (!skb_queue_empty(list)) {
/*
* Last packet in queue is reference point (now).
* First packet in queue is already in flight,
* calculate this time bonus and substract
* from delay.
*/
delay -= now - netem_skb_cb(skb_peek(list))->time_to_send;
now = netem_skb_cb(skb_peek_tail(list))->time_to_send;
}
}

cb->time_to_send = now + delay;
++q->counter;
ret = qdisc_enqueue(skb, q->qdisc);
Expand Down Expand Up @@ -535,6 +559,14 @@ static void get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
init_crandom(&q->corrupt_cor, r->correlation);
}

static void get_rate(struct Qdisc *sch, const struct nlattr *attr)
{
struct netem_sched_data *q = qdisc_priv(sch);
const struct tc_netem_rate *r = nla_data(attr);

q->rate = r->rate;
}

static int get_loss_clg(struct Qdisc *sch, const struct nlattr *attr)
{
struct netem_sched_data *q = qdisc_priv(sch);
Expand Down Expand Up @@ -594,6 +626,7 @@ static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
[TCA_NETEM_CORR] = { .len = sizeof(struct tc_netem_corr) },
[TCA_NETEM_REORDER] = { .len = sizeof(struct tc_netem_reorder) },
[TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) },
[TCA_NETEM_RATE] = { .len = sizeof(struct tc_netem_rate) },
[TCA_NETEM_LOSS] = { .type = NLA_NESTED },
};

Expand Down Expand Up @@ -666,6 +699,9 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
if (tb[TCA_NETEM_CORRUPT])
get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);

if (tb[TCA_NETEM_RATE])
get_rate(sch, tb[TCA_NETEM_RATE]);

q->loss_model = CLG_RANDOM;
if (tb[TCA_NETEM_LOSS])
ret = get_loss_clg(sch, tb[TCA_NETEM_LOSS]);
Expand Down Expand Up @@ -846,6 +882,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
struct tc_netem_corr cor;
struct tc_netem_reorder reorder;
struct tc_netem_corrupt corrupt;
struct tc_netem_rate rate;

qopt.latency = q->latency;
qopt.jitter = q->jitter;
Expand All @@ -868,6 +905,9 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
corrupt.correlation = q->corrupt_cor.rho;
NLA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);

rate.rate = q->rate;
NLA_PUT(skb, TCA_NETEM_RATE, sizeof(rate), &rate);

if (dump_loss_model(q, skb) != 0)
goto nla_put_failure;

Expand Down

0 comments on commit 1ded314

Please sign in to comment.