static struct hlist_node *ct_get_first(struct seq_file *seq)
{
struct ct_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0;
st->bucket < nf_conntrack_htable_size;
st->bucket++) {
- if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
- return nf_conntrack_hash[st->bucket].first;
+ n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
{
struct ct_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_conntrack_htable_size)
return NULL;
- head = nf_conntrack_hash[st->bucket].first;
+ head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
}
return head;
}
}
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_get_idx(seq, *pos);
}
}
static void ct_seq_stop(struct seq_file *s, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
static int ct_seq_show(struct seq_file *s, void *v)
{
const struct nf_conntrack_tuple_hash *hash = v;
const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
- struct nf_conntrack_l3proto *l3proto;
- struct nf_conntrack_l4proto *l4proto;
+ const struct nf_conntrack_l3proto *l3proto;
+ const struct nf_conntrack_l4proto *l4proto;
NF_CT_ASSERT(ct);
? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
return -ENOSPC;
- if (l4proto->print_conntrack(s, ct))
+ if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
return -ENOSPC;
if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
{
struct ct_expect_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
- if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
- return nf_ct_expect_hash[st->bucket].first;
+ n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
{
struct ct_expect_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_ct_expect_hsize)
return NULL;
- head = nf_ct_expect_hash[st->bucket].first;
+ head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
}
return head;
}
}
static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_expect_get_idx(seq, *pos);
}
}
static void exp_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
static int exp_seq_show(struct seq_file *s, void *v)
{
struct nf_conntrack_expect *exp;
- struct hlist_node *n = v;
+ const struct hlist_node *n = v;
exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
static int ct_cpu_seq_show(struct seq_file *seq, void *v)
{
unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
- struct ip_conntrack_stat *st = v;
+ const struct ip_conntrack_stat *st = v;
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");