Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 1449
b: refs/heads/master
c: 0dca51d
h: refs/heads/master
i:
  1447: 3dd9b84
v: v3
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed May 26, 2005
1 parent 3e29713 commit e1e411f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f9f32ac65ee4a452a912a8440cebbc4dff73852
refs/heads/master: 0dca51d362b8e4af6b0dbc9e54d1e5165341918a
9 changes: 8 additions & 1 deletion trunk/include/linux/pkt_sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ enum
TCA_NETEM_UNSPEC,
TCA_NETEM_CORR,
TCA_NETEM_DELAY_DIST,
TCA_NETEM_REORDER,
__TCA_NETEM_MAX,
};

Expand All @@ -437,7 +438,7 @@ struct tc_netem_qopt
__u32 latency; /* added delay (us) */
__u32 limit; /* fifo limit (packets) */
__u32 loss; /* random packet loss (0=none ~0=100%) */
__u32 gap; /* re-ordering gap (0 for delay all) */
__u32 gap; /* re-ordering gap (0 for none) */
__u32 duplicate; /* random packet dup (0=none ~0=100%) */
__u32 jitter; /* random jitter in latency (us) */
};
Expand All @@ -449,6 +450,12 @@ struct tc_netem_corr
__u32 dup_corr; /* duplicate correlation */
};

struct tc_netem_reorder
{
__u32 probability;
__u32 correlation;
};

#define NETEM_DIST_SCALE 8192

#endif
54 changes: 42 additions & 12 deletions trunk/net/sched/sch_netem.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ struct netem_sched_data {
u32 gap;
u32 jitter;
u32 duplicate;
u32 reorder;

struct crndstate {
unsigned long last;
unsigned long rho;
} delay_cor, loss_cor, dup_cor;
} delay_cor, loss_cor, dup_cor, reorder_cor;

struct disttable {
u32 size;
Expand Down Expand Up @@ -180,23 +181,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
q->duplicate = dupsave;
}

/*
* Do re-ordering by putting one out of N packets at the front
* of the queue.
* gap == 0 is special case for no-reordering.
*/
if (q->gap == 0 || q->counter != q->gap) {
if (q->gap == 0 /* not doing reordering */
|| q->counter < q->gap /* inside last reordering gap */
|| q->reorder < get_crandom(&q->reorder_cor)) {
psched_time_t now;
PSCHED_GET_TIME(now);
PSCHED_TADD2(now,
tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist),
PSCHED_TADD2(now, tabledist(q->latency, q->jitter,
&q->delay_cor, q->delay_dist),
cb->time_to_send);

++q->counter;
ret = q->qdisc->enqueue(skb, q->qdisc);
} else {
q->counter = 0;
/*
* Do re-ordering by putting one out of N packets at the front
* of the queue.
*/
PSCHED_GET_TIME(cb->time_to_send);
q->counter = 0;
ret = q->qdisc->ops->requeue(skb, q->qdisc);
}

Expand Down Expand Up @@ -351,6 +352,19 @@ static int get_correlation(struct Qdisc *sch, const struct rtattr *attr)
return 0;
}

static int get_reorder(struct Qdisc *sch, const struct rtattr *attr)
{
struct netem_sched_data *q = qdisc_priv(sch);
const struct tc_netem_reorder *r = RTA_DATA(attr);

if (RTA_PAYLOAD(attr) != sizeof(*r))
return -EINVAL;

q->reorder = r->probability;
init_crandom(&q->reorder_cor, r->correlation);
return 0;
}

static int netem_change(struct Qdisc *sch, struct rtattr *opt)
{
struct netem_sched_data *q = qdisc_priv(sch);
Expand All @@ -371,9 +385,15 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
q->jitter = qopt->jitter;
q->limit = qopt->limit;
q->gap = qopt->gap;
q->counter = 0;
q->loss = qopt->loss;
q->duplicate = qopt->duplicate;

/* for compatiablity with earlier versions.
* if gap is set, need to assume 100% probablity
*/
q->reorder = ~0;

/* Handle nested options after initial queue options.
* Should have put all options in nested format but too late now.
*/
Expand All @@ -395,6 +415,11 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
if (ret)
return ret;
}
if (tb[TCA_NETEM_REORDER-1]) {
ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
if (ret)
return ret;
}
}


Expand All @@ -412,7 +437,6 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
init_timer(&q->timer);
q->timer.function = netem_watchdog;
q->timer.data = (unsigned long) sch;
q->counter = 0;

q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
if (!q->qdisc) {
Expand Down Expand Up @@ -444,6 +468,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
struct rtattr *rta = (struct rtattr *) b;
struct tc_netem_qopt qopt;
struct tc_netem_corr cor;
struct tc_netem_reorder reorder;

qopt.latency = q->latency;
qopt.jitter = q->jitter;
Expand All @@ -457,6 +482,11 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
cor.loss_corr = q->loss_cor.rho;
cor.dup_corr = q->dup_cor.rho;
RTA_PUT(skb, TCA_NETEM_CORR, sizeof(cor), &cor);

reorder.probability = q->reorder;
reorder.correlation = q->reorder_cor.rho;
RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);

rta->rta_len = skb->tail - b;

return skb->len;
Expand Down

0 comments on commit e1e411f

Please sign in to comment.