声明:本文为原创
#####请转贴时保留以下内容######
作者:GTT
请提出宝贵意见Mail:mtloveft@hotmail.com
Linux Version:2.6.33
提示:本文是介绍linux 网络协议栈初始化!
网络命名空间的初始化是linux网络协议栈中第一个被初始化的。为什么要先初始化网络命名空间呢。
因为旧版本的关于网络的全局变量都被包含到命名空间了。所以必须先初始化网络命名空间。
根据以下代码
pure_initcall(net_ns_init); //net/core/net_namespace.c
就知道net_ns_init是被先执行的。
它的代码如下
static int __init net_ns_init(void) { struct net_generic *ng;
#ifdef CONFIG_NET_NS net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), SMP_CACHE_BYTES, SLAB_PANIC, NULL);
/* Create workqueue for cleanup */ netns_wq = create_singlethread_workqueue("netns"); if (!netns_wq) panic("Could not create netns workq"); #endif
ng = net_alloc_generic(); if (!ng) panic("Could not allocate generic netns");
rcu_assign_pointer(init_net.gen, ng);
mutex_lock(&net_mutex); if (setup_net(&init_net)) panic("Could not setup the initial network namespace");
rtnl_lock(); list_add_tail_rcu(&init_net.list, &net_namespace_list); rtnl_unlock();
mutex_unlock(&net_mutex);
return 0; }
|
编译内核时如果没指定CONFIG_NET_NS这项
CONFIG_NET_NS是编译配置选项,用户可以重构网络空间结构。
也就是struct net结构。Kernel主要是考虑扩展性和灵活性。
一般用户不会配置此项,kernel提供一个默认的值即init_net
在net_ns_init方法里对init_net进行初始化。
init_net的定义如下
struct net init_net;
网络命名空间定义了2个链表,pernet_list和net_namespace_list
如下
static LIST_HEAD(pernet_list);
static struct list_head *first_device = &pernet_list;
LIST_HEAD(net_namespace_list);
init_net会被链接到net_namespace_list这个双向链表上。
pernet_operations结构将被链接到pernet_list这个双向链表上。
以后,如果没自定义网络命名空间的话,所有想用网络命名空间时都将利用init_net。
/* * setup_net runs the initializers for the network namespace object. */ static __net_init int setup_net(struct net *net) { /* Must be called with net_mutex held */ const struct pernet_operations *ops, *saved_ops; int error = 0; LIST_HEAD(net_exit_list);
atomic_set(&net->count, 1);
#ifdef NETNS_REFCNT_DEBUG atomic_set(&net->use_count, 0); #endif
list_for_each_entry(ops, &pernet_list, list) { error = ops_init(ops, net); if (error < 0) goto out_undo; } out: return error;
out_undo: /* Walk through the list backwards calling the exit functions * for the pernet modules whose init functions did not fail. */ list_add(&net->exit_list, &net_exit_list); saved_ops = ops; list_for_each_entry_continue_reverse(ops, &pernet_list, list) ops_exit_list(ops, &net_exit_list);
ops = saved_ops; list_for_each_entry_continue_reverse(ops, &pernet_list, list) ops_free_list(ops, &net_exit_list);
rcu_barrier(); goto out; }
|
阅读(3441) | 评论(1) | 转发(0) |