6 * Author: Eric Biederman <ebiederm@xmission.com>
8 * proc net directory handling functions
11 #include <linux/uaccess.h>
13 #include <linux/errno.h>
14 #include <linux/time.h>
15 #include <linux/proc_fs.h>
16 #include <linux/stat.h>
17 #include <linux/slab.h>
18 #include <linux/init.h>
19 #include <linux/sched.h>
20 #include <linux/sched/task.h>
21 #include <linux/module.h>
22 #include <linux/bitops.h>
23 #include <linux/mount.h>
24 #include <linux/nsproxy.h>
25 #include <linux/uidgid.h>
26 #include <net/net_namespace.h>
27 #include <linux/seq_file.h>
31 static inline struct net
*PDE_NET(struct proc_dir_entry
*pde
)
33 return pde
->parent
->data
;
36 static struct net
*get_proc_net(const struct inode
*inode
)
38 return maybe_get_net(PDE_NET(PDE(inode
)));
41 int seq_open_net(struct inode
*ino
, struct file
*f
,
42 const struct seq_operations
*ops
, int size
)
45 struct seq_net_private
*p
;
47 BUG_ON(size
< sizeof(*p
));
49 net
= get_proc_net(ino
);
53 p
= __seq_open_private(f
, ops
, size
);
63 EXPORT_SYMBOL_GPL(seq_open_net
);
65 int single_open_net(struct inode
*inode
, struct file
*file
,
66 int (*show
)(struct seq_file
*, void *))
72 net
= get_proc_net(inode
);
76 err
= single_open(file
, show
, net
);
87 EXPORT_SYMBOL_GPL(single_open_net
);
89 int seq_release_net(struct inode
*ino
, struct file
*f
)
93 seq
= f
->private_data
;
95 put_net(seq_file_net(seq
));
96 seq_release_private(ino
, f
);
99 EXPORT_SYMBOL_GPL(seq_release_net
);
101 int single_release_net(struct inode
*ino
, struct file
*f
)
103 struct seq_file
*seq
= f
->private_data
;
104 put_net(seq
->private);
105 return single_release(ino
, f
);
107 EXPORT_SYMBOL_GPL(single_release_net
);
109 static struct net
*get_proc_task_net(struct inode
*dir
)
111 struct task_struct
*task
;
113 struct net
*net
= NULL
;
116 task
= pid_task(proc_pid(dir
), PIDTYPE_PID
);
121 net
= get_net(ns
->net_ns
);
129 static struct dentry
*proc_tgid_net_lookup(struct inode
*dir
,
130 struct dentry
*dentry
, unsigned int flags
)
135 de
= ERR_PTR(-ENOENT
);
136 net
= get_proc_task_net(dir
);
138 de
= proc_lookup_de(net
->proc_net
, dir
, dentry
);
144 static int proc_tgid_net_getattr(const struct path
*path
, struct kstat
*stat
,
145 u32 request_mask
, unsigned int query_flags
)
147 struct inode
*inode
= d_inode(path
->dentry
);
150 net
= get_proc_task_net(inode
);
152 generic_fillattr(inode
, stat
);
155 stat
->nlink
= net
->proc_net
->nlink
;
162 const struct inode_operations proc_net_inode_operations
= {
163 .lookup
= proc_tgid_net_lookup
,
164 .getattr
= proc_tgid_net_getattr
,
167 static int proc_tgid_net_readdir(struct file
*file
, struct dir_context
*ctx
)
173 net
= get_proc_task_net(file_inode(file
));
175 ret
= proc_readdir_de(net
->proc_net
, file
, ctx
);
181 const struct file_operations proc_net_operations
= {
182 .llseek
= generic_file_llseek
,
183 .read
= generic_read_dir
,
184 .iterate_shared
= proc_tgid_net_readdir
,
187 static __net_init
int proc_net_ns_init(struct net
*net
)
189 struct proc_dir_entry
*netd
, *net_statd
;
195 netd
= kzalloc(sizeof(*netd
) + 4, GFP_KERNEL
);
199 netd
->subdir
= RB_ROOT
;
203 netd
->parent
= &proc_root
;
204 memcpy(netd
->name
, "net", 4);
206 uid
= make_kuid(net
->user_ns
, 0);
210 gid
= make_kgid(net
->user_ns
, 0);
214 proc_set_user(netd
, uid
, gid
);
217 net_statd
= proc_net_mkdir(net
, "stat", netd
);
221 net
->proc_net
= netd
;
222 net
->proc_net_stat
= net_statd
;
231 static __net_exit
void proc_net_ns_exit(struct net
*net
)
233 remove_proc_entry("stat", net
->proc_net
);
234 kfree(net
->proc_net
);
237 static struct pernet_operations __net_initdata proc_net_ns_ops
= {
238 .init
= proc_net_ns_init
,
239 .exit
= proc_net_ns_exit
,
242 int __init
proc_net_init(void)
244 proc_symlink("net", NULL
, "self/net");
246 return register_pernet_subsys(&proc_net_ns_ops
);