struct net 结构体表示的内核中的网络命名空间(net_namespace)。在linux内核中,每一个网络设备(struct net_device)都有一个所属的网络命名空间,至于一个网络设备是属于内核中的那一个网络命名空间,在介绍网络设备(struct net_device。在linux内核中,用struct net_device来刻画一个网络设备)时候再说。

    在linux内核中,网络命名空间struct net结构体中包含多个字段,在本篇中只介绍其中的一些字段,用于描述内核中网络命名空间的宏观构架。

    struct net

    {

       //用于将内核中的所有的网络命名空间以双链表的形式组织起来,即将

       //所有的struct net结构体组织成双链表;

       struct list_head list ;


         //因为在一个网络命名空间中,可能有多个网络设备,而这些网络设备也是

       //通过双链表的形式组织起来的。而dev_base_head就是网络设备双链表

       //的链表头;

       struct list_head dev_base_head ;


         //因为在一个网络命名空间中,每一个网络设备都有其设备名,而内核为了

       //能够根据网络设备名快速的找到相应的网络设备,使用了内核中常有的

       //哈希散列表来实现根据设备名来快速查找设备。

       struct hlist_head *name_hlist ;


       //在一个网络设备命名空间中,每一个网络设备在系统中都会有一个唯一

       //的接口索引值(int ifindex),同样内核也是通过内核中的哈希散列表

       //来实现根据接口索引值快速查找网络设备。

       struct hlist_head *index_hlist ;

    }


    通过以上对内核中网络命名空间中的一些字段的介绍,明白了内核中的网络命名空间(struct net)是以双链表的形式组织起来的,而在linux内核中的双链表是有头节点的,那内核中的网络命名空间双链表的头节点在哪儿?

    在linux内核中定义了一个如下的结构体,并将其导出,让用户可以通过它来遍历、查找、添加网络命名空间。

    LIST_HEAD(net_namespace_list);

    EXPORT_SYMBOL_GPL(net_namespace_list);


   在linux内核中默认情况下,会有一个默认的网络命名空间,其名为init_net

,并也将其导出,作为全局变量。

   struct net init_net;

    EXPORT_SYMBOL_GPL(init_net);

  

   向内核中添加一个网络命名空间:

   struct net *net_create(void);//这个函数用于向内核中添加一个网络

                                 //命名空间;

   这个函数主要做了三件事:

      1.通过struct net *net_alloc(void)函数分配了一个struct net结构体

       2.通过setup_net(struct net *ns)函数对分配的struct net结构体进行了相应的设置;

      3.最后,将分配的struct net结构体加入到 net_namespace_list的双链表尾部。


  

   释放一个网络命名空间:

   void net_free(struct net *ns);



    遍历内核中的所有的网络命名空间:

    # define for_each_net(var) \

      list_for_each_entry(var, &net_namespace_list, list)

 

    # define for_each_net_rcu(var) \

      list_for_each_entry_rcu(var, &net_namespace_list, list)


  总结:

       网络命名空间struct net通过其中的:

           struct list_head dev_base_list 将其中的所有的网络设备以双链表的形式组织起来。

           struct hlist_head *name_hlist  用于实现通过网络设备名来快速查找网络设备(struct net_device);

           struct hlist_head *index_hlist 用于实现通过网络设备的接口索引值来快速查找网络设备。


        struct net *net_create(void) 用于向内核中添加一个网络命名空间


        void net_free(struct net *ns)用于释放内核中的一个网络命名空间


        for_each_net(struct net *var) 用于遍历内核中的网络命名空间


        for_each_net_rcu(struct net *var)