Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 236570
b: refs/heads/master
c: 0e60ebe
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and Patrick McHardy committed Nov 15, 2010
1 parent fe7a701 commit 9db30bf
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 29 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: 9811600f7c1f18152430c6b93b0a76fdd88a59ce
refs/heads/master: 0e60ebe04c51807db972d03665651ae6b5c26d7e
6 changes: 3 additions & 3 deletions trunk/include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ struct nf_afinfo {
int route_key_size;
};

extern const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO];
extern const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO];
static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
{
return rcu_dereference(nf_afinfo[family]);
Expand Down Expand Up @@ -355,9 +355,9 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
#endif /*CONFIG_NETFILTER*/

#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *) __rcu;
extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
extern void (*nf_ct_destroy)(struct nf_conntrack *);
extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif
Expand Down
4 changes: 2 additions & 2 deletions trunk/include/net/netfilter/nf_conntrack_ecache.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct nf_ct_event_notifier {
int (*fcn)(unsigned int events, struct nf_ct_event *item);
};

extern struct nf_ct_event_notifier *nf_conntrack_event_cb;
extern struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);

Expand Down Expand Up @@ -167,7 +167,7 @@ struct nf_exp_event_notifier {
int (*fcn)(unsigned int events, struct nf_exp_event *item);
};

extern struct nf_exp_event_notifier *nf_expect_event_cb;
extern struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
extern int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *nb);
extern void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *nb);

Expand Down
2 changes: 1 addition & 1 deletion trunk/include/net/netfilter/nf_conntrack_l3proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct nf_conntrack_l3proto {
struct module *me;
};

extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];

/* Protocol registration. */
extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/netfilter/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ EXPORT_SYMBOL(skb_make_writable);
/* This does not belong here, but locally generated errors need it if connection
tracking in use: without this, connection may not be in hash table, and hence
manufactured ICMP or RST packets will not be associated with it. */
void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *) __rcu __read_mostly;
EXPORT_SYMBOL(ip_ct_attach);

void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
Expand All @@ -229,7 +229,7 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
}
EXPORT_SYMBOL(nf_ct_attach);

void (*nf_ct_destroy)(struct nf_conntrack *);
void (*nf_ct_destroy)(struct nf_conntrack *) __rcu __read_mostly;
EXPORT_SYMBOL(nf_ct_destroy);

void nf_conntrack_destroy(struct nf_conntrack *nfct)
Expand Down
6 changes: 3 additions & 3 deletions trunk/net/netfilter/nf_conntrack_expect.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
struct hlist_node *n;

for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
n = rcu_dereference(hlist_first_rcu(&net->ct.expect_hash[st->bucket]));
if (n)
return n;
}
Expand All @@ -495,11 +495,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
struct net *net = seq_file_net(seq);
struct ct_expect_iter_state *st = seq->private;

head = rcu_dereference(head->next);
head = rcu_dereference(hlist_next_rcu(head));
while (head == NULL) {
if (++st->bucket >= nf_ct_expect_hsize)
return NULL;
head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
head = rcu_dereference(hlist_first_rcu(&net->ct.expect_hash[st->bucket]));
}
return head;
}
Expand Down
20 changes: 15 additions & 5 deletions trunk/net/netfilter/nf_conntrack_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto
int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
{
int ret = 0;
struct nf_conntrack_l3proto *old;

if (proto->l3proto >= AF_MAX)
return -EBUSY;
Expand All @@ -174,7 +175,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
return -EINVAL;

mutex_lock(&nf_ct_proto_mutex);
if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
old = rcu_dereference_protected(nf_ct_l3protos[proto->l3proto],
lockdep_is_held(&nf_ct_proto_mutex));
if (old != &nf_conntrack_l3proto_generic) {
ret = -EBUSY;
goto out_unlock;
}
Expand All @@ -201,7 +204,9 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
BUG_ON(proto->l3proto >= AF_MAX);

mutex_lock(&nf_ct_proto_mutex);
BUG_ON(nf_ct_l3protos[proto->l3proto] != proto);
BUG_ON(rcu_dereference_protected(nf_ct_l3protos[proto->l3proto],
lockdep_is_held(&nf_ct_proto_mutex)
) != proto);
rcu_assign_pointer(nf_ct_l3protos[proto->l3proto],
&nf_conntrack_l3proto_generic);
nf_ct_l3proto_unregister_sysctl(proto);
Expand Down Expand Up @@ -299,8 +304,10 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
smp_wmb();

nf_ct_protos[l4proto->l3proto] = proto_array;
} else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] !=
&nf_conntrack_l4proto_generic) {
} else if (rcu_dereference_protected(
nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
lockdep_is_held(&nf_ct_proto_mutex)
) != &nf_conntrack_l4proto_generic) {
ret = -EBUSY;
goto out_unlock;
}
Expand Down Expand Up @@ -331,7 +338,10 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
BUG_ON(l4proto->l3proto >= PF_MAX);

mutex_lock(&nf_ct_proto_mutex);
BUG_ON(nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != l4proto);
BUG_ON(rcu_dereference_protected(
nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
lockdep_is_held(&nf_ct_proto_mutex)
) != l4proto);
rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
&nf_conntrack_l4proto_generic);
nf_ct_l4proto_unregister_sysctl(l4proto);
Expand Down
9 changes: 6 additions & 3 deletions trunk/net/netfilter/nf_conntrack_standalone.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_acct.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <linux/rculist_nulls.h>

MODULE_LICENSE("GPL");

Expand Down Expand Up @@ -56,7 +57,7 @@ static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
for (st->bucket = 0;
st->bucket < net->ct.htable_size;
st->bucket++) {
n = rcu_dereference(net->ct.hash[st->bucket].first);
n = rcu_dereference(hlist_nulls_first_rcu(&net->ct.hash[st->bucket]));
if (!is_a_nulls(n))
return n;
}
Expand All @@ -69,13 +70,15 @@ static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
struct net *net = seq_file_net(seq);
struct ct_iter_state *st = seq->private;

head = rcu_dereference(head->next);
head = rcu_dereference(hlist_nulls_next_rcu(head));
while (is_a_nulls(head)) {
if (likely(get_nulls_value(head) == st->bucket)) {
if (++st->bucket >= net->ct.htable_size)
return NULL;
}
head = rcu_dereference(net->ct.hash[st->bucket].first);
head = rcu_dereference(
hlist_nulls_first_rcu(
&net->ct.hash[st->bucket]));
}
return head;
}
Expand Down
6 changes: 4 additions & 2 deletions trunk/net/netfilter/nf_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ static int seq_show(struct seq_file *s, void *v)
struct nf_logger *t;
int ret;

logger = nf_loggers[*pos];
logger = rcu_dereference_protected(nf_loggers[*pos],
lockdep_is_held(&nf_log_mutex));

if (!logger)
ret = seq_printf(s, "%2lld NONE (", *pos);
Expand Down Expand Up @@ -249,7 +250,8 @@ static int nf_log_proc_dostring(ctl_table *table, int write,
mutex_unlock(&nf_log_mutex);
} else {
mutex_lock(&nf_log_mutex);
logger = nf_loggers[tindex];
logger = rcu_dereference_protected(nf_loggers[tindex],
lockdep_is_held(&nf_log_mutex));
if (!logger)
table->data = "NONE";
else
Expand Down
18 changes: 14 additions & 4 deletions trunk/net/netfilter/nf_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ static DEFINE_MUTEX(queue_handler_mutex);
int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
{
int ret;
const struct nf_queue_handler *old;

if (pf >= ARRAY_SIZE(queue_handler))
return -EINVAL;

mutex_lock(&queue_handler_mutex);
if (queue_handler[pf] == qh)
old = rcu_dereference_protected(queue_handler[pf],
lockdep_is_held(&queue_handler_mutex));
if (old == qh)
ret = -EEXIST;
else if (queue_handler[pf])
else if (old)
ret = -EBUSY;
else {
rcu_assign_pointer(queue_handler[pf], qh);
Expand All @@ -49,11 +52,15 @@ EXPORT_SYMBOL(nf_register_queue_handler);
/* The caller must flush their queue before this */
int nf_unregister_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
{
const struct nf_queue_handler *old;

if (pf >= ARRAY_SIZE(queue_handler))
return -EINVAL;

mutex_lock(&queue_handler_mutex);
if (queue_handler[pf] && queue_handler[pf] != qh) {
old = rcu_dereference_protected(queue_handler[pf],
lockdep_is_held(&queue_handler_mutex));
if (old && old != qh) {
mutex_unlock(&queue_handler_mutex);
return -EINVAL;
}
Expand All @@ -73,7 +80,10 @@ void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)

mutex_lock(&queue_handler_mutex);
for (pf = 0; pf < ARRAY_SIZE(queue_handler); pf++) {
if (queue_handler[pf] == qh)
if (rcu_dereference_protected(
queue_handler[pf],
lockdep_is_held(&queue_handler_mutex)
) == qh)
rcu_assign_pointer(queue_handler[pf], NULL);
}
mutex_unlock(&queue_handler_mutex);
Expand Down
6 changes: 3 additions & 3 deletions trunk/net/netfilter/nfnetlink_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,19 +874,19 @@ static struct hlist_node *get_first(struct iter_state *st)

for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
if (!hlist_empty(&instance_table[st->bucket]))
return rcu_dereference_bh(instance_table[st->bucket].first);
return rcu_dereference_bh(hlist_first_rcu(&instance_table[st->bucket]));
}
return NULL;
}

static struct hlist_node *get_next(struct iter_state *st, struct hlist_node *h)
{
h = rcu_dereference_bh(h->next);
h = rcu_dereference_bh(hlist_next_rcu(h));
while (!h) {
if (++st->bucket >= INSTANCE_BUCKETS)
return NULL;

h = rcu_dereference_bh(instance_table[st->bucket].first);
h = rcu_dereference_bh(hlist_first_rcu(&instance_table[st->bucket]));
}
return h;
}
Expand Down

0 comments on commit 9db30bf

Please sign in to comment.