diff options
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 99 |
1 files changed, 37 insertions, 62 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b61a770884fa..51559a8c6e57 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2582,12 +2582,13 @@ EXPORT_SYMBOL(udp_prot); static struct sock *udp_get_first(struct seq_file *seq, int start) { struct sock *sk; + struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file)); struct udp_iter_state *state = seq->private; struct net *net = seq_file_net(seq); - for (state->bucket = start; state->bucket <= state->udp_table->mask; + for (state->bucket = start; state->bucket <= afinfo->udp_table->mask; ++state->bucket) { - struct udp_hslot *hslot = &state->udp_table->hash[state->bucket]; + struct udp_hslot *hslot = &afinfo->udp_table->hash[state->bucket]; if (hlist_empty(&hslot->head)) continue; @@ -2596,7 +2597,7 @@ static struct sock *udp_get_first(struct seq_file *seq, int start) sk_for_each(sk, &hslot->head) { if (!net_eq(sock_net(sk), net)) continue; - if (sk->sk_family == state->family) + if (sk->sk_family == afinfo->family) goto found; } spin_unlock_bh(&hslot->lock); @@ -2608,16 +2609,17 @@ found: static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk) { + struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file)); struct udp_iter_state *state = seq->private; struct net *net = seq_file_net(seq); do { sk = sk_next(sk); - } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family)); + } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != afinfo->family)); if (!sk) { - if (state->bucket <= state->udp_table->mask) - spin_unlock_bh(&state->udp_table->hash[state->bucket].lock); + if (state->bucket <= afinfo->udp_table->mask) + spin_unlock_bh(&afinfo->udp_table->hash[state->bucket].lock); return udp_get_first(seq, state->bucket + 1); } return sk; @@ -2633,15 +2635,16 @@ static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos) return pos ? NULL : sk; } -static void *udp_seq_start(struct seq_file *seq, loff_t *pos) +void *udp_seq_start(struct seq_file *seq, loff_t *pos) { struct udp_iter_state *state = seq->private; state->bucket = MAX_UDP_PORTS; return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN; } +EXPORT_SYMBOL(udp_seq_start); -static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos) +void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct sock *sk; @@ -2653,56 +2656,17 @@ static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos) ++*pos; return sk; } +EXPORT_SYMBOL(udp_seq_next); -static void udp_seq_stop(struct seq_file *seq, void *v) +void udp_seq_stop(struct seq_file *seq, void *v) { + struct udp_seq_afinfo *afinfo = PDE_DATA(file_inode(seq->file)); struct udp_iter_state *state = seq->private; - if (state->bucket <= state->udp_table->mask) - spin_unlock_bh(&state->udp_table->hash[state->bucket].lock); + if (state->bucket <= afinfo->udp_table->mask) + spin_unlock_bh(&afinfo->udp_table->hash[state->bucket].lock); } - -int udp_seq_open(struct inode *inode, struct file *file) -{ - struct udp_seq_afinfo *afinfo = PDE_DATA(inode); - struct udp_iter_state *s; - int err; - - err = seq_open_net(inode, file, &afinfo->seq_ops, - sizeof(struct udp_iter_state)); - if (err < 0) - return err; - - s = ((struct seq_file *)file->private_data)->private; - s->family = afinfo->family; - s->udp_table = afinfo->udp_table; - return err; -} -EXPORT_SYMBOL(udp_seq_open); - -/* ------------------------------------------------------------------------ */ -int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo) -{ - struct proc_dir_entry *p; - int rc = 0; - - afinfo->seq_ops.start = udp_seq_start; - afinfo->seq_ops.next = udp_seq_next; - afinfo->seq_ops.stop = udp_seq_stop; - - p = proc_create_data(afinfo->name, 0444, net->proc_net, - afinfo->seq_fops, afinfo); - if (!p) - rc = -ENOMEM; - return rc; -} -EXPORT_SYMBOL(udp_proc_register); - -void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo) -{ - remove_proc_entry(afinfo->name, net->proc_net); -} -EXPORT_SYMBOL(udp_proc_unregister); +EXPORT_SYMBOL(udp_seq_stop); /* ------------------------------------------------------------------------ */ static void udp4_format_sock(struct sock *sp, struct seq_file *f, @@ -2742,32 +2706,43 @@ int udp4_seq_show(struct seq_file *seq, void *v) return 0; } -static const struct file_operations udp_afinfo_seq_fops = { +static const struct seq_operations udp_seq_ops = { + .start = udp_seq_start, + .next = udp_seq_next, + .stop = udp_seq_stop, + .show = udp4_seq_show, +}; + +static int udp_seq_open(struct inode *inode, struct file *file) +{ + return seq_open_net(inode, file, &udp_seq_ops, + sizeof(struct udp_iter_state)); +} + +const struct file_operations udp_afinfo_seq_fops = { .open = udp_seq_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release_net }; +EXPORT_SYMBOL(udp_afinfo_seq_fops); -/* ------------------------------------------------------------------------ */ static struct udp_seq_afinfo udp4_seq_afinfo = { - .name = "udp", .family = AF_INET, .udp_table = &udp_table, - .seq_fops = &udp_afinfo_seq_fops, - .seq_ops = { - .show = udp4_seq_show, - }, }; static int __net_init udp4_proc_init_net(struct net *net) { - return udp_proc_register(net, &udp4_seq_afinfo); + if (!proc_create_data("udp", 0444, net->proc_net, &udp_afinfo_seq_fops, + &udp4_seq_afinfo)) + return -ENOMEM; + return 0; } static void __net_exit udp4_proc_exit_net(struct net *net) { - udp_proc_unregister(net, &udp4_seq_afinfo); + remove_proc_entry("udp", net->proc_net); } static struct pernet_operations udp4_net_ops = { |