18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * generic net pointers
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef __NET_GENERIC_H__
78c2ecf20Sopenharmony_ci#define __NET_GENERIC_H__
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/bug.h>
108c2ecf20Sopenharmony_ci#include <linux/rcupdate.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci * Generic net pointers are to be used by modules to put some private
148c2ecf20Sopenharmony_ci * stuff on the struct net without explicit struct net modification
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * The rules are simple:
178c2ecf20Sopenharmony_ci * 1. set pernet_operations->id.  After register_pernet_device you
188c2ecf20Sopenharmony_ci *    will have the id of your private pointer.
198c2ecf20Sopenharmony_ci * 2. set pernet_operations->size to have the code allocate and free
208c2ecf20Sopenharmony_ci *    a private structure pointed to from struct net.
218c2ecf20Sopenharmony_ci * 3. do not change this pointer while the net is alive;
228c2ecf20Sopenharmony_ci * 4. do not try to have any private reference on the net_generic object.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * After accomplishing all of the above, the private pointer can be
258c2ecf20Sopenharmony_ci * accessed with the net_generic() call.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistruct net_generic {
298c2ecf20Sopenharmony_ci	union {
308c2ecf20Sopenharmony_ci		struct {
318c2ecf20Sopenharmony_ci			unsigned int len;
328c2ecf20Sopenharmony_ci			struct rcu_head rcu;
338c2ecf20Sopenharmony_ci		} s;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci		void *ptr[0];
368c2ecf20Sopenharmony_ci	};
378c2ecf20Sopenharmony_ci};
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic inline void *net_generic(const struct net *net, unsigned int id)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	struct net_generic *ng;
428c2ecf20Sopenharmony_ci	void *ptr;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	rcu_read_lock();
458c2ecf20Sopenharmony_ci	ng = rcu_dereference(net->gen);
468c2ecf20Sopenharmony_ci	ptr = ng->ptr[id];
478c2ecf20Sopenharmony_ci	rcu_read_unlock();
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	return ptr;
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci#endif
52