網絡設備模塊初始化(net/core/dev.c/net_dev_init)

/*
 *  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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章