linux/net/core/net_namespace.c

// SPDX-License-Identifier: GPL-2.0-only
#define pr_fmt(fmt)

#include <linux/workqueue.h>
#include <linux/rtnetlink.h>
#include <linux/cache.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/idr.h>
#include <linux/rculist.h>
#include <linux/nsproxy.h>
#include <linux/fs.h>
#include <linux/proc_ns.h>
#include <linux/file.h>
#include <linux/export.h>
#include <linux/user_namespace.h>
#include <linux/net_namespace.h>
#include <linux/sched/task.h>
#include <linux/uidgid.h>
#include <linux/cookie.h>
#include <linux/proc_fs.h>

#include <net/sock.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

/*
 *	Our network namespace constructor/destructor lists
 */

static LIST_HEAD(pernet_list);
static struct list_head *first_device =;

LIST_HEAD();
EXPORT_SYMBOL_GPL();

/* Protects net_namespace_list. Nests iside rtnl_lock() */
DECLARE_RWSEM();
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_KEYS
static struct key_tag init_net_key_domain =;
#endif

struct net init_net;
EXPORT_SYMBOL();

static bool init_net_initialized;
/*
 * pernet_ops_rwsem: protects: pernet_list, net_generic_ids,
 * init_net_initialized and first_device pointer.
 * This is internal net namespace object. Please, don't use it
 * outside.
 */
DECLARE_RWSEM();
EXPORT_SYMBOL_GPL();

#define MIN_PERNET_OPS_ID

#define INITIAL_NET_GEN_PTRS

static unsigned int max_gen_ptrs =;

DEFINE_COOKIE();

static struct net_generic *net_alloc_generic(void)
{}

static int net_assign_generic(struct net *net, unsigned int id, void *data)
{}

static int ops_init(const struct pernet_operations *ops, struct net *net)
{}

static void ops_pre_exit_list(const struct pernet_operations *ops,
			      struct list_head *net_exit_list)
{}

static void ops_exit_list(const struct pernet_operations *ops,
			  struct list_head *net_exit_list)
{}

static void ops_free_list(const struct pernet_operations *ops,
			  struct list_head *net_exit_list)
{}

/* should be called with nsid_lock held */
static int alloc_netid(struct net *net, struct net *peer, int reqid)
{}

/* This function is used by idr_for_each(). If net is equal to peer, the
 * function returns the id so that idr_for_each() stops. Because we cannot
 * returns the id 0 (idr_for_each() will not stop), we return the magic value
 * NET_ID_ZERO (-1) for it.
 */
#define NET_ID_ZERO
static int net_eq_idr(int id, void *net, void *peer)
{}

/* Must be called from RCU-critical section or with nsid_lock held */
static int __peernet2id(const struct net *net, struct net *peer)
{}

static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
			      struct nlmsghdr *nlh, gfp_t gfp);
/* This function returns the id of a peer netns. If no id is assigned, one will
 * be allocated and returned.
 */
int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp)
{}
EXPORT_SYMBOL_GPL();

/* This function returns, if assigned, the id of a peer netns. */
int peernet2id(const struct net *net, struct net *peer)
{}
EXPORT_SYMBOL();

/* This function returns true is the peer netns has an id assigned into the
 * current netns.
 */
bool peernet_has_id(const struct net *net, struct net *peer)
{}

struct net *get_net_ns_by_id(const struct net *net, int id)
{}
EXPORT_SYMBOL_GPL();

/* init code that must occur even if setup_net() is not called. */
static __net_init void preinit_net(struct net *net)
{}

/*
 * setup_net runs the initializers for the network namespace object.
 */
static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
{}

static int __net_init net_defaults_init_net(struct net *net)
{}

static struct pernet_operations net_defaults_ops =;

static __init int net_defaults_init(void)
{}

core_initcall(net_defaults_init);

#ifdef CONFIG_NET_NS
static struct ucounts *inc_net_namespaces(struct user_namespace *ns)
{}

static void dec_net_namespaces(struct ucounts *ucounts)
{}

static struct kmem_cache *net_cachep __ro_after_init;
static struct workqueue_struct *netns_wq;

static struct net *net_alloc(void)
{}

static void net_free(struct net *net)
{}

void net_drop_ns(void *p)
{}

struct net *copy_net_ns(unsigned long flags,
			struct user_namespace *user_ns, struct net *old_net)
{}

/**
 * net_ns_get_ownership - get sysfs ownership data for @net
 * @net: network namespace in question (can be NULL)
 * @uid: kernel user ID for sysfs objects
 * @gid: kernel group ID for sysfs objects
 *
 * Returns the uid/gid pair of root in the user namespace associated with the
 * given network namespace.
 */
void net_ns_get_ownership(const struct net *net, kuid_t *uid, kgid_t *gid)
{}
EXPORT_SYMBOL_GPL();

static void unhash_nsid(struct net *net, struct net *last)
{}

static LLIST_HEAD(cleanup_list);

static void cleanup_net(struct work_struct *work)
{}

/**
 * net_ns_barrier - wait until concurrent net_cleanup_work is done
 *
 * cleanup_net runs from work queue and will first remove namespaces
 * from the global list, then run net exit functions.
 *
 * Call this in module exit path to make sure that all netns
 * ->exit ops have been invoked before the function is removed.
 */
void net_ns_barrier(void)
{}
EXPORT_SYMBOL();

static DECLARE_WORK(net_cleanup_work, cleanup_net);

void __put_net(struct net *net)
{}
EXPORT_SYMBOL_GPL();

/**
 * get_net_ns - increment the refcount of the network namespace
 * @ns: common namespace (net)
 *
 * Returns the net's common namespace or ERR_PTR() if ref is zero.
 */
struct ns_common *get_net_ns(struct ns_common *ns)
{}
EXPORT_SYMBOL_GPL();

struct net *get_net_ns_by_fd(int fd)
{}
EXPORT_SYMBOL_GPL();
#endif

struct net *get_net_ns_by_pid(pid_t pid)
{}
EXPORT_SYMBOL_GPL();

static __net_init int net_ns_net_init(struct net *net)
{}

static __net_exit void net_ns_net_exit(struct net *net)
{}

static struct pernet_operations __net_initdata net_ns_ops =;

static const struct nla_policy rtnl_net_policy[NETNSA_MAX + 1] =;

static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
			  struct netlink_ext_ack *extack)
{}

static int rtnl_net_get_size(void)
{}

struct net_fill_args {};

static int rtnl_net_fill(struct sk_buff *skb, struct net_fill_args *args)
{}

static int rtnl_net_valid_getid_req(struct sk_buff *skb,
				    const struct nlmsghdr *nlh,
				    struct nlattr **tb,
				    struct netlink_ext_ack *extack)
{}

static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
			  struct netlink_ext_ack *extack)
{}

struct rtnl_net_dump_cb {};

/* Runs in RCU-critical section. */
static int rtnl_net_dumpid_one(int id, void *peer, void *data)
{}

static int rtnl_valid_dump_net_req(const struct nlmsghdr *nlh, struct sock *sk,
				   struct rtnl_net_dump_cb *net_cb,
				   struct netlink_callback *cb)
{}

static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb)
{}

static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
			      struct nlmsghdr *nlh, gfp_t gfp)
{}

#ifdef CONFIG_NET_NS
static void __init netns_ipv4_struct_check(void)
{}
#endif

void __init net_ns_init(void)
{}

static void free_exit_list(struct pernet_operations *ops, struct list_head *net_exit_list)
{}

#ifdef CONFIG_NET_NS
static int __register_pernet_operations(struct list_head *list,
					struct pernet_operations *ops)
{}

static void __unregister_pernet_operations(struct pernet_operations *ops)
{}

#else

static int __register_pernet_operations(struct list_head *list,
					struct pernet_operations *ops)
{
	if (!init_net_initialized) {
		list_add_tail(&ops->list, list);
		return 0;
	}

	return ops_init(ops, &init_net);
}

static void __unregister_pernet_operations(struct pernet_operations *ops)
{
	if (!init_net_initialized) {
		list_del(&ops->list);
	} else {
		LIST_HEAD(net_exit_list);
		list_add(&init_net.exit_list, &net_exit_list);
		free_exit_list(ops, &net_exit_list);
	}
}

#endif /* CONFIG_NET_NS */

static DEFINE_IDA(net_generic_ids);

static int register_pernet_operations(struct list_head *list,
				      struct pernet_operations *ops)
{}

static void unregister_pernet_operations(struct pernet_operations *ops)
{}

/**
 *      register_pernet_subsys - register a network namespace subsystem
 *	@ops:  pernet operations structure for the subsystem
 *
 *	Register a subsystem which has init and exit functions
 *	that are called when network namespaces are created and
 *	destroyed respectively.
 *
 *	When registered all network namespace init functions are
 *	called for every existing network namespace.  Allowing kernel
 *	modules to have a race free view of the set of network namespaces.
 *
 *	When a new network namespace is created all of the init
 *	methods are called in the order in which they were registered.
 *
 *	When a network namespace is destroyed all of the exit methods
 *	are called in the reverse of the order with which they were
 *	registered.
 */
int register_pernet_subsys(struct pernet_operations *ops)
{}
EXPORT_SYMBOL_GPL();

/**
 *      unregister_pernet_subsys - unregister a network namespace subsystem
 *	@ops: pernet operations structure to manipulate
 *
 *	Remove the pernet operations structure from the list to be
 *	used when network namespaces are created or destroyed.  In
 *	addition run the exit method for all existing network
 *	namespaces.
 */
void unregister_pernet_subsys(struct pernet_operations *ops)
{}
EXPORT_SYMBOL_GPL();

/**
 *      register_pernet_device - register a network namespace device
 *	@ops:  pernet operations structure for the subsystem
 *
 *	Register a device which has init and exit functions
 *	that are called when network namespaces are created and
 *	destroyed respectively.
 *
 *	When registered all network namespace init functions are
 *	called for every existing network namespace.  Allowing kernel
 *	modules to have a race free view of the set of network namespaces.
 *
 *	When a new network namespace is created all of the init
 *	methods are called in the order in which they were registered.
 *
 *	When a network namespace is destroyed all of the exit methods
 *	are called in the reverse of the order with which they were
 *	registered.
 */
int register_pernet_device(struct pernet_operations *ops)
{}
EXPORT_SYMBOL_GPL();

/**
 *      unregister_pernet_device - unregister a network namespace netdevice
 *	@ops: pernet operations structure to manipulate
 *
 *	Remove the pernet operations structure from the list to be
 *	used when network namespaces are created or destroyed.  In
 *	addition run the exit method for all existing network
 *	namespaces.
 */
void unregister_pernet_device(struct pernet_operations *ops)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_NET_NS
static struct ns_common *netns_get(struct task_struct *task)
{}

static inline struct net *to_net_ns(struct ns_common *ns)
{}

static void netns_put(struct ns_common *ns)
{}

static int netns_install(struct nsset *nsset, struct ns_common *ns)
{}

static struct user_namespace *netns_owner(struct ns_common *ns)
{}

const struct proc_ns_operations netns_operations =;
#endif