diff options
Diffstat (limited to 'net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c')
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 114 |
1 files changed, 72 insertions, 42 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 89f933e81035..b3dd5de9a258 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c @@ -18,12 +18,6 @@ #include <net/netfilter/nf_conntrack_l4proto.h> #include <net/netfilter/nf_conntrack_expect.h> -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif - #ifdef CONFIG_NF_CT_ACCT static unsigned int seq_print_counters(struct seq_file *s, @@ -41,35 +35,36 @@ struct ct_iter_state { unsigned int bucket; }; -static struct list_head *ct_get_first(struct seq_file *seq) +static struct hlist_node *ct_get_first(struct seq_file *seq) { struct ct_iter_state *st = seq->private; for (st->bucket = 0; st->bucket < nf_conntrack_htable_size; st->bucket++) { - if (!list_empty(&nf_conntrack_hash[st->bucket])) - return nf_conntrack_hash[st->bucket].next; + if (!hlist_empty(&nf_conntrack_hash[st->bucket])) + return nf_conntrack_hash[st->bucket].first; } return NULL; } -static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head) +static struct hlist_node *ct_get_next(struct seq_file *seq, + struct hlist_node *head) { struct ct_iter_state *st = seq->private; head = head->next; - while (head == &nf_conntrack_hash[st->bucket]) { + while (head == NULL) { if (++st->bucket >= nf_conntrack_htable_size) return NULL; - head = nf_conntrack_hash[st->bucket].next; + head = nf_conntrack_hash[st->bucket].first; } return head; } -static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos) +static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos) { - struct list_head *head = ct_get_first(seq); + struct hlist_node *head = ct_get_first(seq); if (head) while (pos && (head = ct_get_next(seq, head))) @@ -169,7 +164,7 @@ static int ct_seq_show(struct seq_file *s, void *v) return 0; } -static struct seq_operations ct_seq_ops = { +static const struct seq_operations ct_seq_ops = { .start = ct_seq_start, .next = ct_seq_next, .stop = ct_seq_stop, @@ -182,7 +177,7 @@ static int ct_open(struct inode *inode, struct file *file) struct ct_iter_state *st; int ret; - st = kmalloc(sizeof(struct ct_iter_state), GFP_KERNEL); + st = kzalloc(sizeof(struct ct_iter_state), GFP_KERNEL); if (st == NULL) return -ENOMEM; ret = seq_open(file, &ct_seq_ops); @@ -190,7 +185,6 @@ static int ct_open(struct inode *inode, struct file *file) goto out_free; seq = file->private_data; seq->private = st; - memset(st, 0, sizeof(struct ct_iter_state)); return ret; out_free: kfree(st); @@ -206,47 +200,68 @@ static const struct file_operations ct_file_ops = { }; /* expects */ -static void *exp_seq_start(struct seq_file *s, loff_t *pos) +struct ct_expect_iter_state { + unsigned int bucket; +}; + +static struct hlist_node *ct_expect_get_first(struct seq_file *seq) { - struct list_head *e = &nf_conntrack_expect_list; - loff_t i; + struct ct_expect_iter_state *st = seq->private; - /* strange seq_file api calls stop even if we fail, - * thus we need to grab lock since stop unlocks */ - read_lock_bh(&nf_conntrack_lock); + 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; + } + return NULL; +} - if (list_empty(e)) - return NULL; +static struct hlist_node *ct_expect_get_next(struct seq_file *seq, + struct hlist_node *head) +{ + struct ct_expect_iter_state *st = seq->private; - for (i = 0; i <= *pos; i++) { - e = e->next; - if (e == &nf_conntrack_expect_list) + head = head->next; + while (head == NULL) { + if (++st->bucket >= nf_ct_expect_hsize) return NULL; + head = nf_ct_expect_hash[st->bucket].first; } - return e; + return head; } -static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos) +static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos) { - struct list_head *e = v; + struct hlist_node *head = ct_expect_get_first(seq); - ++*pos; - e = e->next; + if (head) + while (pos && (head = ct_expect_get_next(seq, head))) + pos--; + return pos ? NULL : head; +} - if (e == &nf_conntrack_expect_list) - return NULL; +static void *exp_seq_start(struct seq_file *seq, loff_t *pos) +{ + read_lock_bh(&nf_conntrack_lock); + return ct_expect_get_idx(seq, *pos); +} - return e; +static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + (*pos)++; + return ct_expect_get_next(seq, v); } -static void exp_seq_stop(struct seq_file *s, void *v) +static void exp_seq_stop(struct seq_file *seq, void *v) { read_unlock_bh(&nf_conntrack_lock); } static int exp_seq_show(struct seq_file *s, void *v) { - struct nf_conntrack_expect *exp = v; + struct nf_conntrack_expect *exp; + struct hlist_node *n = v; + + exp = hlist_entry(n, struct nf_conntrack_expect, hnode); if (exp->tuple.src.l3num != AF_INET) return 0; @@ -266,7 +281,7 @@ static int exp_seq_show(struct seq_file *s, void *v) return seq_putc(s, '\n'); } -static struct seq_operations exp_seq_ops = { +static const struct seq_operations exp_seq_ops = { .start = exp_seq_start, .next = exp_seq_next, .stop = exp_seq_stop, @@ -275,7 +290,22 @@ static struct seq_operations exp_seq_ops = { static int exp_open(struct inode *inode, struct file *file) { - return seq_open(file, &exp_seq_ops); + struct seq_file *seq; + struct ct_expect_iter_state *st; + int ret; + + st = kzalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL); + if (!st) + return -ENOMEM; + ret = seq_open(file, &exp_seq_ops); + if (ret) + goto out_free; + seq = file->private_data; + seq->private = st; + return ret; +out_free: + kfree(st); + return ret; } static const struct file_operations ip_exp_file_ops = { @@ -283,7 +313,7 @@ static const struct file_operations ip_exp_file_ops = { .open = exp_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release + .release = seq_release_private, }; static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) @@ -354,7 +384,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v) return 0; } -static struct seq_operations ct_cpu_seq_ops = { +static const struct seq_operations ct_cpu_seq_ops = { .start = ct_cpu_seq_start, .next = ct_cpu_seq_next, .stop = ct_cpu_seq_stop, |