13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
50 #define CHOKE_MAX_QUEUE (128*1024 - 1)
81 static u32 random_N(
unsigned int N)
83 return reciprocal_divide(
random32(), N);
125 static void choke_drop_by_idx(
struct Qdisc *
sch,
unsigned int idx)
133 choke_zap_head_holes(q);
135 choke_zap_tail_holes(q);
137 sch->
qstats.backlog -= qdisc_pkt_len(skb);
138 qdisc_drop(skb, sch);
151 qdisc_cb_private_validate(skb,
sizeof(
struct choke_skb_cb));
160 static u16 choke_get_classid(
const struct sk_buff *skb)
170 static bool choke_match_flow(
struct sk_buff *skb1,
197 static bool choke_classify(
struct sk_buff *skb,
198 struct Qdisc *sch,
int *qerr)
207 #ifdef CONFIG_NET_CLS_ACT
236 *pidx = (q->
head + random_N(choke_len(q))) & q->
tab_mask;
240 }
while (--retrys > 0);
242 return q->
tab[*pidx = q->
head];
258 oskb = choke_peek_random(q, pidx);
260 return choke_get_classid(nskb) == choke_get_classid(oskb);
262 return choke_match_flow(oskb, nskb);
265 static int choke_enqueue(
struct sk_buff *skb,
struct Qdisc *sch)
273 if (!choke_classify(skb, sch, &ret))
279 q->
vars.qavg = red_calc_qavg(p, &q->
vars, sch->
q.qlen);
280 if (red_is_idling(&q->
vars))
281 red_end_of_idle_period(&q->
vars);
290 if (choke_match_random(q, skb, &idx)) {
292 choke_drop_by_idx(sch, idx);
293 goto congestion_drop;
301 if (use_harddrop(q) || !use_ecn(q) ||
302 !INET_ECN_set_ce(skb)) {
303 q->
stats.forced_drop++;
304 goto congestion_drop;
307 q->
stats.forced_mark++;
308 }
else if (++q->
vars.qcount) {
309 if (red_mark_probability(p, &q->
vars, q->
vars.qavg)) {
311 q->
vars.qR = red_random(p);
314 if (!use_ecn(q) || !INET_ECN_set_ce(skb)) {
315 q->
stats.prob_drop++;
316 goto congestion_drop;
319 q->
stats.prob_mark++;
322 q->
vars.qR = red_random(p);
326 if (sch->
q.qlen < q->
limit) {
330 sch->
qstats.backlog += qdisc_pkt_len(skb);
335 return qdisc_drop(skb, sch);
338 qdisc_drop(skb, sch);
354 if (!red_is_idling(&q->
vars))
355 red_start_of_idle_period(&q->
vars);
361 choke_zap_head_holes(q);
363 sch->
qstats.backlog -= qdisc_pkt_len(skb);
364 qdisc_bstats_update(sch, skb);
369 static unsigned int choke_drop(
struct Qdisc *sch)
374 len = qdisc_queue_drop(sch);
378 if (!red_is_idling(&q->
vars))
379 red_start_of_idle_period(&q->
vars);
385 static void choke_reset(
struct Qdisc *sch)
389 red_restart(&q->
vars);
399 static void choke_free(
void *
addr)
402 if (is_vmalloc_addr(addr))
422 err = nla_parse_nested(tb,
TCA_CHOKE_MAX, opt, choke_policy);
450 unsigned int oqlen = sch->
q.qlen,
tail = 0;
462 sch->
qstats.backlog -= qdisc_pkt_len(skb);
464 qdisc_drop(skb, sch);
483 red_set_vars(&q->
vars);
486 red_end_of_idle_period(&q->
vars);
488 sch_tree_unlock(sch);
493 static int choke_init(
struct Qdisc *sch,
struct nlattr *opt)
495 return choke_change(sch, opt);
498 static int choke_dump(
struct Qdisc *sch,
struct sk_buff *skb)
507 .Wlog = q->
parms.Wlog,
508 .Plog = q->
parms.Plog,
509 .Scell_log = q->
parms.Scell_log,
514 goto nla_put_failure;
517 nla_put_u32(skb, TCA_CHOKE_MAX_P, q->
parms.max_P))
518 goto nla_put_failure;
519 return nla_nest_end(skb, opts);
522 nla_nest_cancel(skb, opts);
530 .early = q->
stats.prob_drop + q->
stats.forced_drop,
531 .marked = q->
stats.prob_mark + q->
stats.forced_mark,
532 .pdrop = q->
stats.pdrop,
533 .other = q->
stats.other,
534 .matched = q->
stats.matched,
540 static void choke_destroy(
struct Qdisc *sch)
548 static struct Qdisc *choke_leaf(
struct Qdisc *sch,
unsigned long arg)
553 static unsigned long choke_get(
struct Qdisc *sch,
u32 classid)
558 static void choke_put(
struct Qdisc *q,
unsigned long cl)
562 static unsigned long choke_bind(
struct Qdisc *sch,
unsigned long parent,
568 static struct tcf_proto **choke_find_tcf(
struct Qdisc *sch,
unsigned long cl)
577 static int choke_dump_class(
struct Qdisc *sch,
unsigned long cl,
587 if (arg->
fn(sch, 1, arg) < 0) {
599 .tcf_chain = choke_find_tcf,
600 .bind_tcf = choke_bind,
601 .unbind_tcf = choke_put,
602 .dump = choke_dump_class,
606 static struct sk_buff *choke_peek_head(
struct Qdisc *sch)
617 .enqueue = choke_enqueue,
618 .dequeue = choke_dequeue,
619 .peek = choke_peek_head,
622 .destroy = choke_destroy,
623 .reset = choke_reset,
624 .change = choke_change,
626 .dump_stats = choke_dump_stats,
630 static int __init choke_module_init(
void)
635 static void __exit choke_module_exit(
void)