summaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/Kconfig41
-rw-r--r--net/sched/Makefile14
-rw-r--r--net/sched/act_api.c6
-rw-r--r--net/sched/act_gact.c (renamed from net/sched/gact.c)3
-rw-r--r--net/sched/act_ipt.c (renamed from net/sched/ipt.c)8
-rw-r--r--net/sched/act_mirred.c (renamed from net/sched/mirred.c)3
-rw-r--r--net/sched/act_pedit.c (renamed from net/sched/pedit.c)5
-rw-r--r--net/sched/act_police.c (renamed from net/sched/police.c)17
-rw-r--r--net/sched/act_simple.c (renamed from net/sched/simple.c)3
-rw-r--r--net/sched/ematch.c1
-rw-r--r--net/sched/sch_cbq.c4
-rw-r--r--net/sched/sch_hfsc.c12
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--net/sched/sch_netem.c51
-rw-r--r--net/sched/sch_prio.c14
-rw-r--r--net/sched/sch_sfq.c4
-rw-r--r--net/sched/sch_teql.c13
17 files changed, 110 insertions, 93 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 7f34e7fd767..778b1e5a4b5 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -40,10 +40,11 @@ config NET_SCHED
The available schedulers are listed in the following questions; you
can say Y to as many as you like. If unsure, say N now.
+if NET_SCHED
+
choice
prompt "Packet scheduler clock source"
- depends on NET_SCHED
- default NET_SCH_CLK_JIFFIES
+ default NET_SCH_CLK_GETTIMEOFDAY
---help---
Packet schedulers need a monotonic clock that increments at a static
rate. The kernel provides several suitable interfaces, each with
@@ -98,11 +99,9 @@ config NET_SCH_CLK_CPU
endchoice
comment "Queueing/Scheduling"
- depends on NET_SCHED
config NET_SCH_CBQ
tristate "Class Based Queueing (CBQ)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Class-Based Queueing (CBQ) packet
scheduling algorithm. This algorithm classifies the waiting packets
@@ -120,7 +119,6 @@ config NET_SCH_CBQ
config NET_SCH_HTB
tristate "Hierarchical Token Bucket (HTB)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Hierarchical Token Buckets (HTB)
packet scheduling algorithm. See
@@ -135,7 +133,6 @@ config NET_SCH_HTB
config NET_SCH_HFSC
tristate "Hierarchical Fair Service Curve (HFSC)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Hierarchical Fair Service Curve
(HFSC) packet scheduling algorithm.
@@ -145,7 +142,7 @@ config NET_SCH_HFSC
config NET_SCH_ATM
tristate "ATM Virtual Circuits (ATM)"
- depends on NET_SCHED && ATM
+ depends on ATM
---help---
Say Y here if you want to use the ATM pseudo-scheduler. This
provides a framework for invoking classifiers, which in turn
@@ -159,7 +156,6 @@ config NET_SCH_ATM
config NET_SCH_PRIO
tristate "Multi Band Priority Queueing (PRIO)"
- depends on NET_SCHED
---help---
Say Y here if you want to use an n-band priority queue packet
scheduler.
@@ -169,7 +165,6 @@ config NET_SCH_PRIO
config NET_SCH_RED
tristate "Random Early Detection (RED)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Random Early Detection (RED)
packet scheduling algorithm.
@@ -181,7 +176,6 @@ config NET_SCH_RED
config NET_SCH_SFQ
tristate "Stochastic Fairness Queueing (SFQ)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Stochastic Fairness Queueing (SFQ)
packet scheduling algorithm .
@@ -193,7 +187,6 @@ config NET_SCH_SFQ
config NET_SCH_TEQL
tristate "True Link Equalizer (TEQL)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the True Link Equalizer (TLE) packet
scheduling algorithm. This queueing discipline allows the combination
@@ -206,7 +199,6 @@ config NET_SCH_TEQL
config NET_SCH_TBF
tristate "Token Bucket Filter (TBF)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Token Bucket Filter (TBF) packet
scheduling algorithm.
@@ -218,7 +210,6 @@ config NET_SCH_TBF
config NET_SCH_GRED
tristate "Generic Random Early Detection (GRED)"
- depends on NET_SCHED
---help---
Say Y here if you want to use the Generic Random Early Detection
(GRED) packet scheduling algorithm for some of your network devices
@@ -230,7 +221,6 @@ config NET_SCH_GRED
config NET_SCH_DSMARK
tristate "Differentiated Services marker (DSMARK)"
- depends on NET_SCHED
---help---
Say Y if you want to schedule packets according to the
Differentiated Services architecture proposed in RFC 2475.
@@ -242,7 +232,6 @@ config NET_SCH_DSMARK
config NET_SCH_NETEM
tristate "Network emulator (NETEM)"
- depends on NET_SCHED
---help---
Say Y if you want to emulate network delay, loss, and packet
re-ordering. This is often useful to simulate networks when
@@ -255,7 +244,6 @@ config NET_SCH_NETEM
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
- depends on NET_SCHED
---help---
Say Y here if you want to use classifiers for incoming packets.
If unsure, say Y.
@@ -264,14 +252,12 @@ config NET_SCH_INGRESS
module will be called sch_ingress.
comment "Classification"
- depends on NET_SCHED
config NET_CLS
boolean
config NET_CLS_BASIC
tristate "Elementary classification (BASIC)"
- depends NET_SCHED
select NET_CLS
---help---
Say Y here if you want to be able to classify packets using
@@ -282,7 +268,6 @@ config NET_CLS_BASIC
config NET_CLS_TCINDEX
tristate "Traffic-Control Index (TCINDEX)"
- depends NET_SCHED
select NET_CLS
---help---
Say Y here if you want to be able to classify packets based on
@@ -294,7 +279,6 @@ config NET_CLS_TCINDEX
config NET_CLS_ROUTE4
tristate "Routing decision (ROUTE)"
- depends NET_SCHED
select NET_CLS_ROUTE
select NET_CLS
---help---
@@ -306,11 +290,9 @@ config NET_CLS_ROUTE4
config NET_CLS_ROUTE
bool
- default n
config NET_CLS_FW
tristate "Netfilter mark (FW)"
- depends NET_SCHED
select NET_CLS
---help---
If you say Y here, you will be able to classify packets
@@ -321,7 +303,6 @@ config NET_CLS_FW
config NET_CLS_U32
tristate "Universal 32bit comparisons w/ hashing (U32)"
- depends NET_SCHED
select NET_CLS
---help---
Say Y here to be able to classify packetes using a universal
@@ -345,7 +326,6 @@ config CLS_U32_MARK
config NET_CLS_RSVP
tristate "IPv4 Resource Reservation Protocol (RSVP)"
- depends on NET_SCHED
select NET_CLS
select NET_ESTIMATOR
---help---
@@ -361,7 +341,6 @@ config NET_CLS_RSVP
config NET_CLS_RSVP6
tristate "IPv6 Resource Reservation Protocol (RSVP6)"
- depends on NET_SCHED
select NET_CLS
select NET_ESTIMATOR
---help---
@@ -377,7 +356,6 @@ config NET_CLS_RSVP6
config NET_EMATCH
bool "Extended Matches"
- depends NET_SCHED
select NET_CLS
---help---
Say Y here if you want to use extended matches on top of classifiers
@@ -433,7 +411,7 @@ config NET_EMATCH_META
tristate "Metadata"
depends on NET_EMATCH
---help---
- Say Y here if you want to be ablt to classify packets based on
+ Say Y here if you want to be able to classify packets based on
metadata such as load average, netfilter attributes, socket
attributes and routing decisions.
@@ -456,7 +434,7 @@ config NET_EMATCH_TEXT
config NET_CLS_ACT
bool "Actions"
- depends on EXPERIMENTAL && NET_SCHED
+ depends on EXPERIMENTAL
select NET_ESTIMATOR
---help---
Say Y here if you want to use traffic control actions. Actions
@@ -539,7 +517,7 @@ config NET_ACT_SIMP
config NET_CLS_POLICE
bool "Traffic Policing (obsolete)"
- depends on NET_SCHED && NET_CLS_ACT!=y
+ depends on NET_CLS_ACT!=y
select NET_ESTIMATOR
---help---
Say Y here if you want to do traffic policing, i.e. strict
@@ -549,7 +527,7 @@ config NET_CLS_POLICE
config NET_CLS_IND
bool "Incoming device classification"
- depends on NET_SCHED && (NET_CLS_U32 || NET_CLS_FW)
+ depends on NET_CLS_U32 || NET_CLS_FW
---help---
Say Y here to extend the u32 and fw classifier to support
classification based on the incoming device. This option is
@@ -557,11 +535,12 @@ config NET_CLS_IND
config NET_ESTIMATOR
bool "Rate estimator"
- depends on NET_SCHED
---help---
Say Y here to allow using rate estimators to estimate the current
rate-of-flow for network devices, queues, etc. This module is
automaticaly selected if needed but can be selected manually for
statstical purposes.
+endif # NET_SCHED
+
endmenu
diff --git a/net/sched/Makefile b/net/sched/Makefile
index e48d0d456b3..0f06aec6609 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -7,13 +7,13 @@ obj-y := sch_generic.o
obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o sch_blackhole.o
obj-$(CONFIG_NET_CLS) += cls_api.o
obj-$(CONFIG_NET_CLS_ACT) += act_api.o
-obj-$(CONFIG_NET_ACT_POLICE) += police.o
-obj-$(CONFIG_NET_CLS_POLICE) += police.o
-obj-$(CONFIG_NET_ACT_GACT) += gact.o
-obj-$(CONFIG_NET_ACT_MIRRED) += mirred.o
-obj-$(CONFIG_NET_ACT_IPT) += ipt.o
-obj-$(CONFIG_NET_ACT_PEDIT) += pedit.o
-obj-$(CONFIG_NET_ACT_SIMP) += simple.o
+obj-$(CONFIG_NET_ACT_POLICE) += act_police.o
+obj-$(CONFIG_NET_CLS_POLICE) += act_police.o
+obj-$(CONFIG_NET_ACT_GACT) += act_gact.o
+obj-$(CONFIG_NET_ACT_MIRRED) += act_mirred.o
+obj-$(CONFIG_NET_ACT_IPT) += act_ipt.o
+obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o
+obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 8aebe8f6d27..792ce59940e 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -34,7 +34,7 @@
#include <net/sch_generic.h>
#include <net/act_api.h>
-#if 1 /* control */
+#if 0 /* control */
#define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args)
#else
#define DPRINTK(format, args...)
@@ -165,7 +165,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action *act,
while ((a = act) != NULL) {
repeat:
if (a->ops && a->ops->act) {
- ret = a->ops->act(&skb, a, res);
+ ret = a->ops->act(skb, a, res);
if (TC_MUNGED & skb->tc_verd) {
/* copied already, allow trampling */
skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
@@ -290,7 +290,7 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
if (a_o == NULL) {
#ifdef CONFIG_KMOD
rtnl_unlock();
- request_module(act_name);
+ request_module("act_%s", act_name);
rtnl_lock();
a_o = tc_lookup_action_n(act_name);
diff --git a/net/sched/gact.c b/net/sched/act_gact.c
index d1c6d542912..a1e68f78dcc 100644
--- a/net/sched/gact.c
+++ b/net/sched/act_gact.c
@@ -135,10 +135,9 @@ tcf_gact_cleanup(struct tc_action *a, int bind)
}
static int
-tcf_gact(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{
struct tcf_gact *p = PRIV(a, gact);
- struct sk_buff *skb = *pskb;
int action = TC_ACT_SHOT;
spin_lock(&p->lock);
diff --git a/net/sched/ipt.c b/net/sched/act_ipt.c
index f50136eed21..39a22a3ffe7 100644
--- a/net/sched/ipt.c
+++ b/net/sched/act_ipt.c
@@ -62,7 +62,7 @@ ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
struct ipt_target *target;
int ret = 0;
- target = ipt_find_target(t->u.user.name, t->u.user.revision);
+ target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision);
if (!target)
return -ENOENT;
@@ -201,11 +201,10 @@ tcf_ipt_cleanup(struct tc_action *a, int bind)
}
static int
-tcf_ipt(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_ipt(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{
int ret = 0, result = 0;
struct tcf_ipt *p = PRIV(a, ipt);
- struct sk_buff *skb = *pskb;
if (skb_cloned(skb)) {
if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -222,6 +221,9 @@ tcf_ipt(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
worry later - danger - this API seems to have changed
from earlier kernels */
+ /* iptables targets take a double skb pointer in case the skb
+ * needs to be replaced. We don't own the skb, so this must not
+ * happen. The pskb_expand_head above should make sure of this */
ret = p->t->u.kernel.target->target(&skb, skb->dev, NULL,
p->hook, p->t->data, NULL);
switch (ret) {
diff --git a/net/sched/mirred.c b/net/sched/act_mirred.c
index 20d06916dc0..4fcccbd5088 100644
--- a/net/sched/mirred.c
+++ b/net/sched/act_mirred.c
@@ -158,12 +158,11 @@ tcf_mirred_cleanup(struct tc_action *a, int bind)
}
static int
-tcf_mirred(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_mirred(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{
struct tcf_mirred *p = PRIV(a, mirred);
struct net_device *dev;
struct sk_buff *skb2 = NULL;
- struct sk_buff *skb = *pskb;
u32 at = G_TC_AT(skb->tc_verd);
spin_lock(&p->lock);
diff --git a/net/sched/pedit.c b/net/sched/act_pedit.c
index 767d24f4610..1742a68e012 100644
--- a/net/sched/pedit.c
+++ b/net/sched/act_pedit.c
@@ -130,10 +130,9 @@ tcf_pedit_cleanup(struct tc_action *a, int bind)
}
static int
-tcf_pedit(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_pedit(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{
struct tcf_pedit *p = PRIV(a, pedit);
- struct sk_buff *skb = *pskb;
int i, munged = 0;
u8 *pptr;
@@ -246,10 +245,12 @@ tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref)
t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
t.expires = jiffies_to_clock_t(p->tm.expires);
RTA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
+ kfree(opt);
return skb->len;
rtattr_failure:
skb_trim(skb, b - skb->data);
+ kfree(opt);
return -1;
}
diff --git a/net/sched/police.c b/net/sched/act_police.c
index eb39fb2f39b..fa877f8f652 100644
--- a/net/sched/police.c
+++ b/net/sched/act_police.c
@@ -284,11 +284,10 @@ static int tcf_act_police_cleanup(struct tc_action *a, int bind)
return 0;
}
-static int tcf_act_police(struct sk_buff **pskb, struct tc_action *a,
+static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
struct tcf_result *res)
{
psched_time_t now;
- struct sk_buff *skb = *pskb;
struct tcf_police *p = PRIV(a);
long toks;
long ptoks = 0;
@@ -408,7 +407,7 @@ police_cleanup_module(void)
module_init(police_init_module);
module_exit(police_cleanup_module);
-#endif
+#else /* CONFIG_NET_CLS_ACT */
struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est)
{
@@ -545,6 +544,7 @@ int tcf_police(struct sk_buff *skb, struct tcf_police *p)
spin_unlock(&p->lock);
return p->action;
}
+EXPORT_SYMBOL(tcf_police);
int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p)
{
@@ -601,13 +601,4 @@ errout:
return -1;
}
-
-EXPORT_SYMBOL(tcf_police);
-EXPORT_SYMBOL(tcf_police_destroy);
-EXPORT_SYMBOL(tcf_police_dump);
-EXPORT_SYMBOL(tcf_police_dump_stats);
-EXPORT_SYMBOL(tcf_police_hash);
-EXPORT_SYMBOL(tcf_police_ht);
-EXPORT_SYMBOL(tcf_police_locate);
-EXPORT_SYMBOL(tcf_police_lookup);
-EXPORT_SYMBOL(tcf_police_new_index);
+#endif /* CONFIG_NET_CLS_ACT */
diff --git a/net/sched/simple.c b/net/sched/act_simple.c
index 8a6ae4f491e..e5f2e1f431e 100644
--- a/net/sched/simple.c
+++ b/net/sched/act_simple.c
@@ -44,9 +44,8 @@ static DEFINE_RWLOCK(simp_lock);
#include <net/pkt_act.h>
#include <net/act_generic.h>
-static int tcf_simp(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{
- struct sk_buff *skb = *pskb;
struct tcf_defact *p = PRIV(a, defact);
spin_lock(&p->lock);
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 64b047c6556..5cb956b721e 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -92,7 +92,6 @@
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
#include <net/pkt_cls.h>
-#include <config/net/ematch/stack.h>
static LIST_HEAD(ematch_ops);
static DEFINE_RWLOCK(ematch_mod_lock);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 09453f997d8..6cd81708bf7 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -257,7 +257,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
(cl = cbq_class_lookup(q, prio)) != NULL)
return cl;
- *qerr = NET_XMIT_DROP;
+ *qerr = NET_XMIT_BYPASS;
for (;;) {
int result = 0;
defmap = head->defaults;
@@ -413,7 +413,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
q->rx_class = cl;
#endif
if (cl == NULL) {
- if (ret == NET_XMIT_DROP)
+ if (ret == NET_XMIT_BYPASS)
sch->qstats.drops++;
kfree_skb(skb);
return ret;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index c26764bc410..91132f6871d 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -208,7 +208,7 @@ struct hfsc_sched
do { \
struct timeval tv; \
do_gettimeofday(&tv); \
- (stamp) = 1000000ULL * tv.tv_sec + tv.tv_usec; \
+ (stamp) = 1ULL * USEC_PER_SEC * tv.tv_sec + tv.tv_usec; \
} while (0)
#endif
@@ -502,8 +502,8 @@ d2dx(u32 d)
u64 dx;
dx = ((u64)d * PSCHED_JIFFIE2US(HZ));
- dx += 1000000 - 1;
- do_div(dx, 1000000);
+ dx += USEC_PER_SEC - 1;
+ do_div(dx, USEC_PER_SEC);
return dx;
}
@@ -523,7 +523,7 @@ dx2d(u64 dx)
{
u64 d;
- d = dx * 1000000;
+ d = dx * USEC_PER_SEC;
do_div(d, PSCHED_JIFFIE2US(HZ));
return (u32)d;
}
@@ -1227,7 +1227,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
if (cl->level == 0)
return cl;
- *qerr = NET_XMIT_DROP;
+ *qerr = NET_XMIT_BYPASS;
tcf = q->root.filter_list;
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
#ifdef CONFIG_NET_CLS_ACT
@@ -1643,7 +1643,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
cl = hfsc_classify(skb, sch, &err);
if (cl == NULL) {
- if (err == NET_XMIT_DROP)
+ if (err == NET_XMIT_BYPASS)
sch->qstats.drops++;
kfree_skb(skb);
return err;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 558cc087e60..3ec95df4a85 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -321,7 +321,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, in
if ((cl = htb_find(skb->priority,sch)) != NULL && cl->level == 0)
return cl;
- *qerr = NET_XMIT_DROP;
+ *qerr = NET_XMIT_BYPASS;
tcf = q->filter_list;
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
#ifdef CONFIG_NET_CLS_ACT
@@ -724,7 +724,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
}
#ifdef CONFIG_NET_CLS_ACT
} else if (!cl) {
- if (ret == NET_XMIT_DROP)
+ if (ret == NET_XMIT_BYPASS)
sch->qstats.drops++;
kfree_skb (skb);
return ret;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index cdc8d283791..ba528320483 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -25,7 +25,7 @@
#include <net/pkt_sched.h>
-#define VERSION "1.1"
+#define VERSION "1.2"
/* Network Emulation Queuing algorithm.
====================================
@@ -65,11 +65,12 @@ struct netem_sched_data {
u32 jitter;
u32 duplicate;
u32 reorder;
+ u32 corrupt;
struct crndstate {
unsigned long last;
unsigned long rho;
- } delay_cor, loss_cor, dup_cor, reorder_cor;
+ } delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor;
struct disttable {
u32 size;
@@ -183,6 +184,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
q->duplicate = dupsave;
}
+ /*
+ * Randomized packet corruption.
+ * Make copy if needed since we are modifying
+ * If packet is going to be hardware checksummed, then
+ * do it now in software before we mangle it.
+ */
+ if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
+ if (!(skb = skb_unshare(skb, GFP_ATOMIC))
+ || (skb->ip_summed == CHECKSUM_HW
+ && skb_checksum_help(skb, 0))) {
+ sch->qstats.drops++;
+ return NET_XMIT_DROP;
+ }
+
+ skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
+ }
+
if (q->gap == 0 /* not doing reordering */
|| q->counter < q->gap /* inside last reordering gap */
|| q->reorder < get_crandom(&q->reorder_cor)) {
@@ -382,6 +400,20 @@ static int get_reorder(struct Qdisc *sch, const struct rtattr *attr)
return 0;
}
+static int get_corrupt(struct Qdisc *sch, const struct rtattr *attr)
+{
+ struct netem_sched_data *q = qdisc_priv(sch);
+ const struct tc_netem_corrupt *r = RTA_DATA(attr);
+
+ if (RTA_PAYLOAD(attr) != sizeof(*r))
+ return -EINVAL;
+
+ q->corrupt = r->probability;
+ init_crandom(&q->corrupt_cor, r->correlation);
+ return 0;
+}
+
+/* Parse netlink message to set options */
static int netem_change(struct Qdisc *sch, struct rtattr *opt)
{
struct netem_sched_data *q = qdisc_priv(sch);
@@ -432,13 +464,19 @@ 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;
}
- }
+ if (tb[TCA_NETEM_CORRUPT-1]) {
+ ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT-1]);
+ if (ret)
+ return ret;
+ }
+ }
return 0;
}
@@ -464,7 +502,7 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
const struct netem_skb_cb *cb
= (const struct netem_skb_cb *)skb->cb;
- if (PSCHED_TLESS(cb->time_to_send, ncb->time_to_send))
+ if (!PSCHED_TLESS(ncb->time_to_send, cb->time_to_send))
break;
}
@@ -564,6 +602,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
struct tc_netem_qopt qopt;
struct tc_netem_corr cor;
struct tc_netem_reorder reorder;
+ struct tc_netem_corrupt corrupt;
qopt.latency = q->latency;
qopt.jitter = q->jitter;
@@ -582,6 +621,10 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
reorder.correlation = q->reorder_cor.rho;
RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
+ corrupt.probability = q->corrupt;
+ corrupt.correlation = q->corrupt_cor.rho;
+ RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
+
rta->rta_len = skb->tail - b;
return skb->len;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 3ac0f495bad..1641db33a99 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -54,7 +54,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
u32 band = skb->priority;
struct tcf_result res;
- *qerr = NET_XMIT_DROP;
+ *qerr = NET_XMIT_BYPASS;
if (TC_H_MAJ(skb->priority) != sch->handle) {
#ifdef CONFIG_NET_CLS_ACT
switch (tc_classify(skb, q->filter_list, &res)) {
@@ -91,7 +91,8 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
qdisc = prio_classify(skb, sch, &ret);
#ifdef CONFIG_NET_CLS_ACT
if (qdisc == NULL) {
- if (ret == NET_XMIT_DROP)
+
+ if (ret == NET_XMIT_BYPASS)
sch->qstats.drops++;
kfree_skb(skb);
return ret;
@@ -118,7 +119,7 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
qdisc = prio_classify(skb, sch, &ret);
#ifdef CONFIG_NET_CLS_ACT
if (qdisc == NULL) {
- if (ret == NET_XMIT_DROP)
+ if (ret == NET_XMIT_BYPASS)
sch->qstats.drops++;
kfree_skb(skb);
return ret;
@@ -227,14 +228,13 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
}
sch_tree_unlock(sch);
- for (i=0; i<=TC_PRIO_MAX; i++) {
- int band = q->prio2band[i];
- if (q->queues[band] == &noop_qdisc) {
+ for (i=0; i<q->bands; i++) {
+ if (q->queues[i] == &noop_qdisc) {
struct Qdisc *child;
child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
if (child) {
sch_tree_lock(sch);
- child = xchg(&q->queues[band], child);
+ child = xchg(&q->queues[i], child);
if (child != &noop_qdisc)
qdisc_destroy(child);
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 8734bb7280e..86d8da0cbd0 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -144,6 +144,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
(iph->protocol == IPPROTO_TCP ||
iph->protocol == IPPROTO_UDP ||
+ iph->protocol == IPPROTO_SCTP ||
+ iph->protocol == IPPROTO_DCCP ||
iph->protocol == IPPROTO_ESP))
h2 ^= *(((u32*)iph) + iph->ihl);
break;
@@ -155,6 +157,8 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
if (iph->nexthdr == IPPROTO_TCP ||
iph->nexthdr == IPPROTO_UDP ||
+ iph->nexthdr == IPPROTO_SCTP ||
+ iph->nexthdr == IPPROTO_DCCP ||
iph->nexthdr == IPPROTO_ESP)
h2 ^= *(u32*)&iph[1];
break;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 6cf0342706b..79b8ef34c6e 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -22,6 +22,7 @@
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
+#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
@@ -273,7 +274,7 @@ teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *de
static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct teql_master *master = (void*)dev->priv;
+ struct teql_master *master = netdev_priv(dev);
struct Qdisc *start, *q;
int busy;
int nores;
@@ -349,7 +350,7 @@ drop:
static int teql_master_open(struct net_device *dev)
{
struct Qdisc * q;
- struct teql_master *m = (void*)dev->priv;
+ struct teql_master *m = netdev_priv(dev);
int mtu = 0xFFFE;
unsigned flags = IFF_NOARP|IFF_MULTICAST;
@@ -396,13 +397,13 @@ static int teql_master_close(struct net_device *dev)
static struct net_device_stats *teql_master_stats(struct net_device *dev)
{
- struct teql_master *m = (void*)dev->priv;
+ struct teql_master *m = netdev_priv(dev);
return &m->stats;
}
static int teql_master_mtu(struct net_device *dev, int new_mtu)
{
- struct teql_master *m = (void*)dev->priv;
+ struct teql_master *m = netdev_priv(dev);
struct Qdisc *q;
if (new_mtu < 68)
@@ -422,7 +423,7 @@ static int teql_master_mtu(struct net_device *dev, int new_mtu)
static __init void teql_master_setup(struct net_device *dev)
{
- struct teql_master *master = dev->priv;
+ struct teql_master *master = netdev_priv(dev);
struct Qdisc_ops *ops = &master->qops;
master->dev = dev;
@@ -475,7 +476,7 @@ static int __init teql_init(void)
break;
}
- master = dev->priv;
+ master = netdev_priv(dev);
strlcpy(master->qops.id, dev->name, IFNAMSIZ);
err = register_qdisc(&master->qops);