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 Dobriyanstatic 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