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

简介:     虽然做了很久的网卡驱动,熟悉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  和链路层组播相关.


相关文章
|
存储 运维 API
HPE OneView 10.0 - HPE 服务器、存储和网络设备集中管理软件
HPE OneView 10.0 - HPE 服务器、存储和网络设备集中管理软件
284 1
|
11月前
|
安全 Linux 网络安全
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
280 0
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
|
12月前
|
存储 监控 Linux
Dell OpenManage Enterprise 4.5 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.5 - Dell 服务器、存储和网络设备集中管理软件
317 0
|
存储 安全 Linux
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
480 4
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
WGLOG日志管理系统可以采集网络设备的日志吗
WGLOG日志审计系统提供开放接口,支持外部获取日志内容后发送至该接口,实现日志的存储与分析。详情请访问:https://www.wgstart.com/wglog/docs9.html
|
存储 监控 算法
公司内部网络监控中的二叉搜索树算法:基于 Node.js 的实时设备状态管理
在数字化办公生态系统中,公司内部网络监控已成为企业信息安全管理体系的核心构成要素。随着局域网内终端设备数量呈指数级增长,实现设备状态的实时追踪与异常节点的快速定位,已成为亟待解决的关键技术难题。传统线性数据结构在处理动态更新的设备信息时,存在检索效率低下的固有缺陷;而树形数据结构因其天然的分层特性与高效的检索机制,逐渐成为网络监控领域的研究热点。本文以二叉搜索树(Binary Search Tree, BST)作为研究对象,系统探讨其在公司内部网络监控场景中的应用机制,并基于 Node.js 平台构建一套具备实时更新与快速查询功能的设备状态管理算法框架。
435 3
|
安全 Ubuntu Linux
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
681 0
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
|
XML 安全 网络安全
Nipper 3.7.0 Windows x64 - 网络设备漏洞评估
Nipper 3.7.0 Windows x64 - 网络设备漏洞评估
319 0
Nipper 3.7.0 Windows x64 - 网络设备漏洞评估
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
619 20
|
安全 Linux 网络安全
利用Python脚本自动备份网络设备配置
通过本文的介绍,我们了解了如何利用Python脚本自动备份网络设备配置。该脚本使用 `paramiko`库通过SSH连接到设备,获取并保存配置文件。通过定时任务调度,可以实现定期自动备份,确保网络设备配置的安全和可用。希望这些内容能够帮助你在实际工作中实现网络设备的自动化备份。
835 14

热门文章

最新文章