From: John Fastabend <john.fastabend@gmail.com>
To: xiyou.wangcong@gmail.com, davem@davemloft.net
Cc: netdev@vger.kernel.org, jhs@mojatatu.com, eric.dumazet@gmail.com
Subject: [PATCH v1 2/2] net: sched: replace ematch calls to use struct net
Date: Thu, 02 Oct 2014 22:46:25 -0700 [thread overview]
Message-ID: <20141003054624.20925.28150.stgit@nitbit.x32> (raw)
In-Reply-To: <20141003054558.20925.67091.stgit@nitbit.x32>
We can not use tcf_proto tp in all cases from RCU callbacks
so this patch simplifies the ematch code paths to take a
'struct net' and then use it directly in em_ipset the only
user.
Previously, em_ipset took the 'net' attribute from the
qdisc embedded in the tcp_proto struct.
This resolves casis where tcf_em_destroy() was being used
in callbacks and referencing the possibly invalid tcf_proto
field.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/net/pkt_cls.h | 13 ++++++-------
net/sched/cls_basic.c | 9 ++++-----
net/sched/cls_cgroup.c | 10 +++++-----
net/sched/cls_flow.c | 12 ++++++------
net/sched/em_canid.c | 6 +++---
net/sched/em_ipset.c | 7 +++----
net/sched/em_meta.c | 4 ++--
net/sched/em_nbyte.c | 2 +-
net/sched/em_text.c | 4 ++--
net/sched/ematch.c | 18 +++++++++---------
10 files changed, 41 insertions(+), 44 deletions(-)
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index ef44ad9..f6ebcf3 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -229,12 +229,11 @@ struct tcf_ematch_tree {
struct tcf_ematch_ops {
int kind;
int datalen;
- int (*change)(struct tcf_proto *, void *,
+ int (*change)(struct net *, void *,
int, struct tcf_ematch *);
int (*match)(struct sk_buff *, struct tcf_ematch *,
struct tcf_pkt_info *);
- void (*destroy)(struct tcf_proto *,
- struct tcf_ematch *);
+ void (*destroy)(struct net *, struct tcf_ematch *);
int (*dump)(struct sk_buff *, struct tcf_ematch *);
struct module *owner;
struct list_head link;
@@ -242,9 +241,9 @@ struct tcf_ematch_ops {
int tcf_em_register(struct tcf_ematch_ops *);
void tcf_em_unregister(struct tcf_ematch_ops *);
-int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
+int tcf_em_tree_validate(struct net *, struct nlattr *,
struct tcf_ematch_tree *);
-void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
+void tcf_em_tree_destroy(struct net *, struct tcf_ematch_tree *);
int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
struct tcf_pkt_info *);
@@ -300,8 +299,8 @@ static inline int tcf_em_tree_match(struct sk_buff *skb,
struct tcf_ematch_tree {
};
-#define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
-#define tcf_em_tree_destroy(tp, t) do { (void)(t); } while(0)
+#define tcf_em_tree_validate(net, tb, t) ((void)(t), 0)
+#define tcf_em_tree_destroy(net, t) do { (void)(t); } while(0)
#define tcf_em_tree_dump(skb, t, tlv) (0)
#define tcf_em_tree_change(tp, dst, src) do { } while(0)
#define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 81ddfa6..f37e4fb 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -32,7 +32,7 @@ struct basic_filter {
struct tcf_exts exts;
struct tcf_ematch_tree ematches;
struct tcf_result res;
- struct tcf_proto *tp;
+ struct net *net;
struct list_head link;
struct rcu_head rcu;
};
@@ -91,10 +91,9 @@ static int basic_init(struct tcf_proto *tp)
static void basic_delete_filter(struct rcu_head *head)
{
struct basic_filter *f = container_of(head, struct basic_filter, rcu);
- struct tcf_proto *tp = f->tp;
tcf_exts_destroy(&f->exts);
- tcf_em_tree_destroy(tp, &f->ematches);
+ tcf_em_tree_destroy(f->net, &f->ematches);
kfree(f);
}
@@ -147,7 +146,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
if (err < 0)
return err;
- err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &t);
+ err = tcf_em_tree_validate(net, tb[TCA_BASIC_EMATCHES], &t);
if (err < 0)
goto errout;
@@ -158,7 +157,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
tcf_exts_change(tp, &f->exts, &e);
tcf_em_tree_change(tp, &f->ematches, &t);
- f->tp = tp;
+ f->net = net;
return 0;
errout:
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 3409f16..d4fef3a 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -22,7 +22,7 @@ struct cls_cgroup_head {
u32 handle;
struct tcf_exts exts;
struct tcf_ematch_tree ematches;
- struct tcf_proto *tp;
+ struct net *net;
struct rcu_head rcu;
};
@@ -87,7 +87,7 @@ static void cls_cgroup_destroy_rcu(struct rcu_head *root)
rcu);
tcf_exts_destroy(&head->exts);
- tcf_em_tree_destroy(head->tp, &head->ematches);
+ tcf_em_tree_destroy(head->net, &head->ematches);
kfree(head);
}
@@ -122,7 +122,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
else
new->handle = handle;
- new->tp = tp;
+ new->net = net;
err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
cgroup_policy);
if (err < 0)
@@ -133,7 +133,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
if (err < 0)
goto errout;
- err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
+ err = tcf_em_tree_validate(net, tb[TCA_CGROUP_EMATCHES], &t);
if (err < 0) {
tcf_exts_destroy(&e);
goto errout;
@@ -157,7 +157,7 @@ static void cls_cgroup_destroy(struct tcf_proto *tp)
if (head) {
tcf_exts_destroy(&head->exts);
- tcf_em_tree_destroy(tp, &head->ematches);
+ tcf_em_tree_destroy(head->net, &head->ematches);
RCU_INIT_POINTER(tp->root, NULL);
kfree_rcu(head, rcu);
}
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index f18d27f7..5413810 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -41,7 +41,7 @@ struct flow_filter {
struct list_head list;
struct tcf_exts exts;
struct tcf_ematch_tree ematches;
- struct tcf_proto *tp;
+ struct net *net;
struct timer_list perturb_timer;
u32 perturb_period;
u32 handle;
@@ -355,7 +355,7 @@ static void flow_destroy_filter(struct rcu_head *head)
del_timer_sync(&f->perturb_timer);
tcf_exts_destroy(&f->exts);
- tcf_em_tree_destroy(f->tp, &f->ematches);
+ tcf_em_tree_destroy(f->net, &f->ematches);
kfree(f);
}
@@ -410,7 +410,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
if (err < 0)
return err;
- err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &t);
+ err = tcf_em_tree_validate(net, tb[TCA_FLOW_EMATCHES], &t);
if (err < 0)
goto err1;
@@ -428,7 +428,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
/* Copy fold into fnew */
fnew->handle = fold->handle;
fnew->keymask = fold->keymask;
- fnew->tp = fold->tp;
+ fnew->net = fold->net;
fnew->handle = fold->handle;
fnew->nkeys = fold->nkeys;
@@ -481,7 +481,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
fnew->handle = handle;
fnew->mask = ~0U;
- fnew->tp = tp;
+ fnew->net = net;
get_random_bytes(&fnew->hashrnd, 4);
tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE);
}
@@ -530,7 +530,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
return 0;
err2:
- tcf_em_tree_destroy(tp, &t);
+ tcf_em_tree_destroy(net, &t);
kfree(fnew);
err1:
tcf_exts_destroy(&e);
diff --git a/net/sched/em_canid.c b/net/sched/em_canid.c
index 7c292d4..65570b3 100644
--- a/net/sched/em_canid.c
+++ b/net/sched/em_canid.c
@@ -120,8 +120,8 @@ static int em_canid_match(struct sk_buff *skb, struct tcf_ematch *m,
return match;
}
-static int em_canid_change(struct tcf_proto *tp, void *data, int len,
- struct tcf_ematch *m)
+static int em_canid_change(struct net *net, void *data, int len,
+ struct tcf_ematch *m)
{
struct can_filter *conf = data; /* Array with rules */
struct canid_match *cm;
@@ -183,7 +183,7 @@ static int em_canid_change(struct tcf_proto *tp, void *data, int len,
return 0;
}
-static void em_canid_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+static void em_canid_destroy(struct net *net, struct tcf_ematch *m)
{
struct canid_match *cm = em_canid_priv(m);
diff --git a/net/sched/em_ipset.c b/net/sched/em_ipset.c
index 527aeb7..10f31df 100644
--- a/net/sched/em_ipset.c
+++ b/net/sched/em_ipset.c
@@ -19,12 +19,11 @@
#include <net/ip.h>
#include <net/pkt_cls.h>
-static int em_ipset_change(struct tcf_proto *tp, void *data, int data_len,
+static int em_ipset_change(struct net *net, void *data, int data_len,
struct tcf_ematch *em)
{
struct xt_set_info *set = data;
ip_set_id_t index;
- struct net *net = dev_net(qdisc_dev(tp->q));
if (data_len != sizeof(*set))
return -EINVAL;
@@ -42,11 +41,11 @@ static int em_ipset_change(struct tcf_proto *tp, void *data, int data_len,
return -ENOMEM;
}
-static void em_ipset_destroy(struct tcf_proto *p, struct tcf_ematch *em)
+static void em_ipset_destroy(struct net *net, struct tcf_ematch *em)
{
const struct xt_set_info *set = (const void *) em->data;
if (set) {
- ip_set_nfnl_put(dev_net(qdisc_dev(p->q)), set->index);
+ ip_set_nfnl_put(net, set->index);
kfree((void *) em->data);
}
}
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 9b8c0b0..7ce92a2 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -856,7 +856,7 @@ static const struct nla_policy meta_policy[TCA_EM_META_MAX + 1] = {
[TCA_EM_META_HDR] = { .len = sizeof(struct tcf_meta_hdr) },
};
-static int em_meta_change(struct tcf_proto *tp, void *data, int len,
+static int em_meta_change(struct net *net, void *data, int len,
struct tcf_ematch *m)
{
int err;
@@ -908,7 +908,7 @@ errout:
return err;
}
-static void em_meta_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+static void em_meta_destroy(struct net *net, struct tcf_ematch *m)
{
if (m)
meta_delete((struct meta_match *) m->data);
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index a3bed07..df3110d 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -23,7 +23,7 @@ struct nbyte_data {
char pattern[0];
};
-static int em_nbyte_change(struct tcf_proto *tp, void *data, int data_len,
+static int em_nbyte_change(struct net *net, void *data, int data_len,
struct tcf_ematch *em)
{
struct tcf_em_nbyte *nbyte = data;
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index 15d353d..45d53d5 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -45,7 +45,7 @@ static int em_text_match(struct sk_buff *skb, struct tcf_ematch *m,
return skb_find_text(skb, from, to, tm->config, &state) != UINT_MAX;
}
-static int em_text_change(struct tcf_proto *tp, void *data, int len,
+static int em_text_change(struct net *net, void *data, int len,
struct tcf_ematch *m)
{
struct text_match *tm;
@@ -100,7 +100,7 @@ retry:
return 0;
}
-static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+static void em_text_destroy(struct net *net, struct tcf_ematch *m)
{
if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config)
textsearch_destroy(EM_TEXT_PRIV(m)->config);
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 3a633de..b3b90ef 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -170,7 +170,7 @@ static inline struct tcf_ematch *tcf_em_get_match(struct tcf_ematch_tree *tree,
}
-static int tcf_em_validate(struct tcf_proto *tp,
+static int tcf_em_validate(struct net *net,
struct tcf_ematch_tree_hdr *tree_hdr,
struct tcf_ematch *em, struct nlattr *nla, int idx)
{
@@ -240,7 +240,7 @@ static int tcf_em_validate(struct tcf_proto *tp,
goto errout;
if (em->ops->change) {
- err = em->ops->change(tp, data, data_len, em);
+ err = em->ops->change(net, data, data_len, em);
if (err < 0)
goto errout;
} else if (data_len > 0) {
@@ -285,7 +285,7 @@ static const struct nla_policy em_policy[TCA_EMATCH_TREE_MAX + 1] = {
/**
* tcf_em_tree_validate - validate ematch config TLV and build ematch tree
*
- * @tp: classifier kind handle
+ * @net: callers net reference
* @nla: ematch tree configuration TLV
* @tree: destination ematch tree variable to store the resulting
* ematch tree.
@@ -298,7 +298,7 @@ static const struct nla_policy em_policy[TCA_EMATCH_TREE_MAX + 1] = {
*
* Returns a negative error code if the configuration TLV contains errors.
*/
-int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
+int tcf_em_tree_validate(struct net *net, struct nlattr *nla,
struct tcf_ematch_tree *tree)
{
int idx, list_len, matches_len, err;
@@ -356,7 +356,7 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
em = tcf_em_get_match(tree, idx);
- err = tcf_em_validate(tp, tree_hdr, em, rt_match, idx);
+ err = tcf_em_validate(net, tree_hdr, em, rt_match, idx);
if (err < 0)
goto errout_abort;
@@ -378,7 +378,7 @@ errout:
return err;
errout_abort:
- tcf_em_tree_destroy(tp, tree);
+ tcf_em_tree_destroy(net, tree);
return err;
}
EXPORT_SYMBOL(tcf_em_tree_validate);
@@ -386,14 +386,14 @@ EXPORT_SYMBOL(tcf_em_tree_validate);
/**
* tcf_em_tree_destroy - destroy an ematch tree
*
- * @tp: classifier kind handle
+ * @net: callers net reference
* @tree: ematch tree to be deleted
*
* This functions destroys an ematch tree previously created by
* tcf_em_tree_validate()/tcf_em_tree_change(). You must ensure that
* the ematch tree is not in use before calling this function.
*/
-void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
+void tcf_em_tree_destroy(struct net *net, struct tcf_ematch_tree *tree)
{
int i;
@@ -405,7 +405,7 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
if (em->ops) {
if (em->ops->destroy)
- em->ops->destroy(tp, em);
+ em->ops->destroy(net, em);
else if (!tcf_em_is_simple(em))
kfree((void *) em->data);
module_put(em->ops->owner);
next prev parent reply other threads:[~2014-10-03 5:46 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-03 5:45 [PATCH v1 1/2] net: sched: do not use tcf_proto 'tp' argument from call_rcu John Fastabend
2014-10-03 5:46 ` John Fastabend [this message]
2014-10-03 22:40 ` [PATCH v1 2/2] net: sched: replace ematch calls to use struct net Cong Wang
2014-10-04 0:19 ` John Fastabend
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=20141003054624.20925.28150.stgit@nitbit.x32 \
--to=john.fastabend@gmail.com \
--cc=davem@davemloft.net \
--cc=eric.dumazet@gmail.com \
--cc=jhs@mojatatu.com \
--cc=netdev@vger.kernel.org \
--cc=xiyou.wangcong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.