162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * generic net pointers 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __NET_GENERIC_H__ 762306a36Sopenharmony_ci#define __NET_GENERIC_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/bug.h> 1062306a36Sopenharmony_ci#include <linux/rcupdate.h> 1162306a36Sopenharmony_ci#include <net/net_namespace.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Generic net pointers are to be used by modules to put some private 1562306a36Sopenharmony_ci * stuff on the struct net without explicit struct net modification 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * The rules are simple: 1862306a36Sopenharmony_ci * 1. set pernet_operations->id. After register_pernet_device you 1962306a36Sopenharmony_ci * will have the id of your private pointer. 2062306a36Sopenharmony_ci * 2. set pernet_operations->size to have the code allocate and free 2162306a36Sopenharmony_ci * a private structure pointed to from struct net. 2262306a36Sopenharmony_ci * 3. do not change this pointer while the net is alive; 2362306a36Sopenharmony_ci * 4. do not try to have any private reference on the net_generic object. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * After accomplishing all of the above, the private pointer can be 2662306a36Sopenharmony_ci * accessed with the net_generic() call. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct net_generic { 3062306a36Sopenharmony_ci union { 3162306a36Sopenharmony_ci struct { 3262306a36Sopenharmony_ci unsigned int len; 3362306a36Sopenharmony_ci struct rcu_head rcu; 3462306a36Sopenharmony_ci } s; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci DECLARE_FLEX_ARRAY(void *, ptr); 3762306a36Sopenharmony_ci }; 3862306a36Sopenharmony_ci}; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic inline void *net_generic(const struct net *net, unsigned int id) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct net_generic *ng; 4362306a36Sopenharmony_ci void *ptr; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci rcu_read_lock(); 4662306a36Sopenharmony_ci ng = rcu_dereference(net->gen); 4762306a36Sopenharmony_ci ptr = ng->ptr[id]; 4862306a36Sopenharmony_ci rcu_read_unlock(); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci return ptr; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci#endif 53