一文读懂Linux网络命名空间( 四 )

  • 这个结构没什么特别之处 :

一文读懂Linux网络命名空间

文章插图
 
?
 
  • 内核pernet_operations结构将被链接到pernet_list这个双向链表上, 定义:
static LIST_HEAD(pernet_list);static struct list_head *first_device = &pernet_list;DEFINE_MUTEX(net_mutex);
  • 辅助函数register_pernet_subsys和unregister_pernet_subsys分别向该链表添加和删除数据元素. 每当创建一个新的网络命名空间时, 内核将遍历pernet_operations的链表, 用表示新命名空间的net实例作为参数来调用初始化函数 。在删除网络命名空间时,清理工作的处理是类似的
网络命令空间的创建
  • 每个network namespace包换许多元件, 所以当一个新的network namespace被创建, 这些元件必须被初始化. 同样, 当它被删除时,需要做必要的清理工作.
  • Kernel引入了如下结构pernet_operations来维护所有需要做的 initialization/cleanup工作
  • 当一个新的network namespace被创建, kernel遍历pernet_operations 的list, 即遍历pernet_list, 并调用其init函数.
  • 在linux内核中默认情况下, 会有一个"默认的网络命名空间", 其名为init_net, 并也将其导出, 作为全局变量.
  • kernel2.4、2.6:通过copy_net_ns和net_create函数向内核中添加一个网络命名空间, 其中copy_net_ns函数
//http://lxr.free-electrons.com/source/net/core/net_namespace.c?v=2.6.32#L120//这个函数用于向内核中添加一个网络命名空间// struct net *net_create(void);// 这个函数主要做了三件事 :// 1.通过struct net*net_alloc(void)函数分配了一个structnet结构体// 2.通过setup_net(struct net*ns)函数对分配的struct net结构体进行了相应的设置;// 3.将分配的struct net结构体加入到 net_namespace_list的双链表尾部//http://lxr.free-electrons.com/source/net/core/net_namespace.c?v=2.6.32#L143struct net *copy_net_ns(unsigned long flags, struct net *old_net){if (!(flags & CLONE_NEWNET))return get_net(old_net);return net_create();}// 1. 如果设置了CLONE_NEWNET, 就通过net_create创建一个新的net网络命令空间// 2. 否则的话, 返回旧的网络命令空间
  • kernel 3.10之后删除了 net_create 函数, 而通过copy_net_ns函数添加一个网络命名空间 。
释放一个网络命名空间
  • 内核可以通过net_free和net_drop_ns函数来释放掉指定的网络命名空间.
  • 定义:
static void net_free(struct net *net){kfree(rcu_access_pointer(net->gen));kmem_cache_free(net_cachep, net);}void net_drop_ns(void *p){struct net *ns = p;if (ns && atomic_dec_and_test(&ns->passive))net_free(ns);}2.3 总结
  • 记住下列事实就足够了
  1. 网络子系统实现的所有全局函数,都需要一个网络命名空间作为参数,而网络子系统的所有全局属性,只能通过所述命名空间迂回访问.
  2. linux系统包括默认的命名空间 : init_net和用户自定义的net namespace一般是默认的命名空间:init_net, 也就是所有的"网络通信协议"+"网络设备"都是属于默认的命名空间.
  3. 网络命名空间定义了2个链表, pernet_list和net_namespace_list init_net会被链接到net_namespace_list这个双向链表上 pernet_operations结构将被链接到first_device = pernet_list这个双向链表上
  4. 如果没自定义网络命名空间的话,所有想用网络命名空间时都将利用默认的init_net
3、网络命令空间设备命名空间设备指的是那些?
  • 就是网络设备. 通过register_pernet_device注册:就是"注册一个网络设备"到"所有的网络命名空间net", 网络设备包括两类:虚拟的网络设备和物理网络设备 :
3.1 虚拟网络设备
  • 虚拟网络设备的协议根据自身设计特点对skb数据进行处理, 并通过全局变量xx_net_id和各个协议私有的特殊数据结构xx_net, 寻找到该数据包对应的应用层socket插口, 并将其放在该socket插口的接收队列中; 最后应用层在某个时刻会通过read系统调用读取该数据

一文读懂Linux网络命名空间

文章插图
 
?
 
3.2 物理网络设备
  • 比如网卡驱动、无线网卡驱动
3.3 namespace与socket, 网络设备的关系