欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络设备模块初始化(net/core/dev.c/net_dev_init)

程序员文章站 2022-03-07 09:38:01
...
/*
 *  Initialize the DEV module. At boot time this walks the device list and
 *  unhooks any devices that fail to initialise (normally hardware not
 *  present) and leaves us with a valid list of present and active devices.
 *
 */

/*
 *       This is called single threaded during boot, so no need
 *       to take the rtnl semaphore.
 */
static int __init net_dev_init(void)
{
    int i, rc = -ENOMEM;

    BUG_ON(!dev_boot_phase);

    net_random_init();

    /*初始化dev相关proc文件(dev,softnet_stat)
      /proc/net/dev  可以显示网络接口的一些收发包信息  
      /proc/net/softnet_stat 显示每个CPU处理接收包的统计信息 
    */
    if (dev_proc_init())
        goto out;

    /*初始化网络接口属性(如eth0、lo、eth1)
    /sys/class/net/xxx/*** 显示了各种设备的一些属性信息,比如IP、掩码、mac地址等
    */
    if (netdev_sysfs_init())
        goto out;

    /*ptype_all处理所有包类型列表初始化(如PF_PACKT协议族),这个链表上的协议处理程序接收所有协议的报文,主要用于网络工具和网络嗅探器接收报文。比如tcpdump 抓包程序和原始套接字使用这种类型的packet_type结构*/
    /*ptype_base基本包类型列表初始化,具体到eth_type这时基本包类型是指二层链路上的负载类型,比如IP、VLAN等*/
    INIT_LIST_HEAD(&ptype_all);
    for (i = 0; i < 16; i++) 
        INIT_LIST_HEAD(&ptype_base[i]);

    /*基于名称的设备HASH列表初始化*/
    for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)
        INIT_HLIST_HEAD(&dev_name_head[i]);

    /*基于设备接口索引的设备HASH列表 */
    for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)
        INIT_HLIST_HEAD(&dev_index_head[i]);

    /*
     *  Initialise the packet receive queues.
     */

    for_each_possible_cpu(i) {
        struct softnet_data *queue;

        /*每CPU的软中断处理数据*/
        queue = &per_cpu(softnet_data, i);

        /*初始化收包工作所需要的列表等参数 ,这里input_pkg_queue及虚拟设备backlog_dev仅用于不支持NAPI接收模式的设备驱动使用*/
        skb_queue_head_init(&queue->input_pkt_queue);
        queue->completion_queue = NULL;
        INIT_LIST_HEAD(&queue->poll_list);
        set_bit(__LINK_STATE_START, &queue->backlog_dev.state);
        queue->backlog_dev.weight = weight_p;
        queue->backlog_dev.poll = process_backlog;
        atomic_set(&queue->backlog_dev.refcnt, 1);
    }

    /*注册网络子系统,dma客户端*/
    netdev_dma_register();

    dev_boot_phase = 0;

    /*注册收发包软中断 **
    open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
    open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);

    /*向支持热拔插类型的CPU注册CPU改变通知链,当CPU被移除时,将被移除的CPU上待处理的收发包队列转移到当前正在使用的CPU上工作*/
    hotcpu_notifier(dev_cpu_callback, 0);

    /* 注册了网络设备的通知链,后续当网络设备DOWN(如ifdown命令)掉时,会遍历  
      dst_garbage_list列表,则列表中所有dst_entry条目的input、output回调分别设置为  
     dst_discard_in和dst_discard_out来进行丢包处理。*/
    dst_init();

    /*/proc/net/dev_mcast  可以显示所有设备的组播地址列表 */
    dev_mcast_init();
    rc = 0;
out:
    return rc;
}

参考文章链接:https://blog.csdn.net/liujianfeng1984/article/details/41343075

相关标签: 网络协议栈