网络设备初始化---基础

简介:     虽然做了很久的网卡驱动,熟悉npai机制,但是一直没有底气去深入内核学习,作为学习的引导书《深入理解linux网络内幕》,写点学习心得. 参考内核 linux   2.6.32.
    虽然做了很久的网卡驱动,熟悉npai机制,但是一直没有底气去深入内核学习,作为学习的引导书《深入理解linux网络内幕》,写点学习心得.
参考内核 linux   2.6.32.60    kernel/net/core/dev.c  
   在dev.c 中我们知道其实它是作为一个网络中间层,往下接驱动,往上接tcp/ip协议. 它是一个神奇的桥梁. 这里我们简单的分析它的初始化函数:
    static int __init net_dev_init(void)


点击(此处)折叠或打开

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

    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;

    open_softirq(NET_TX_SOFTIRQ, net_tx_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;
}

subsys_initcall(net_dev_init);
这里我们做一个简单的分析.

先看dev_proc_init函数  它在/proc/net 下注册3个文件:

Dev  如果cat 表示输出系统所以netdevie 设备的统计信息. 而这些设备都挂着全局设备链表dev_base上.

Softnet :
#cat /proc/net/softnet_stat
0d02effd 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000f43
00010042 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000009b9
000026be 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000012a
0000113e 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000054

四行表示4个CPU,
 第一列为该CPU所接收到的所有数据包, 第二列为该CPU缺省queue满的时候, 所删除的包的个数,(没有统计对于使用NAPI的adapter, 由于ring 满而导致删除的包),第三列表示time_squeeze, 就是说,一次的软中断的触发还不能处理完目前已经接收的数据,因而要设置下轮软中断,time_squeeze 就表示设置的次数.
第四--第八暂时没用, 最后一个为CPU_collision,cpu 碰撞ci数.(net/sched.c) 这些信息对分析cpu队列性能会有帮助.

ptye:
cat  输出当前内核注册网络处理协议 .

通过dev_add_pack函数注册网络协议,包类型

void dev_add_pack(struct packet_type *pt)

{

              int hash;

 

              spin_lock_bh(&ptype_lock);

              if (pt->type == htons(ETH_P_ALL))

                            list_add_rcu(&pt->list, &ptype_all);

              else {

                            hash = ntohs(pt->type) & PTYPE_HASH_MASK;

                            list_add_rcu(&pt->list, &ptype_base[hash]);

              }

              spin_unlock_bh(&ptype_lock);

}

而我们看到ptype_all 和 ptype_base链表在net_dev_init 初始化.

INIT_LIST_HEAD(&ptype_all);

         for (i = 0; i

                   INIT_LIST_HEAD(&ptype_base[i]);

....
netdev_kobject_init()   在/sys/class/下注册net类 它和设备模型有关 .
接下来我们看 

点击(此处)折叠或打开

  1. /**
  2.  * register_pernet_subsys - register a network namespace subsystem
  3.  *    @ops: pernet operations structure for the subsystem
  4.  *
  5.  *    Register a subsystem which has init and exit functions
  6.  *    that are called when network namespaces are created and
  7.  *    destroyed respectively.
  8.  *
  9.  *    When registered all network namespace init functions are
  10.  *    called for every existing network namespace. Allowing kernel
  11.  *    modules to have a race free view of the set of network namespaces.
  12.  *
  13.  *    When a new network namespace is created all of the init
  14.  *    methods are called in the order in which they were registered.
  15.  *
  16.  *    When a network namespace is destroyed all of the exit methods
  17.  *    are called in the reverse of the order with which they were
  18.  *    registered.
  19.  */
  20. int register_pernet_subsys(struct pernet_operations *ops)
  21. {
  22.     int error;
  23.     mutex_lock(&net_mutex);
  24.     error = register_pernet_operations(first_device, ops);
  25.     mutex_unlock(&net_mutex);
  26.     return error;
  27. }

register_pernet_subsys注册的所有的网络命名空间子系统都加入到 static struct list_head *first_device = &pernet_list;这个链表里.而它的深远意义目前不是很懂.
接着初始化cpu收发队列 ,这里是重点.

点击(此处)折叠或打开

  1. /*
  2.      *    Initialise the packet receive queues.
  3.      */

  4.     for_each_possible_cpu(i) {
  5.         struct softnet_data *queue;

  6.         queue = &per_cpu(softnet_data, i);
  7.         skb_queue_head_init(&queue->input_pkt_queue);
  8.         queue->completion_queue = NULL;
  9.         INIT_LIST_HEAD(&queue->poll_list);

  10.         queue->backlog.poll = process_backlog;
  11.         queue->backlog.weight = weight_p;
  12.         queue->backlog.gro_list = NULL;
  13.         queue->backlog.gro_count = 0;
  14.     }

对于struct softnet_data这个结构体需要单独讲解. cpu队列在以后数据收发时我们会经常见到它,看过NAPI机制的人应该更加熟悉.  
register_pernet_device(&loopback_net_ops)注册lo  回环网络设备.

open_softirq(NET_TX_SOFTIRQ, net_tx_action);
open_softirq(NET_RX_SOFTIRQ, net_rx_action);

注册收发软中断,发送中断和tc有关.  看它的调用机制就明白。 接收中断napi机制有关.
hotcpu_notifier(dev_cpu_callback, 0); 注册cpu通知链,在cpu热插拔的时候,调用回调函数.

dst_init();

注册路由通知链

dev_mcast_init();

proc/net/下创建 dev_mcast  和链路层组播相关.


相关文章
|
3天前
|
存储 安全 网络安全
网络设备的部署(串行与并行)
网络设备的部署(串行与并行)
13 4
|
3天前
|
Java Linux API
统计android设备的网络数据使用量
统计android设备的网络数据使用量
16 0
|
3天前
|
安全 测试技术 网络架构
【专栏】编写网络设备割接方案的七个步骤,包括明确割接目标、收集信息、制定计划、设计流程、风险评估、准备测试环境和编写文档。
【4月更文挑战第28天】本文介绍了编写网络设备割接方案的七个步骤,包括明确割接目标、收集信息、制定计划、设计流程、风险评估、准备测试环境和编写文档。通过实际案例分析,展示了如何成功完成割接,确保业务连续性和稳定性。遵循这些步骤,可提高割接成功率,为公司的网络性能和安全提供保障。
|
3天前
|
网络虚拟化 数据安全/隐私保护 网络架构
无线网络管理设备
无线网络管理设备
14 3
|
3天前
|
网络协议 网络安全 数据库
LabVIEW中MAX在我的网络上不显示“远程系统”选项卡或设备
LabVIEW中MAX在我的网络上不显示“远程系统”选项卡或设备
|
3天前
|
安全 网络安全 数据库
LabVIEW NI网络设备在MAX中不显示或未识别
LabVIEW NI网络设备在MAX中不显示或未识别
17 4
|
3天前
|
存储 Shell 网络安全
|
3天前
|
安全
AC/DC电源模块在通信与网络设备中的应用的研究
AC/DC电源模块在通信与网络设备中的应用的研究
AC/DC电源模块在通信与网络设备中的应用的研究
|
3天前
BOSHIDA AC/DC电源模块在通信与网络设备中的应用研究
BOSHIDA AC/DC电源模块在通信与网络设备中的应用研究
BOSHIDA AC/DC电源模块在通信与网络设备中的应用研究
|
3天前
|
安全 网络协议 网络架构
【网络技术设备安全】BGP 基础与概述-2-中转 AS 中的 IBGP 路由传递
【网络技术设备安全】BGP 基础与概述-2-中转 AS 中的 IBGP 路由传递
【网络技术设备安全】BGP 基础与概述-2-中转 AS 中的 IBGP 路由传递

热门文章

最新文章