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)