Chinaunix首页 | 论坛 | 博客
  • 博客访问: 629814
  • 博文数量: 155
  • 博客积分: 5688
  • 博客等级: 大校
  • 技术积分: 2134
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-15 15:12
文章分类

全部博文(155)

文章存档

2011年(58)

2010年(97)

分类: LINUX

2010-09-14 22:49:43

声明:本文为原创
#####请转贴时保留以下内容######
作者GTT
本文档归属http://oldtown.cublog.cn/.转载请注明出处!
请提出宝贵意见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;
}

 
 
 
 
 
 
 
 
 


阅读(3372) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-15 15:01:23

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com