Loading fs/proc/proc_net.c +38 −0 Original line number Diff line number Diff line Loading @@ -22,10 +22,48 @@ #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) { Loading include/linux/seq_file.h +13 −0 Original line number Diff line number Diff line Loading @@ -63,5 +63,18 @@ extern struct list_head *seq_list_start_head(struct list_head *head, 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 net/core/dev.c +5 −23 Original line number Diff line number Diff line Loading @@ -2364,7 +2364,7 @@ static int dev_ifconf(struct net *net, char __user *arg) */ 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; Loading @@ -2382,7 +2382,7 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos) 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); Loading Loading @@ -2481,26 +2481,8 @@ static const struct seq_operations dev_seq_ops = { 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 = { Loading @@ -2508,7 +2490,7 @@ 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 = { Loading net/core/dev_mcast.c +4 −22 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ EXPORT_SYMBOL(dev_mc_unsync); #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; Loading Loading @@ -241,26 +241,8 @@ static const struct seq_operations dev_mc_seq_ops = { 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 = { Loading @@ -268,7 +250,7 @@ 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 Loading net/netlink/af_netlink.c +7 −26 Original line number Diff line number Diff line Loading @@ -1681,7 +1681,7 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, #ifdef CONFIG_PROC_FS struct nl_seq_iter { struct net *net; struct seq_net_private p; int link; int hash_idx; }; Loading @@ -1699,7 +1699,7 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos) 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; Loading Loading @@ -1734,7 +1734,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) 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; Loading @@ -1746,7 +1746,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) 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; Loading Loading @@ -1802,27 +1802,8 @@ static const struct seq_operations netlink_seq_ops = { 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 = { Loading @@ -1830,7 +1811,7 @@ 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 Loading Loading
fs/proc/proc_net.c +38 −0 Original line number Diff line number Diff line Loading @@ -22,10 +22,48 @@ #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) { Loading
include/linux/seq_file.h +13 −0 Original line number Diff line number Diff line Loading @@ -63,5 +63,18 @@ extern struct list_head *seq_list_start_head(struct list_head *head, 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
net/core/dev.c +5 −23 Original line number Diff line number Diff line Loading @@ -2364,7 +2364,7 @@ static int dev_ifconf(struct net *net, char __user *arg) */ 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; Loading @@ -2382,7 +2382,7 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos) 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); Loading Loading @@ -2481,26 +2481,8 @@ static const struct seq_operations dev_seq_ops = { 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 = { Loading @@ -2508,7 +2490,7 @@ 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 = { Loading
net/core/dev_mcast.c +4 −22 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ EXPORT_SYMBOL(dev_mc_unsync); #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; Loading Loading @@ -241,26 +241,8 @@ static const struct seq_operations dev_mc_seq_ops = { 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 = { Loading @@ -268,7 +250,7 @@ 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 Loading
net/netlink/af_netlink.c +7 −26 Original line number Diff line number Diff line Loading @@ -1681,7 +1681,7 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, #ifdef CONFIG_PROC_FS struct nl_seq_iter { struct net *net; struct seq_net_private p; int link; int hash_idx; }; Loading @@ -1699,7 +1699,7 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos) 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; Loading Loading @@ -1734,7 +1734,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) 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; Loading @@ -1746,7 +1746,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) 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; Loading Loading @@ -1802,27 +1802,8 @@ static const struct seq_operations netlink_seq_ops = { 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 = { Loading @@ -1830,7 +1811,7 @@ 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 Loading