6 * Author: Eric Biederman <ebiederm@xmission.com>
8 * proc net directory handling functions
11 #include <asm/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/init.h>
18 #include <linux/sched.h>
19 #include <linux/module.h>
20 #include <linux/bitops.h>
21 #include <linux/smp_lock.h>
22 #include <linux/mount.h>
23 #include <linux/nsproxy.h>
24 #include <net/net_namespace.h>
29 struct proc_dir_entry
*proc_net_fops_create(struct net
*net
,
30 const char *name
, mode_t mode
, const struct file_operations
*fops
)
32 struct proc_dir_entry
*res
;
34 res
= create_proc_entry(name
, mode
, net
->proc_net
);
36 res
->proc_fops
= fops
;
39 EXPORT_SYMBOL_GPL(proc_net_fops_create
);
41 void proc_net_remove(struct net
*net
, const char *name
)
43 remove_proc_entry(name
, net
->proc_net
);
45 EXPORT_SYMBOL_GPL(proc_net_remove
);
47 struct net
*get_proc_net(const struct inode
*inode
)
49 return maybe_get_net(PDE_NET(PDE(inode
)));
51 EXPORT_SYMBOL_GPL(get_proc_net
);
53 static struct proc_dir_entry
*proc_net_shadow
;
55 static struct dentry
*proc_net_shadow_dentry(struct dentry
*parent
,
56 struct proc_dir_entry
*de
)
58 struct dentry
*shadow
= NULL
;
63 inode
= proc_get_inode(parent
->d_inode
->i_sb
, de
->low_ino
, de
);
66 shadow
= d_alloc_name(parent
, de
->name
);
69 shadow
->d_op
= parent
->d_op
; /* proc_dentry_operations */
70 d_instantiate(shadow
, inode
);
80 static void *proc_net_follow_link(struct dentry
*parent
, struct nameidata
*nd
)
82 struct net
*net
= current
->nsproxy
->net_ns
;
83 struct dentry
*shadow
;
84 shadow
= proc_net_shadow_dentry(parent
, net
->proc_net
);
86 return ERR_PTR(-ENOENT
);
89 /* My dentry count is 1 and that should be enough as the
90 * shadow dentry is thrown away immediately.
96 static struct dentry
*proc_net_lookup(struct inode
*dir
, struct dentry
*dentry
,
99 struct net
*net
= current
->nsproxy
->net_ns
;
100 struct dentry
*shadow
;
102 shadow
= proc_net_shadow_dentry(nd
->dentry
, net
->proc_net
);
104 return ERR_PTR(-ENOENT
);
109 return shadow
->d_inode
->i_op
->lookup(shadow
->d_inode
, dentry
, nd
);
112 static int proc_net_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
114 struct net
*net
= current
->nsproxy
->net_ns
;
115 struct dentry
*shadow
;
118 shadow
= proc_net_shadow_dentry(dentry
->d_parent
, net
->proc_net
);
121 ret
= shadow
->d_inode
->i_op
->setattr(shadow
, iattr
);
126 static const struct file_operations proc_net_dir_operations
= {
127 .read
= generic_read_dir
,
130 static struct inode_operations proc_net_dir_inode_operations
= {
131 .follow_link
= proc_net_follow_link
,
132 .lookup
= proc_net_lookup
,
133 .setattr
= proc_net_setattr
,
136 static __net_init
int proc_net_ns_init(struct net
*net
)
138 struct proc_dir_entry
*root
, *netd
, *net_statd
;
142 root
= kzalloc(sizeof(*root
), GFP_KERNEL
);
147 netd
= proc_mkdir("net", root
);
152 net_statd
= proc_mkdir("stat", netd
);
158 net_statd
->data
= net
;
160 net
->proc_net_root
= root
;
161 net
->proc_net
= netd
;
162 net
->proc_net_stat
= net_statd
;
168 remove_proc_entry("net", root
);
174 static __net_exit
void proc_net_ns_exit(struct net
*net
)
176 remove_proc_entry("stat", net
->proc_net
);
177 remove_proc_entry("net", net
->proc_net_root
);
178 kfree(net
->proc_net_root
);
181 static struct pernet_operations __net_initdata proc_net_ns_ops
= {
182 .init
= proc_net_ns_init
,
183 .exit
= proc_net_ns_exit
,
186 int __init
proc_net_init(void)
188 proc_net_shadow
= proc_mkdir("net", NULL
);
189 proc_net_shadow
->proc_iops
= &proc_net_dir_inode_operations
;
190 proc_net_shadow
->proc_fops
= &proc_net_dir_operations
;
192 return register_pernet_subsys(&proc_net_ns_ops
);