static int __init net_dev_init(void)
{
int i, rc = -ENOMEM;
BUG_ON(!dev_boot_phase);
/*初始化proc文件系统,*/
if (dev_proc_init())
goto out;
/*向sysfs注册为net类,这样会创建/sys/class/net目录,在该目录下每个已注册的网络设备都会有一个子目录,包含很多文件*/
if (netdev_kobject_init())
goto out;
INIT_LIST_HEAD(&ptype_all);
/*协议处理例程向量ptypes_base初始化,用于分离入口流量的多路合并传输*/
for (i = 0; i < PTYPE_HASH_SIZE; i++)
INIT_LIST_HEAD(&ptype_base[i]);
INIT_LIST_HEAD(&offload_base);
if (register_pernet_subsys(&netdev_net_ops))
goto out;
/*初始化数据包接收队列(软中断队列)
/*遍历每一个CPU,取得它的softnet_data,其实它是一个struct softnet_data的Per-CPU变量*/
for_each_possible_cpu(i) {
/*取得第i个CPU的softnet_data也就是软中断的数据队列*/
struct softnet_data *sd = &per_cpu(softnet_data, i);
memset(sd, 0, sizeof(*sd));
/*初始化对列头部*/
skb_queue_head_init(&sd->input_pkt_queue);
skb_queue_head_init(&sd->process_queue);
sd->completion_queue = NULL;
INIT_LIST_HEAD(&sd->poll_list);
sd->output_queue = NULL;
sd->output_queue_tailp = &sd->output_queue;
#ifdef CONFIG_RPS
sd->csd.func = rps_trigger_softirq;
sd->csd.info = sd;
sd->csd.flags = 0;
sd->cpu = i;
#endif
/*把backlog的轮询函数初始化为 process_backlog该函数来处理传统接口使用的输入队列的报文这里是重点,数据包走向netif_receive_skb全靠process_backlog ,process_backlog函数是个什么鬼,会在后面讲到*/
sd->backlog.poll = process_backlog;
/*backlog 轮询函数一次可以处理的报文上限个数*/
sd->backlog.weight = weight_p;
sd->backlog.gro_list = NULL;
sd->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;
/*注册接收,发送软中断*/
open_softirq(NET_TX_SOFTIRQ, net_tx_action);
open_softirq(NET_RX_SOFTIRQ, net_rx_action);
/*注册cpu回调函数,CPU入口队列中的缓冲区出列,然后传给netif_rx函数 */
hotcpu_notifier(dev_cpu_callback, 0);
dst_init();
rc = 0;
out:
return rc;
}