162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Operations on the network namespace 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef __NET_NET_NAMESPACE_H 662306a36Sopenharmony_ci#define __NET_NET_NAMESPACE_H 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/atomic.h> 962306a36Sopenharmony_ci#include <linux/refcount.h> 1062306a36Sopenharmony_ci#include <linux/workqueue.h> 1162306a36Sopenharmony_ci#include <linux/list.h> 1262306a36Sopenharmony_ci#include <linux/sysctl.h> 1362306a36Sopenharmony_ci#include <linux/uidgid.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <net/flow.h> 1662306a36Sopenharmony_ci#include <net/netns/core.h> 1762306a36Sopenharmony_ci#include <net/netns/mib.h> 1862306a36Sopenharmony_ci#include <net/netns/unix.h> 1962306a36Sopenharmony_ci#include <net/netns/packet.h> 2062306a36Sopenharmony_ci#include <net/netns/ipv4.h> 2162306a36Sopenharmony_ci#include <net/netns/ipv6.h> 2262306a36Sopenharmony_ci#include <net/netns/nexthop.h> 2362306a36Sopenharmony_ci#include <net/netns/ieee802154_6lowpan.h> 2462306a36Sopenharmony_ci#include <net/netns/sctp.h> 2562306a36Sopenharmony_ci#include <net/netns/netfilter.h> 2662306a36Sopenharmony_ci#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 2762306a36Sopenharmony_ci#include <net/netns/conntrack.h> 2862306a36Sopenharmony_ci#endif 2962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 3062306a36Sopenharmony_ci#include <net/netns/flow_table.h> 3162306a36Sopenharmony_ci#endif 3262306a36Sopenharmony_ci#include <net/netns/nftables.h> 3362306a36Sopenharmony_ci#include <net/netns/xfrm.h> 3462306a36Sopenharmony_ci#include <net/netns/mpls.h> 3562306a36Sopenharmony_ci#include <net/netns/can.h> 3662306a36Sopenharmony_ci#include <net/netns/xdp.h> 3762306a36Sopenharmony_ci#include <net/netns/smc.h> 3862306a36Sopenharmony_ci#include <net/netns/bpf.h> 3962306a36Sopenharmony_ci#include <net/netns/mctp.h> 4062306a36Sopenharmony_ci#include <net/net_trackers.h> 4162306a36Sopenharmony_ci#include <linux/ns_common.h> 4262306a36Sopenharmony_ci#include <linux/idr.h> 4362306a36Sopenharmony_ci#include <linux/skbuff.h> 4462306a36Sopenharmony_ci#include <linux/notifier.h> 4562306a36Sopenharmony_ci#include <linux/xarray.h> 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistruct user_namespace; 4862306a36Sopenharmony_cistruct proc_dir_entry; 4962306a36Sopenharmony_cistruct net_device; 5062306a36Sopenharmony_cistruct sock; 5162306a36Sopenharmony_cistruct ctl_table_header; 5262306a36Sopenharmony_cistruct net_generic; 5362306a36Sopenharmony_cistruct uevent_sock; 5462306a36Sopenharmony_cistruct netns_ipvs; 5562306a36Sopenharmony_cistruct bpf_prog; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define NETDEV_HASHBITS 8 5962306a36Sopenharmony_ci#define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistruct net { 6262306a36Sopenharmony_ci /* First cache line can be often dirtied. 6362306a36Sopenharmony_ci * Do not place here read-mostly fields. 6462306a36Sopenharmony_ci */ 6562306a36Sopenharmony_ci refcount_t passive; /* To decide when the network 6662306a36Sopenharmony_ci * namespace should be freed. 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_ci spinlock_t rules_mod_lock; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci atomic_t dev_unreg_count; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci unsigned int dev_base_seq; /* protected by rtnl_mutex */ 7362306a36Sopenharmony_ci u32 ifindex; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci spinlock_t nsid_lock; 7662306a36Sopenharmony_ci atomic_t fnhe_genid; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci struct list_head list; /* list of network namespaces */ 7962306a36Sopenharmony_ci struct list_head exit_list; /* To linked to call pernet exit 8062306a36Sopenharmony_ci * methods on dead net ( 8162306a36Sopenharmony_ci * pernet_ops_rwsem read locked), 8262306a36Sopenharmony_ci * or to unregister pernet ops 8362306a36Sopenharmony_ci * (pernet_ops_rwsem write locked). 8462306a36Sopenharmony_ci */ 8562306a36Sopenharmony_ci struct llist_node cleanup_list; /* namespaces on death row */ 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#ifdef CONFIG_KEYS 8862306a36Sopenharmony_ci struct key_tag *key_domain; /* Key domain of operation tag */ 8962306a36Sopenharmony_ci#endif 9062306a36Sopenharmony_ci struct user_namespace *user_ns; /* Owning user namespace */ 9162306a36Sopenharmony_ci struct ucounts *ucounts; 9262306a36Sopenharmony_ci struct idr netns_ids; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci struct ns_common ns; 9562306a36Sopenharmony_ci struct ref_tracker_dir refcnt_tracker; 9662306a36Sopenharmony_ci struct ref_tracker_dir notrefcnt_tracker; /* tracker for objects not 9762306a36Sopenharmony_ci * refcounted against netns 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ci struct list_head dev_base_head; 10062306a36Sopenharmony_ci struct proc_dir_entry *proc_net; 10162306a36Sopenharmony_ci struct proc_dir_entry *proc_net_stat; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 10462306a36Sopenharmony_ci struct ctl_table_set sysctls; 10562306a36Sopenharmony_ci#endif 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci struct sock *rtnl; /* rtnetlink socket */ 10862306a36Sopenharmony_ci struct sock *genl_sock; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci struct uevent_sock *uevent_sock; /* uevent socket */ 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci struct hlist_head *dev_name_head; 11362306a36Sopenharmony_ci struct hlist_head *dev_index_head; 11462306a36Sopenharmony_ci struct xarray dev_by_index; 11562306a36Sopenharmony_ci struct raw_notifier_head netdev_chain; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci /* Note that @hash_mix can be read millions times per second, 11862306a36Sopenharmony_ci * it is critical that it is on a read_mostly cache line. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci u32 hash_mix; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci struct net_device *loopback_dev; /* The loopback */ 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci /* core fib_rules */ 12562306a36Sopenharmony_ci struct list_head rules_ops; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci struct netns_core core; 12862306a36Sopenharmony_ci struct netns_mib mib; 12962306a36Sopenharmony_ci struct netns_packet packet; 13062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_UNIX) 13162306a36Sopenharmony_ci struct netns_unix unx; 13262306a36Sopenharmony_ci#endif 13362306a36Sopenharmony_ci struct netns_nexthop nexthop; 13462306a36Sopenharmony_ci struct netns_ipv4 ipv4; 13562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 13662306a36Sopenharmony_ci struct netns_ipv6 ipv6; 13762306a36Sopenharmony_ci#endif 13862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) 13962306a36Sopenharmony_ci struct netns_ieee802154_lowpan ieee802154_lowpan; 14062306a36Sopenharmony_ci#endif 14162306a36Sopenharmony_ci#if defined(CONFIG_IP_SCTP) || defined(CONFIG_IP_SCTP_MODULE) 14262306a36Sopenharmony_ci struct netns_sctp sctp; 14362306a36Sopenharmony_ci#endif 14462306a36Sopenharmony_ci#ifdef CONFIG_NETFILTER 14562306a36Sopenharmony_ci struct netns_nf nf; 14662306a36Sopenharmony_ci#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 14762306a36Sopenharmony_ci struct netns_ct ct; 14862306a36Sopenharmony_ci#endif 14962306a36Sopenharmony_ci#if defined(CONFIG_NF_TABLES) || defined(CONFIG_NF_TABLES_MODULE) 15062306a36Sopenharmony_ci struct netns_nftables nft; 15162306a36Sopenharmony_ci#endif 15262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) 15362306a36Sopenharmony_ci struct netns_ft ft; 15462306a36Sopenharmony_ci#endif 15562306a36Sopenharmony_ci#endif 15662306a36Sopenharmony_ci#ifdef CONFIG_WEXT_CORE 15762306a36Sopenharmony_ci struct sk_buff_head wext_nlevents; 15862306a36Sopenharmony_ci#endif 15962306a36Sopenharmony_ci struct net_generic __rcu *gen; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci /* Used to store attached BPF programs */ 16262306a36Sopenharmony_ci struct netns_bpf bpf; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci /* Note : following structs are cache line aligned */ 16562306a36Sopenharmony_ci#ifdef CONFIG_XFRM 16662306a36Sopenharmony_ci struct netns_xfrm xfrm; 16762306a36Sopenharmony_ci#endif 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci u64 net_cookie; /* written once */ 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IP_VS) 17262306a36Sopenharmony_ci struct netns_ipvs *ipvs; 17362306a36Sopenharmony_ci#endif 17462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MPLS) 17562306a36Sopenharmony_ci struct netns_mpls mpls; 17662306a36Sopenharmony_ci#endif 17762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CAN) 17862306a36Sopenharmony_ci struct netns_can can; 17962306a36Sopenharmony_ci#endif 18062306a36Sopenharmony_ci#ifdef CONFIG_XDP_SOCKETS 18162306a36Sopenharmony_ci struct netns_xdp xdp; 18262306a36Sopenharmony_ci#endif 18362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MCTP) 18462306a36Sopenharmony_ci struct netns_mctp mctp; 18562306a36Sopenharmony_ci#endif 18662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CRYPTO_USER) 18762306a36Sopenharmony_ci struct sock *crypto_nlsk; 18862306a36Sopenharmony_ci#endif 18962306a36Sopenharmony_ci struct sock *diag_nlsk; 19062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_SMC) 19162306a36Sopenharmony_ci struct netns_smc smc; 19262306a36Sopenharmony_ci#endif 19362306a36Sopenharmony_ci} __randomize_layout; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci#include <linux/seq_file_net.h> 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/* Init's network namespace */ 19862306a36Sopenharmony_ciextern struct net init_net; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci#ifdef CONFIG_NET_NS 20162306a36Sopenharmony_cistruct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns, 20262306a36Sopenharmony_ci struct net *old_net); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_civoid net_ns_get_ownership(const struct net *net, kuid_t *uid, kgid_t *gid); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_civoid net_ns_barrier(void); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistruct ns_common *get_net_ns(struct ns_common *ns); 20962306a36Sopenharmony_cistruct net *get_net_ns_by_fd(int fd); 21062306a36Sopenharmony_ci#else /* CONFIG_NET_NS */ 21162306a36Sopenharmony_ci#include <linux/sched.h> 21262306a36Sopenharmony_ci#include <linux/nsproxy.h> 21362306a36Sopenharmony_cistatic inline struct net *copy_net_ns(unsigned long flags, 21462306a36Sopenharmony_ci struct user_namespace *user_ns, struct net *old_net) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci if (flags & CLONE_NEWNET) 21762306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 21862306a36Sopenharmony_ci return old_net; 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistatic inline void net_ns_get_ownership(const struct net *net, 22262306a36Sopenharmony_ci kuid_t *uid, kgid_t *gid) 22362306a36Sopenharmony_ci{ 22462306a36Sopenharmony_ci *uid = GLOBAL_ROOT_UID; 22562306a36Sopenharmony_ci *gid = GLOBAL_ROOT_GID; 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic inline void net_ns_barrier(void) {} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_cistatic inline struct ns_common *get_net_ns(struct ns_common *ns) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic inline struct net *get_net_ns_by_fd(int fd) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci#endif /* CONFIG_NET_NS */ 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ciextern struct list_head net_namespace_list; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistruct net *get_net_ns_by_pid(pid_t pid); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 24762306a36Sopenharmony_civoid ipx_register_sysctl(void); 24862306a36Sopenharmony_civoid ipx_unregister_sysctl(void); 24962306a36Sopenharmony_ci#else 25062306a36Sopenharmony_ci#define ipx_register_sysctl() 25162306a36Sopenharmony_ci#define ipx_unregister_sysctl() 25262306a36Sopenharmony_ci#endif 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci#ifdef CONFIG_NET_NS 25562306a36Sopenharmony_civoid __put_net(struct net *net); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/* Try using get_net_track() instead */ 25862306a36Sopenharmony_cistatic inline struct net *get_net(struct net *net) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci refcount_inc(&net->ns.count); 26162306a36Sopenharmony_ci return net; 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistatic inline struct net *maybe_get_net(struct net *net) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci /* Used when we know struct net exists but we 26762306a36Sopenharmony_ci * aren't guaranteed a previous reference count 26862306a36Sopenharmony_ci * exists. If the reference count is zero this 26962306a36Sopenharmony_ci * function fails and returns NULL. 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_ci if (!refcount_inc_not_zero(&net->ns.count)) 27262306a36Sopenharmony_ci net = NULL; 27362306a36Sopenharmony_ci return net; 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci/* Try using put_net_track() instead */ 27762306a36Sopenharmony_cistatic inline void put_net(struct net *net) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci if (refcount_dec_and_test(&net->ns.count)) 28062306a36Sopenharmony_ci __put_net(net); 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_cistatic inline 28462306a36Sopenharmony_ciint net_eq(const struct net *net1, const struct net *net2) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci return net1 == net2; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic inline int check_net(const struct net *net) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci return refcount_read(&net->ns.count) != 0; 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_civoid net_drop_ns(void *); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci#else 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_cistatic inline struct net *get_net(struct net *net) 29962306a36Sopenharmony_ci{ 30062306a36Sopenharmony_ci return net; 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic inline void put_net(struct net *net) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic inline struct net *maybe_get_net(struct net *net) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci return net; 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_cistatic inline 31362306a36Sopenharmony_ciint net_eq(const struct net *net1, const struct net *net2) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci return 1; 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistatic inline int check_net(const struct net *net) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci return 1; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci#define net_drop_ns NULL 32462306a36Sopenharmony_ci#endif 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic inline void __netns_tracker_alloc(struct net *net, 32862306a36Sopenharmony_ci netns_tracker *tracker, 32962306a36Sopenharmony_ci bool refcounted, 33062306a36Sopenharmony_ci gfp_t gfp) 33162306a36Sopenharmony_ci{ 33262306a36Sopenharmony_ci#ifdef CONFIG_NET_NS_REFCNT_TRACKER 33362306a36Sopenharmony_ci ref_tracker_alloc(refcounted ? &net->refcnt_tracker : 33462306a36Sopenharmony_ci &net->notrefcnt_tracker, 33562306a36Sopenharmony_ci tracker, gfp); 33662306a36Sopenharmony_ci#endif 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistatic inline void netns_tracker_alloc(struct net *net, netns_tracker *tracker, 34062306a36Sopenharmony_ci gfp_t gfp) 34162306a36Sopenharmony_ci{ 34262306a36Sopenharmony_ci __netns_tracker_alloc(net, tracker, true, gfp); 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic inline void __netns_tracker_free(struct net *net, 34662306a36Sopenharmony_ci netns_tracker *tracker, 34762306a36Sopenharmony_ci bool refcounted) 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci#ifdef CONFIG_NET_NS_REFCNT_TRACKER 35062306a36Sopenharmony_ci ref_tracker_free(refcounted ? &net->refcnt_tracker : 35162306a36Sopenharmony_ci &net->notrefcnt_tracker, tracker); 35262306a36Sopenharmony_ci#endif 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cistatic inline struct net *get_net_track(struct net *net, 35662306a36Sopenharmony_ci netns_tracker *tracker, gfp_t gfp) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci get_net(net); 35962306a36Sopenharmony_ci netns_tracker_alloc(net, tracker, gfp); 36062306a36Sopenharmony_ci return net; 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_cistatic inline void put_net_track(struct net *net, netns_tracker *tracker) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci __netns_tracker_free(net, tracker, true); 36662306a36Sopenharmony_ci put_net(net); 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_citypedef struct { 37062306a36Sopenharmony_ci#ifdef CONFIG_NET_NS 37162306a36Sopenharmony_ci struct net *net; 37262306a36Sopenharmony_ci#endif 37362306a36Sopenharmony_ci} possible_net_t; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic inline void write_pnet(possible_net_t *pnet, struct net *net) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci#ifdef CONFIG_NET_NS 37862306a36Sopenharmony_ci pnet->net = net; 37962306a36Sopenharmony_ci#endif 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_cistatic inline struct net *read_pnet(const possible_net_t *pnet) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci#ifdef CONFIG_NET_NS 38562306a36Sopenharmony_ci return pnet->net; 38662306a36Sopenharmony_ci#else 38762306a36Sopenharmony_ci return &init_net; 38862306a36Sopenharmony_ci#endif 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci/* Protected by net_rwsem */ 39262306a36Sopenharmony_ci#define for_each_net(VAR) \ 39362306a36Sopenharmony_ci list_for_each_entry(VAR, &net_namespace_list, list) 39462306a36Sopenharmony_ci#define for_each_net_continue_reverse(VAR) \ 39562306a36Sopenharmony_ci list_for_each_entry_continue_reverse(VAR, &net_namespace_list, list) 39662306a36Sopenharmony_ci#define for_each_net_rcu(VAR) \ 39762306a36Sopenharmony_ci list_for_each_entry_rcu(VAR, &net_namespace_list, list) 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci#ifdef CONFIG_NET_NS 40062306a36Sopenharmony_ci#define __net_init 40162306a36Sopenharmony_ci#define __net_exit 40262306a36Sopenharmony_ci#define __net_initdata 40362306a36Sopenharmony_ci#define __net_initconst 40462306a36Sopenharmony_ci#else 40562306a36Sopenharmony_ci#define __net_init __init 40662306a36Sopenharmony_ci#define __net_exit __ref 40762306a36Sopenharmony_ci#define __net_initdata __initdata 40862306a36Sopenharmony_ci#define __net_initconst __initconst 40962306a36Sopenharmony_ci#endif 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ciint peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp); 41262306a36Sopenharmony_ciint peernet2id(const struct net *net, struct net *peer); 41362306a36Sopenharmony_cibool peernet_has_id(const struct net *net, struct net *peer); 41462306a36Sopenharmony_cistruct net *get_net_ns_by_id(const struct net *net, int id); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_cistruct pernet_operations { 41762306a36Sopenharmony_ci struct list_head list; 41862306a36Sopenharmony_ci /* 41962306a36Sopenharmony_ci * Below methods are called without any exclusive locks. 42062306a36Sopenharmony_ci * More than one net may be constructed and destructed 42162306a36Sopenharmony_ci * in parallel on several cpus. Every pernet_operations 42262306a36Sopenharmony_ci * have to keep in mind all other pernet_operations and 42362306a36Sopenharmony_ci * to introduce a locking, if they share common resources. 42462306a36Sopenharmony_ci * 42562306a36Sopenharmony_ci * The only time they are called with exclusive lock is 42662306a36Sopenharmony_ci * from register_pernet_subsys(), unregister_pernet_subsys() 42762306a36Sopenharmony_ci * register_pernet_device() and unregister_pernet_device(). 42862306a36Sopenharmony_ci * 42962306a36Sopenharmony_ci * Exit methods using blocking RCU primitives, such as 43062306a36Sopenharmony_ci * synchronize_rcu(), should be implemented via exit_batch. 43162306a36Sopenharmony_ci * Then, destruction of a group of net requires single 43262306a36Sopenharmony_ci * synchronize_rcu() related to these pernet_operations, 43362306a36Sopenharmony_ci * instead of separate synchronize_rcu() for every net. 43462306a36Sopenharmony_ci * Please, avoid synchronize_rcu() at all, where it's possible. 43562306a36Sopenharmony_ci * 43662306a36Sopenharmony_ci * Note that a combination of pre_exit() and exit() can 43762306a36Sopenharmony_ci * be used, since a synchronize_rcu() is guaranteed between 43862306a36Sopenharmony_ci * the calls. 43962306a36Sopenharmony_ci */ 44062306a36Sopenharmony_ci int (*init)(struct net *net); 44162306a36Sopenharmony_ci void (*pre_exit)(struct net *net); 44262306a36Sopenharmony_ci void (*exit)(struct net *net); 44362306a36Sopenharmony_ci void (*exit_batch)(struct list_head *net_exit_list); 44462306a36Sopenharmony_ci unsigned int *id; 44562306a36Sopenharmony_ci size_t size; 44662306a36Sopenharmony_ci}; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci/* 44962306a36Sopenharmony_ci * Use these carefully. If you implement a network device and it 45062306a36Sopenharmony_ci * needs per network namespace operations use device pernet operations, 45162306a36Sopenharmony_ci * otherwise use pernet subsys operations. 45262306a36Sopenharmony_ci * 45362306a36Sopenharmony_ci * Network interfaces need to be removed from a dying netns _before_ 45462306a36Sopenharmony_ci * subsys notifiers can be called, as most of the network code cleanup 45562306a36Sopenharmony_ci * (which is done from subsys notifiers) runs with the assumption that 45662306a36Sopenharmony_ci * dev_remove_pack has been called so no new packets will arrive during 45762306a36Sopenharmony_ci * and after the cleanup functions have been called. dev_remove_pack 45862306a36Sopenharmony_ci * is not per namespace so instead the guarantee of no more packets 45962306a36Sopenharmony_ci * arriving in a network namespace is provided by ensuring that all 46062306a36Sopenharmony_ci * network devices and all sockets have left the network namespace 46162306a36Sopenharmony_ci * before the cleanup methods are called. 46262306a36Sopenharmony_ci * 46362306a36Sopenharmony_ci * For the longest time the ipv4 icmp code was registered as a pernet 46462306a36Sopenharmony_ci * device which caused kernel oops, and panics during network 46562306a36Sopenharmony_ci * namespace cleanup. So please don't get this wrong. 46662306a36Sopenharmony_ci */ 46762306a36Sopenharmony_ciint register_pernet_subsys(struct pernet_operations *); 46862306a36Sopenharmony_civoid unregister_pernet_subsys(struct pernet_operations *); 46962306a36Sopenharmony_ciint register_pernet_device(struct pernet_operations *); 47062306a36Sopenharmony_civoid unregister_pernet_device(struct pernet_operations *); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_cistruct ctl_table; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci#define register_net_sysctl(net, path, table) \ 47562306a36Sopenharmony_ci register_net_sysctl_sz(net, path, table, ARRAY_SIZE(table)) 47662306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL 47762306a36Sopenharmony_ciint net_sysctl_init(void); 47862306a36Sopenharmony_cistruct ctl_table_header *register_net_sysctl_sz(struct net *net, const char *path, 47962306a36Sopenharmony_ci struct ctl_table *table, size_t table_size); 48062306a36Sopenharmony_civoid unregister_net_sysctl_table(struct ctl_table_header *header); 48162306a36Sopenharmony_ci#else 48262306a36Sopenharmony_cistatic inline int net_sysctl_init(void) { return 0; } 48362306a36Sopenharmony_cistatic inline struct ctl_table_header *register_net_sysctl_sz(struct net *net, 48462306a36Sopenharmony_ci const char *path, struct ctl_table *table, size_t table_size) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci return NULL; 48762306a36Sopenharmony_ci} 48862306a36Sopenharmony_cistatic inline void unregister_net_sysctl_table(struct ctl_table_header *header) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci} 49162306a36Sopenharmony_ci#endif 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_cistatic inline int rt_genid_ipv4(const struct net *net) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci return atomic_read(&net->ipv4.rt_genid); 49662306a36Sopenharmony_ci} 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6) 49962306a36Sopenharmony_cistatic inline int rt_genid_ipv6(const struct net *net) 50062306a36Sopenharmony_ci{ 50162306a36Sopenharmony_ci return atomic_read(&net->ipv6.fib6_sernum); 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci#endif 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_cistatic inline void rt_genid_bump_ipv4(struct net *net) 50662306a36Sopenharmony_ci{ 50762306a36Sopenharmony_ci atomic_inc(&net->ipv4.rt_genid); 50862306a36Sopenharmony_ci} 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ciextern void (*__fib6_flush_trees)(struct net *net); 51162306a36Sopenharmony_cistatic inline void rt_genid_bump_ipv6(struct net *net) 51262306a36Sopenharmony_ci{ 51362306a36Sopenharmony_ci if (__fib6_flush_trees) 51462306a36Sopenharmony_ci __fib6_flush_trees(net); 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) 51862306a36Sopenharmony_cistatic inline struct netns_ieee802154_lowpan * 51962306a36Sopenharmony_cinet_ieee802154_lowpan(struct net *net) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci return &net->ieee802154_lowpan; 52262306a36Sopenharmony_ci} 52362306a36Sopenharmony_ci#endif 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci/* For callers who don't really care about whether it's IPv4 or IPv6 */ 52662306a36Sopenharmony_cistatic inline void rt_genid_bump_all(struct net *net) 52762306a36Sopenharmony_ci{ 52862306a36Sopenharmony_ci rt_genid_bump_ipv4(net); 52962306a36Sopenharmony_ci rt_genid_bump_ipv6(net); 53062306a36Sopenharmony_ci} 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_cistatic inline int fnhe_genid(const struct net *net) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci return atomic_read(&net->fnhe_genid); 53562306a36Sopenharmony_ci} 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_cistatic inline void fnhe_genid_bump(struct net *net) 53862306a36Sopenharmony_ci{ 53962306a36Sopenharmony_ci atomic_inc(&net->fnhe_genid); 54062306a36Sopenharmony_ci} 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci#ifdef CONFIG_NET 54362306a36Sopenharmony_civoid net_ns_init(void); 54462306a36Sopenharmony_ci#else 54562306a36Sopenharmony_cistatic inline void net_ns_init(void) {} 54662306a36Sopenharmony_ci#endif 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci#endif /* __NET_NET_NAMESPACE_H */ 549