#include <linux/mount.h>
 #include <linux/nsproxy.h>
 #include <net/net_namespace.h>
+#include <linux/seq_file.h>
 
 #include "internal.h"
 
 
+int seq_open_net(struct inode *ino, struct file *f,
+                const struct seq_operations *ops, int size)
+{
+       struct net *net;
+       struct seq_net_private *p;
+
+       BUG_ON(size < sizeof(*p));
+
+       net = get_proc_net(ino);
+       if (net == NULL)
+               return -ENXIO;
+
+       p = __seq_open_private(f, ops, size);
+       if (p == NULL) {
+               put_net(net);
+               return -ENOMEM;
+       }
+       p->net = net;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(seq_open_net);
+
+int seq_release_net(struct inode *ino, struct file *f)
+{
+       struct seq_file *seq;
+       struct seq_net_private *p;
+
+       seq = f->private_data;
+       p = seq->private;
+
+       put_net(p->net);
+       seq_release_private(ino, f);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(seq_release_net);
+
+
 struct proc_dir_entry *proc_net_fops_create(struct net *net,
        const char *name, mode_t mode, const struct file_operations *fops)
 {
 
 extern struct list_head *seq_list_next(void *v, struct list_head *head,
                loff_t *ppos);
 
+struct net;
+struct seq_net_private {
+       struct net *net;
+};
+
+int seq_open_net(struct inode *, struct file *,
+                const struct seq_operations *, int);
+int seq_release_net(struct inode *, struct file *);
+static inline struct net *seq_file_net(struct seq_file *seq)
+{
+       return ((struct seq_net_private *)seq->private)->net;
+}
+
 #endif
 #endif
 
  */
 void *dev_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        loff_t off;
        struct net_device *dev;
 
 
 void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        ++*pos;
        return v == SEQ_START_TOKEN ?
                first_net_device(net) : next_net_device((struct net_device *)v);
 
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res =  seq_open(file, &dev_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int dev_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &dev_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations dev_seq_fops = {
        .open    = dev_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = dev_seq_release,
+       .release = seq_release_net,
 };
 
 static const struct seq_operations softnet_seq_ops = {
 
 #ifdef CONFIG_PROC_FS
 static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        struct net_device *dev;
        loff_t off = 0;
 
 
 static int dev_mc_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res = seq_open(file, &dev_mc_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int dev_mc_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &dev_mc_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations dev_mc_seq_fops = {
        .open    = dev_mc_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = dev_mc_seq_release,
+       .release = seq_release_net,
 };
 
 #endif
 
 
 #ifdef CONFIG_PROC_FS
 struct nl_seq_iter {
-       struct net *net;
+       struct seq_net_private p;
        int link;
        int hash_idx;
 };
 
                for (j = 0; j <= hash->mask; j++) {
                        sk_for_each(s, node, &hash->table[j]) {
-                               if (iter->net != s->sk_net)
+                               if (iter->p.net != s->sk_net)
                                        continue;
                                if (off == pos) {
                                        iter->link = i;
        s = v;
        do {
                s = sk_next(s);
-       } while (s && (iter->net != s->sk_net));
+       } while (s && (iter->p.net != s->sk_net));
        if (s)
                return s;
 
 
                for (; j <= hash->mask; j++) {
                        s = sk_head(&hash->table[j]);
-                       while (s && (iter->net != s->sk_net))
+                       while (s && (iter->p.net != s->sk_net))
                                s = sk_next(s);
                        if (s) {
                                iter->link = i;
 
 static int netlink_seq_open(struct inode *inode, struct file *file)
 {
-       struct nl_seq_iter *iter;
-
-       iter = __seq_open_private(file, &netlink_seq_ops, sizeof(*iter));
-       if (!iter)
-               return -ENOMEM;
-
-       iter->net = get_proc_net(inode);
-       if (!iter->net) {
-               seq_release_private(inode, file);
-               return -ENXIO;
-       }
-
-       return 0;
-}
-
-static int netlink_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct nl_seq_iter *iter = seq->private;
-       put_net(iter->net);
-       return seq_release_private(inode, file);
+       return seq_open_net(inode, file, &netlink_seq_ops,
+                               sizeof(struct nl_seq_iter));
 }
 
 static const struct file_operations netlink_seq_fops = {
        .open           = netlink_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = netlink_seq_release,
+       .release        = seq_release_net,
 };
 
 #endif
 
 
 static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        read_lock(&net->packet_sklist_lock);
        return *pos ? packet_seq_idx(net, *pos - 1) : SEQ_START_TOKEN;
 }
 
 static int packet_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res = seq_open(file, &packet_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int packet_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq=  file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &packet_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations packet_seq_fops = {
        .open           = packet_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = packet_seq_release,
+       .release        = seq_release_net,
 };
 
 #endif
 
 
 #ifdef CONFIG_PROC_FS
 struct unix_iter_state {
-       struct net *net;
+       struct seq_net_private p;
        int i;
 };
 static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos)
        struct sock *s;
 
        for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
-               if (s->sk_net != iter->net)
+               if (s->sk_net != iter->p.net)
                        continue;
                if (off == pos)
                        return s;
                sk = first_unix_socket(&iter->i);
        else
                sk = next_unix_socket(&iter->i, sk);
-       while (sk && (sk->sk_net != iter->net))
+       while (sk && (sk->sk_net != iter->p.net))
                sk = next_unix_socket(&iter->i, sk);
        return sk;
 }
 
 static int unix_seq_open(struct inode *inode, struct file *file)
 {
-       struct unix_iter_state *it;
-
-       it = __seq_open_private(file, &unix_seq_ops,
-                               sizeof(struct unix_iter_state));
-       if (it == NULL)
-               return -ENOMEM;
-
-       it->net = get_proc_net(inode);
-       if (it->net == NULL) {
-               seq_release_private(inode, file);
-               return -ENXIO;
-       }
-       return 0;
-}
-
-static int unix_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct unix_iter_state *iter = seq->private;
-       put_net(iter->net);
-       return seq_release_private(inode, file);
+       return seq_open_net(inode, file, &unix_seq_ops,
+                           sizeof(struct unix_iter_state));
 }
 
 static const struct file_operations unix_seq_fops = {
        .open           = unix_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = unix_seq_release,
+       .release        = seq_release_net,
 };
 
 #endif
 
 
 static int wireless_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res = seq_open(file, &wireless_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int wireless_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &wireless_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations wireless_seq_fops = {
        .open    = wireless_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = wireless_seq_release,
+       .release = seq_release_net,
 };
 
 int wext_proc_init(struct net *net)