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