声明:本文为原创
#####请转贴时保留以下内容######
作者:GTT
请提出宝贵意见Mail:mtloveft@hotmail.com 
Linux Version:2.6.33
提示:本文是介绍linux 网络协议栈初始化!
  
 
下面介绍网络设备层的初始化方法。方法是net_dev_init
subsys_initcall(net_dev_init)
网络设备层的初始化很重要,以后经常得回看这个方法干了些什么。
这里先介绍它的功能,等具体用到它注册或初始化的方法,变量等再回来察看。
下面是source code
| static int __init net_dev_init(void){
 int i, rc = -ENOMEM;
 
 BUG_ON(!dev_boot_phase);
 
 if (dev_proc_init()) goto out;
 
 if (netdev_kobject_init()) goto out;
 
 INIT_LIST_HEAD(&ptype_all);
 for (i = 0; i < PTYPE_HASH_SIZE; i++)
 INIT_LIST_HEAD(&ptype_base[i]);
 
 if (register_pernet_subsys(&netdev_net_ops)) goto out;
 
 /* Initialise the packet receive queues. */
 for_each_possible_cpu(i) {
 struct softnet_data *queue;
 
 queue = &per_cpu(softnet_data, i);
 skb_queue_head_init(&queue->input_pkt_queue);
 queue->completion_queue = NULL;
 INIT_LIST_HEAD(&queue->poll_list);
 
 queue->backlog.poll = process_backlog;
 queue->backlog.weight = weight_p;
 queue->backlog.gro_list = NULL;
 queue->backlog.gro_count = 0;
 }
 
 dev_boot_phase = 0;
 
 /* The loopback device is special if any other network devices
 * is present in a network namespace the loopback device must
 * be present. Since we now dynamically allocate and free the
 * loopback device ensure this invariant is maintained by
 * keeping the loopback device as the first device on the
 * list of network devices. Ensuring the loopback devices
 * is the first device that appears and the last network device
 * that disappears.
 */
 if (register_pernet_device(&loopback_net_ops)) goto out;
 
 if (register_pernet_device(&default_device_ops)) goto out;
 //设置软中断发送处理程序net_tx_action
 open_softirq(NET_TX_SOFTIRQ, net_tx_action);
 //设置软中断接收处理程序net_rx_action
 open_softirq(NET_RX_SOFTIRQ, net_rx_action);
 
 hotcpu_notifier(dev_cpu_callback, 0);
 dst_init();
 dev_mcast_init();
 rc = 0;
 out:
 return rc;
 }
 
 | 
 
 
网络代码中一些很重要的功能,如流量控制,每个CPU的输入队列等功能的初始化,都在此方法里进行。
 
 
主要功能如下
    1:CPU相关的数据结构的初始化,这些数据结构被网络数据接收和发送这两个网络软件中断所使用。
即上面的open_softirq这个方法,被调用了两次。分别注册NET_TX_SOFTIRQ,NET_RX_SOFTIRQ
这两个软中断。中断程序分别是net_tx_action和net_rx_action之后详细介绍这两个重要的方法。
如果看L2以上的程序,可以不关心这两个方法。主要是NIC驱动程序和这两个方法打交道。
 
    2:dev_proc_init() 和dev_mcast_init()会在/proc/目录下新建一些关于网络设备的目录。  
 
    3:netdev_kobject_init() 会在/sys/目录下创建关于网络设备的目录。这个方法和
       上面的dev_proc_init()方法基本一样的功能,在procFS,SysFS这两个文件系统下
        创建网络设备层的目录,这样有些信息就可以和user space的程序打交道了。  
 
 
    4:register_pernet_device(&loopback_net_ops) 注册虚拟Loopback NIC驱动程序。具体怎么注册的,请参看
   Loopback NIC 驱动剖析Series系列文章
 
    5:初始化协议栈L2里的注册L3解析方法的方法数组ptype_base。当受到L2层Frame时,然后调用ptype_base里注册的方法去继续解析高层协议。
 
 
    6: dst_init()是初始化跟协议无关的目标缓存。
 
 
    7: 在通知链表上注册callback 方法。当有CPU的热插拔事件时,这个方法将被调用。callback方法是dev_cpu_callback。
        这个方法现在处理当CPU拔掉时,从CPU的输入队列里把packet取下来,并交给netif_rx处理。
 
 
 
    8: 网络命名空间里注册netdev_net_ops
      这个方法主要初始化以NIC名称为索引和以NIC index为索引的hash表。