1 概述
在linux协议栈中引入网络命名空间,是为了支持网络协议栈的多个实例,而这些协议栈的隔离就是通过命名空间来实现的,一个net namespace为进程提供一个完全独立的网络协议栈的视图,包括网络设备接口、ipv4和ipv6协议栈、ip路由表、防火墙规则、sockets等。一个net namespace提供了一份独立的网络环境,就跟独立的系统一样。一个物理设备只能存在于一个net namespace中,但可以从一个net namespace移动到另一个net namespace。网络系统在初始化的时候会初始化一个初始网络命名空间,即init_net命名空间。后续创建的net namespace命名空间会和init_net一起通过list项组织起来,且每个网络设备都对应一个命名空间,同一命名空间下的网络设备通过dev_base_head组织在一起(如图1所示)。当一个netnamespace被销毁时,物理设备会被自动移回到init net namespace。
2 重要数据结构
2.1 struct net
struct net {
atomic_t passive; /* To decided when the network
* namespace should be freed.
*/
atomic_t count; /*To decided when the network
* namespace should be shut down.
*/
#ifdef NETNS_REFCNT_DEBUG
atomic_t use_count; /* To track references we
* destroy on demand
*/
#endif
spinlock_t rules_mod_lock;
//网络命名空间是扁平结构,采用链表连接
structlist_head list; /* list of network namespaces */
//链入全局cleanup_list链表,用于表示要释放的net
structlist_head cleanup_list; /* namespaces on death row */
//连接到exit_list链表的都会被执行pernet_operations的exit函数
structlist_head exit_list; /* Use only net_mutex */
structproc_dir_entry *proc_net; //对应/proc/net
structproc_dir_entry *proc_net_stat; //对应/proc/net/stat
#ifdef CONFIG_SYSCTL
structctl_table_set sysctls;
#endif
structsock *rtnl; /* rtnetlink socket */
structsock *genl_sock;
structlist_head dev_base_head; // netnamespace中网络设备链表
structhlist_head *dev_name_head;//netnamespace中网络设备名链表
structhlist_head *d