xref: /openbmc/linux/include/net/netns/generic.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2dec827d1SPavel Emelyanov /*
3dec827d1SPavel Emelyanov  * generic net pointers
4dec827d1SPavel Emelyanov  */
5dec827d1SPavel Emelyanov 
6dec827d1SPavel Emelyanov #ifndef __NET_GENERIC_H__
7dec827d1SPavel Emelyanov #define __NET_GENERIC_H__
8dec827d1SPavel Emelyanov 
9187f1882SPaul Gortmaker #include <linux/bug.h>
10dec827d1SPavel Emelyanov #include <linux/rcupdate.h>
11949d6b40SJakub Kicinski #include <net/net_namespace.h>
12dec827d1SPavel Emelyanov 
13dec827d1SPavel Emelyanov /*
14dec827d1SPavel Emelyanov  * Generic net pointers are to be used by modules to put some private
15dec827d1SPavel Emelyanov  * stuff on the struct net without explicit struct net modification
16dec827d1SPavel Emelyanov  *
17dec827d1SPavel Emelyanov  * The rules are simple:
1865c0cfafSEric W. Biederman  * 1. set pernet_operations->id.  After register_pernet_device you
1965c0cfafSEric W. Biederman  *    will have the id of your private pointer.
2005fceb4aSJiri Pirko  * 2. set pernet_operations->size to have the code allocate and free
2105fceb4aSJiri Pirko  *    a private structure pointed to from struct net.
22dec827d1SPavel Emelyanov  * 3. do not change this pointer while the net is alive;
23dec827d1SPavel Emelyanov  * 4. do not try to have any private reference on the net_generic object.
24dec827d1SPavel Emelyanov  *
25dec827d1SPavel Emelyanov  * After accomplishing all of the above, the private pointer can be
26dec827d1SPavel Emelyanov  * accessed with the net_generic() call.
27dec827d1SPavel Emelyanov  */
28dec827d1SPavel Emelyanov 
29dec827d1SPavel Emelyanov struct net_generic {
306af2d5ffSAlexey Dobriyan 	union {
319bfc7b99SAlexey Dobriyan 		struct {
32dec827d1SPavel Emelyanov 			unsigned int len;
33dec827d1SPavel Emelyanov 			struct rcu_head rcu;
349bfc7b99SAlexey Dobriyan 		} s;
35dec827d1SPavel Emelyanov 
36*63a8bf85SGustavo A. R. Silva 		DECLARE_FLEX_ARRAY(void *, ptr);
37dec827d1SPavel Emelyanov 	};
386af2d5ffSAlexey Dobriyan };
39dec827d1SPavel Emelyanov 
net_generic(const struct net * net,unsigned int id)40c7d03a00SAlexey Dobriyan static inline void *net_generic(const struct net *net, unsigned int id)
41dec827d1SPavel Emelyanov {
42dec827d1SPavel Emelyanov 	struct net_generic *ng;
43dec827d1SPavel Emelyanov 	void *ptr;
44dec827d1SPavel Emelyanov 
45dec827d1SPavel Emelyanov 	rcu_read_lock();
46dec827d1SPavel Emelyanov 	ng = rcu_dereference(net->gen);
476af2d5ffSAlexey Dobriyan 	ptr = ng->ptr[id];
48dec827d1SPavel Emelyanov 	rcu_read_unlock();
49dec827d1SPavel Emelyanov 
50dec827d1SPavel Emelyanov 	return ptr;
51dec827d1SPavel Emelyanov }
52dec827d1SPavel Emelyanov #endif
53