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_create(struct net
*net
,
30 const char *name
, mode_t mode
, get_info_t
*get_info
)
32 return create_proc_info_entry(name
,mode
, net
->proc_net
, get_info
);
34 EXPORT_SYMBOL_GPL(proc_net_create
);
36 struct proc_dir_entry
*proc_net_fops_create(struct net
*net
,
37 const char *name
, mode_t mode
, const struct file_operations
*fops
)
39 struct proc_dir_entry
*res
;
41 res
= create_proc_entry(name
, mode
, net
->proc_net
);
43 res
->proc_fops
= fops
;
46 EXPORT_SYMBOL_GPL(proc_net_fops_create
);
48 void proc_net_remove(struct net
*net
, const char *name
)
50 remove_proc_entry(name
, net
->proc_net
);
52 EXPORT_SYMBOL_GPL(proc_net_remove
);
54 struct net
*get_proc_net(const struct inode
*inode
)
56 return maybe_get_net(PDE_NET(PDE(inode
)));
58 EXPORT_SYMBOL_GPL(get_proc_net
);
60 static struct proc_dir_entry
*proc_net_shadow
;
62 static struct dentry
*proc_net_shadow_dentry(struct dentry
*parent
,
63 struct proc_dir_entry
*de
)
65 struct dentry
*shadow
= NULL
;
70 inode
= proc_get_inode(parent
->d_inode
->i_sb
, de
->low_ino
, de
);
73 shadow
= d_alloc_name(parent
, de
->name
);
76 shadow
->d_op
= parent
->d_op
; /* proc_dentry_operations */
77 d_instantiate(shadow
, inode
);
87 static void *proc_net_follow_link(struct dentry
*parent
, struct nameidata
*nd
)
89 struct net
*net
= current
->nsproxy
->net_ns
;
90 struct dentry
*shadow
;
91 shadow
= proc_net_shadow_dentry(parent
, net
->proc_net
);
93 return ERR_PTR(-ENOENT
);
96 /* My dentry count is 1 and that should be enough as the
97 * shadow dentry is thrown away immediately.
103 static struct dentry
*proc_net_lookup(struct inode
*dir
, struct dentry
*dentry
,
104 struct nameidata
*nd
)
106 struct net
*net
= current
->nsproxy
->net_ns
;
107 struct dentry
*shadow
;
109 shadow
= proc_net_shadow_dentry(nd
->dentry
, net
->proc_net
);
111 return ERR_PTR(-ENOENT
);
116 return shadow
->d_inode
->i_op
->lookup(shadow
->d_inode
, dentry
, nd
);
119 static int proc_net_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
121 struct net
*net
= current
->nsproxy
->net_ns
;
122 struct dentry
*shadow
;
125 shadow
= proc_net_shadow_dentry(dentry
->d_parent
, net
->proc_net
);
128 ret
= shadow
->d_inode
->i_op
->setattr(shadow
, iattr
);
133 static const struct file_operations proc_net_dir_operations
= {
134 .read
= generic_read_dir
,
137 static struct inode_operations proc_net_dir_inode_operations
= {
138 .follow_link
= proc_net_follow_link
,
139 .lookup
= proc_net_lookup
,
140 .setattr
= proc_net_setattr
,
143 static __net_init
int proc_net_ns_init(struct net
*net
)
145 struct proc_dir_entry
*root
, *netd
, *net_statd
;
149 root
= kzalloc(sizeof(*root
), GFP_KERNEL
);
154 netd
= proc_mkdir("net", root
);
159 net_statd
= proc_mkdir("stat", netd
);
165 net_statd
->data
= net
;
167 net
->proc_net_root
= root
;
168 net
->proc_net
= netd
;
169 net
->proc_net_stat
= net_statd
;
175 remove_proc_entry("net", root
);
181 static __net_exit
void proc_net_ns_exit(struct net
*net
)
183 remove_proc_entry("stat", net
->proc_net
);
184 remove_proc_entry("net", net
->proc_net_root
);
185 kfree(net
->proc_net_root
);
188 struct pernet_operations __net_initdata proc_net_ns_ops
= {
189 .init
= proc_net_ns_init
,
190 .exit
= proc_net_ns_exit
,
193 int __init
proc_net_init(void)
195 proc_net_shadow
= proc_mkdir("net", NULL
);
196 proc_net_shadow
->proc_iops
= &proc_net_dir_inode_operations
;
197 proc_net_shadow
->proc_fops
= &proc_net_dir_operations
;
199 return register_pernet_subsys(&proc_net_ns_ops
);