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

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


相关文章
|
4天前
|
监控 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
52 20
|
24天前
|
安全 Linux 网络安全
利用Python脚本自动备份网络设备配置
通过本文的介绍,我们了解了如何利用Python脚本自动备份网络设备配置。该脚本使用 `paramiko`库通过SSH连接到设备,获取并保存配置文件。通过定时任务调度,可以实现定期自动备份,确保网络设备配置的安全和可用。希望这些内容能够帮助你在实际工作中实现网络设备的自动化备份。
50 14
|
10天前
|
监控 关系型数据库 MySQL
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
19 0
|
1月前
|
存储 监控 安全
网络设备日志记录
网络设备日志记录是追踪设备事件(如错误、警告、信息活动)的过程,帮助IT管理员进行故障排除和违规后分析。日志详细记录用户活动,涵盖登录、帐户创建及数据访问等。为优化日志记录,需启用日志功能、管理记录内容、区分常规与异常活动,并使用专用工具进行事件关联和分析。集中式日志记录解决方案可收集并统一管理来自多种设备和应用的日志,提供简化搜索、安全存储、主动监控和更好的事件可见性,增强网络安全。常用工具如EventLog Analyzer能灵活收集、存储和分析日志,确保高效管理。
|
2月前
|
5G 数据安全/隐私保护
如果已经链接了5Gwifi网络设备是否还能搜索到其他5Gwifi网络
当设备已经连接到一个5G Wi-Fi网络时,它仍然有能力搜索和发现其他可用的5G Wi-Fi网络。这里所说的“5G Wi-Fi”通常指的是运行在5GHz频段的Wi-Fi网络,而不是与移动通信中的5G网络(即第五代移动通信技术)混淆。
|
3月前
|
网络协议 安全 文件存储
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问,即使IP地址变化,也能通过DDNS服务保持连接。适用于家庭网络远程访问设备及企业临时或移动设备管理,提供便捷性和灵活性。示例代码展示了如何使用Python实现基本的DDNS更新。尽管存在服务可靠性和安全性挑战,DDNS仍极大提升了网络资源的利用效率。
167 6
|
3月前
|
存储 网络性能优化 网络虚拟化
局域网络设备
网卡、中继器、集线器、网桥和交换机是网络通信中的关键设备。网卡实现计算机与网络的连接,中继器用于延长网络传输距离,集线器将多台设备连接至共享网络,网桥通过MAC地址转发数据,而交换机提供高性能的数据转发和过滤服务,支持VLAN、QoS等功能,适用于不同规模的网络环境。
80 3
|
3月前
|
网络协议 安全 网络安全
|
4月前
|
存储 网络安全 数据安全/隐私保护
|
3月前
|
网络虚拟化 数据安全/隐私保护 数据中心
对比了思科和华为网络设备的基本配置、接口配置、VLAN配置、路由配置、访问控制列表配置及其他重要命令
本文对比了思科和华为网络设备的基本配置、接口配置、VLAN配置、路由配置、访问控制列表配置及其他重要命令,帮助网络工程师更好地理解和使用这两个品牌的产品。通过详细对比,展示了两者的相似之处和差异,强调了持续学习的重要性。
108 2

热门文章

最新文章