xref: /linux/include/linux/ns_common.h (revision 18b19abc3709b109676ffd1f48dcd332c2e477d4)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_NS_COMMON_H
3 #define _LINUX_NS_COMMON_H
4 
5 #include <linux/refcount.h>
6 #include <linux/rbtree.h>
7 #include <uapi/linux/sched.h>
8 
9 struct proc_ns_operations;
10 
11 struct cgroup_namespace;
12 struct ipc_namespace;
13 struct mnt_namespace;
14 struct net;
15 struct pid_namespace;
16 struct time_namespace;
17 struct user_namespace;
18 struct uts_namespace;
19 
20 extern struct cgroup_namespace init_cgroup_ns;
21 extern struct ipc_namespace init_ipc_ns;
22 extern struct mnt_namespace init_mnt_ns;
23 extern struct net init_net;
24 extern struct pid_namespace init_pid_ns;
25 extern struct time_namespace init_time_ns;
26 extern struct user_namespace init_user_ns;
27 extern struct uts_namespace init_uts_ns;
28 
29 extern const struct proc_ns_operations netns_operations;
30 extern const struct proc_ns_operations utsns_operations;
31 extern const struct proc_ns_operations ipcns_operations;
32 extern const struct proc_ns_operations pidns_operations;
33 extern const struct proc_ns_operations pidns_for_children_operations;
34 extern const struct proc_ns_operations userns_operations;
35 extern const struct proc_ns_operations mntns_operations;
36 extern const struct proc_ns_operations cgroupns_operations;
37 extern const struct proc_ns_operations timens_operations;
38 extern const struct proc_ns_operations timens_for_children_operations;
39 
40 struct ns_common {
41 	u32 ns_type;
42 	struct dentry *stashed;
43 	const struct proc_ns_operations *ops;
44 	unsigned int inum;
45 	refcount_t __ns_ref; /* do not use directly */
46 	union {
47 		struct {
48 			u64 ns_id;
49 			struct rb_node ns_tree_node;
50 			struct list_head ns_list_node;
51 		};
52 		struct rcu_head ns_rcu;
53 	};
54 };
55 
56 int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_operations *ops, int inum);
57 void __ns_common_free(struct ns_common *ns);
58 
59 #define to_ns_common(__ns)                                    \
60 	_Generic((__ns),                                      \
61 		struct cgroup_namespace *:       &(__ns)->ns, \
62 		const struct cgroup_namespace *: &(__ns)->ns, \
63 		struct ipc_namespace *:          &(__ns)->ns, \
64 		const struct ipc_namespace *:    &(__ns)->ns, \
65 		struct mnt_namespace *:          &(__ns)->ns, \
66 		const struct mnt_namespace *:    &(__ns)->ns, \
67 		struct net *:                    &(__ns)->ns, \
68 		const struct net *:              &(__ns)->ns, \
69 		struct pid_namespace *:          &(__ns)->ns, \
70 		const struct pid_namespace *:    &(__ns)->ns, \
71 		struct time_namespace *:         &(__ns)->ns, \
72 		const struct time_namespace *:   &(__ns)->ns, \
73 		struct user_namespace *:         &(__ns)->ns, \
74 		const struct user_namespace *:   &(__ns)->ns, \
75 		struct uts_namespace *:          &(__ns)->ns, \
76 		const struct uts_namespace *:    &(__ns)->ns)
77 
78 #define ns_init_inum(__ns)                                     \
79 	_Generic((__ns),                                       \
80 		struct cgroup_namespace *: CGROUP_NS_INIT_INO, \
81 		struct ipc_namespace *:    IPC_NS_INIT_INO,    \
82 		struct mnt_namespace *:    MNT_NS_INIT_INO,    \
83 		struct net *:              NET_NS_INIT_INO,    \
84 		struct pid_namespace *:    PID_NS_INIT_INO,    \
85 		struct time_namespace *:   TIME_NS_INIT_INO,   \
86 		struct user_namespace *:   USER_NS_INIT_INO,   \
87 		struct uts_namespace *:    UTS_NS_INIT_INO)
88 
89 #define ns_init_ns(__ns)                                    \
90 	_Generic((__ns),                                    \
91 		struct cgroup_namespace *: &init_cgroup_ns, \
92 		struct ipc_namespace *:    &init_ipc_ns,    \
93 		struct mnt_namespace *:    &init_mnt_ns,     \
94 		struct net *:              &init_net,       \
95 		struct pid_namespace *:    &init_pid_ns,    \
96 		struct time_namespace *:   &init_time_ns,   \
97 		struct user_namespace *:   &init_user_ns,   \
98 		struct uts_namespace *:    &init_uts_ns)
99 
100 #define to_ns_operations(__ns)                                                                         \
101 	_Generic((__ns),                                                                               \
102 		struct cgroup_namespace *: (IS_ENABLED(CONFIG_CGROUPS) ? &cgroupns_operations : NULL), \
103 		struct ipc_namespace *:    (IS_ENABLED(CONFIG_IPC_NS)  ? &ipcns_operations    : NULL), \
104 		struct mnt_namespace *:    &mntns_operations,                                          \
105 		struct net *:              (IS_ENABLED(CONFIG_NET_NS)  ? &netns_operations    : NULL), \
106 		struct pid_namespace *:    (IS_ENABLED(CONFIG_PID_NS)  ? &pidns_operations    : NULL), \
107 		struct time_namespace *:   (IS_ENABLED(CONFIG_TIME_NS) ? &timens_operations   : NULL), \
108 		struct user_namespace *:   (IS_ENABLED(CONFIG_USER_NS) ? &userns_operations   : NULL), \
109 		struct uts_namespace *:    (IS_ENABLED(CONFIG_UTS_NS)  ? &utsns_operations    : NULL))
110 
111 #define ns_common_type(__ns)                                \
112 	_Generic((__ns),                                    \
113 		struct cgroup_namespace *: CLONE_NEWCGROUP, \
114 		struct ipc_namespace *:    CLONE_NEWIPC,    \
115 		struct mnt_namespace *:    CLONE_NEWNS,     \
116 		struct net *:              CLONE_NEWNET,    \
117 		struct pid_namespace *:    CLONE_NEWPID,    \
118 		struct time_namespace *:   CLONE_NEWTIME,   \
119 		struct user_namespace *:   CLONE_NEWUSER,   \
120 		struct uts_namespace *:    CLONE_NEWUTS)
121 
122 #define ns_common_init(__ns)                     \
123 	__ns_common_init(to_ns_common(__ns),     \
124 			 ns_common_type(__ns),   \
125 			 to_ns_operations(__ns), \
126 			 (((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0))
127 
128 #define ns_common_init_inum(__ns, __inum)        \
129 	__ns_common_init(to_ns_common(__ns),     \
130 			 ns_common_type(__ns),   \
131 			 to_ns_operations(__ns), \
132 			 __inum)
133 
134 #define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns)))
135 
__ns_ref_put(struct ns_common * ns)136 static __always_inline __must_check bool __ns_ref_put(struct ns_common *ns)
137 {
138 	return refcount_dec_and_test(&ns->__ns_ref);
139 }
140 
__ns_ref_get(struct ns_common * ns)141 static __always_inline __must_check bool __ns_ref_get(struct ns_common *ns)
142 {
143 	return refcount_inc_not_zero(&ns->__ns_ref);
144 }
145 
146 #define ns_ref_read(__ns) refcount_read(&to_ns_common((__ns))->__ns_ref)
147 #define ns_ref_inc(__ns) refcount_inc(&to_ns_common((__ns))->__ns_ref)
148 #define ns_ref_get(__ns) __ns_ref_get(to_ns_common((__ns)))
149 #define ns_ref_put(__ns) __ns_ref_put(to_ns_common((__ns)))
150 #define ns_ref_put_and_lock(__ns, __lock) \
151 	refcount_dec_and_lock(&to_ns_common((__ns))->__ns_ref, (__lock))
152 
153 #endif
154