From: Patrick McHardy <kaber@trash•net>
To: netdev@vger•kernel.org
Cc: Patrick McHardy <kaber@trash•net>, hadi@cyberus•ca
Subject: [RFC NET_SCHED 01/02]: sch_sfq: add support for external classifiers
Date: Wed, 30 May 2007 11:40:56 +0200 (MEST) [thread overview]
Message-ID: <20070530094021.24073.69313.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20070530094020.24073.84277.sendpatchset@localhost.localdomain>
[NET_SCHED]: sch_sfq: add support for external classifiers
Add support for external classifiers to allow using different flow hash
functions similar to ESFQ. As long as no classifier is attached the
built-in hash is used as before.
Signed-off-by: Patrick McHardy <kaber@trash•net>
---
commit 666e402224e5ca36af0b5a07d424b9c092bce91e
tree f0e020de640693ba9601cc2e4b82daba7bf03689
parent c420bc9f09a0926b708c3edb27eacba434a4f4ba
author Patrick McHardy <kaber@trash•net> Wed, 30 May 2007 11:21:05 +0200
committer Patrick McHardy <kaber@trash•net> Wed, 30 May 2007 11:21:05 +0200
net/sched/sch_sfq.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 96dfdf7..42cd4fc 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -108,6 +108,7 @@ struct sfq_sched_data
int limit;
/* Variables */
+ struct tcf_proto *filter_list;
struct timer_list perturb_timer;
int perturbation;
sfq_index tail; /* Index of current slot in round */
@@ -172,6 +173,42 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
return sfq_fold_hash(q, h, h2);
}
+static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
+ int *qerr)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+ struct tcf_result res;
+ int result;
+
+ if (TC_H_MAJ(skb->priority) == sch->handle &&
+ TC_H_MIN(skb->priority) > 0 &&
+ TC_H_MIN(skb->priority) <= SFQ_HASH_DIVISOR)
+ return TC_H_MIN(skb->priority);
+
+ if (!q->filter_list)
+ return sfq_hash(q, skb) + 1;
+
+ *qerr = NET_XMIT_BYPASS;
+ result = tc_classify(skb, q->filter_list, &res);
+ if (result >= 0) {
+#ifdef CONFIG_NET_CLS_ACT
+ switch (result) {
+ case TC_ACT_STOLEN:
+ case TC_ACT_QUEUED:
+ *qerr = NET_XMIT_SUCCESS;
+ case TC_ACT_SHOT:
+ return 0;
+ }
+#elif defined(CONFIG_NET_CLS_POLICE)
+ if (result == TC_POLICE_SHOT)
+ return 0;
+#endif
+ if (TC_H_MIN(res.classid) <= SFQ_HASH_DIVISOR)
+ return TC_H_MIN(res.classid);
+ }
+ return 0;
+}
+
static inline void sfq_link(struct sfq_sched_data *q, sfq_index x)
{
sfq_index p, n;
@@ -262,8 +299,18 @@ static int
sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- unsigned hash = sfq_hash(q, skb);
+ unsigned int hash;
sfq_index x;
+ int ret;
+
+ hash = sfq_classify(skb, sch, &ret);
+ if (hash == 0) {
+ if (ret == NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return ret;
+ }
+ hash--;
x = q->ht[hash];
if (x == SFQ_DEPTH) {
@@ -298,8 +345,18 @@ static int
sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
- unsigned hash = sfq_hash(q, skb);
+ unsigned int hash;
sfq_index x;
+ int ret;
+
+ hash = sfq_classify(skb, sch, &ret);
+ if (hash == 0) {
+ if (ret == NET_XMIT_BYPASS)
+ sch->qstats.drops++;
+ kfree_skb(skb);
+ return ret;
+ }
+ hash--;
x = q->ht[hash];
if (x == SFQ_DEPTH) {
@@ -456,6 +513,8 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
static void sfq_destroy(struct Qdisc *sch)
{
struct sfq_sched_data *q = qdisc_priv(sch);
+
+ tcf_destroy_chain(q->filter_list);
del_timer(&q->perturb_timer);
}
@@ -481,9 +540,40 @@ rtattr_failure:
return -1;
}
+static int sfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct rtattr **tca, unsigned long *arg)
+{
+ return -ENOSYS;
+}
+
+static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
+{
+ return 0;
+}
+
+static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+
+ if (cl)
+ return NULL;
+ return &q->filter_list;
+}
+
+static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *walker)
+{
+ return;
+}
+
+static struct Qdisc_class_ops sfq_class_ops = {
+ .get = sfq_get,
+ .change = sfq_change_class,
+ .tcf_chain = sfq_find_tcf,
+ .walk = sfq_walk,
+};
+
static struct Qdisc_ops sfq_qdisc_ops = {
- .next = NULL,
- .cl_ops = NULL,
+ .cl_ops = &sfq_class_ops,
.id = "sfq",
.priv_size = sizeof(struct sfq_sched_data),
.enqueue = sfq_enqueue,
next prev parent reply other threads:[~2007-05-30 9:40 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-30 9:40 [RFC NET_SCHED 00/02]: Flexible SFQ flow classification Patrick McHardy
2007-05-30 9:40 ` Patrick McHardy [this message]
2007-05-30 9:40 ` [RFC NET_SCHED 02/02]: Add flow classifier Patrick McHardy
2007-05-30 11:18 ` [RFC NET_SCHED 00/02]: Flexible SFQ flow classification Andy Furniss
2007-05-30 15:32 ` Patrick McHardy
2007-05-30 16:57 ` Andy Furniss
2007-05-30 14:56 ` jamal
2007-05-30 15:27 ` Patrick McHardy
2007-05-30 16:10 ` jamal
2007-05-30 16:23 ` Patrick McHardy
2007-05-30 16:34 ` jamal
2007-05-30 16:55 ` Patrick McHardy
2007-05-30 17:02 ` jamal
2007-08-09 4:12 ` Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070530094021.24073.69313.sendpatchset@localhost.localdomain \
--to=kaber@trash$(echo .)net \
--cc=hadi@cyberus$(echo .)ca \
--cc=netdev@vger$(echo .)kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox