Linux网络协议栈(三)——网络设备(2)

简介: 2.1、网络设备的注册与注销注册网络设备发生在下列情形: (1)加载网卡驱动程序   网卡驱动程序如果被编译进内核,则它在启动时被初始化,在运行时被作为模块加载。无论初始化是否发生,所以由驱动程序控制的网卡都被注册。

2.1、网络设备的注册与注销
注册网络设备发生在下列情形: 
(1)加载网卡驱动程序 
  网卡驱动程序如果被编译进内核,则它在启动时被初始化,在运行时被作为模块加载。无论初始化是否发生,所以由驱动程序控制的网卡都被注册。 
(2)插入可热拔插网络设备 
  当用户插入一块热拔插网卡,内核通知其对应的驱动程序以注册设备。(为了简单化,我们假定设备驱动程序已经被加载)。

两个主要的情形会导致设备注销:
(1)卸载网卡驱动程序 
  这只适用与驱动程序作为模块被加载的情形,当然不适于编译进内核的情况。当管理员卸载网卡设备驱动程序时,所有相关网卡的驱动程序都被注销。
(2)移除热拔插网络设备 
  当用户从正在运行且内核支持热拔插功能的系统中移除热拔插网卡时,网络设备被注销。

2.1.1、分配 net_device结构空间
在内核中,网络设备由结构net_device表示,在注册网络设备之前,必须为之分配内存空间,这一任务由net/core/dev.c中定义的alloc_netdev函数来完成:

Code

内核也提供了一些封装alloc_netdev功能的函数,如下:

alloc_etherdev函数用于以太网设备,所以它创建以字符串eth后跟唯一数字形式的设备名;第二点,它指派ether_setup作为配置函数,对于所有以太网卡来说,配置函数均把net_device结构的部分域初始化为公用值。

Code

2.1.2、注册网络设备
网络设备注册(a)与注销模型(b):

为了简单,来看看回环设备的注册:

Code

注:在这里,设备驱动初始化函数loopback_init并没有调用alloc_netdev来分配内存,而是直接调用kmalloc,实际上alloc_netdev只是对kmalloc的封装而已。

2.2、网络设备的方法
2.2.1、打开与关闭设备
打开网络设备
一旦设备注册即可使用,但它必须在用户(或用户空间应用程序)使能后才可以收发数据。dev_open 处理设备使能的请求,它定义在net/core/dev.c,定义如下:

Code

打开设备由以下几部组成:
(1)如果 dev->open 被定义则调用它。并非所有的驱动程序都初始化这个函数。 
(2)设置 dev->state 的__LINK_STATE_START 标志位,标记设备打开并在运行。
(3)设置 dev->flags 的 IFF_UP 标志位标记设备启动。 
(4)调用dev_activate所指函数初始化流量控制用的排队规则,并启动监视定时器。如
果用户没有配置流量控制,则指定缺省的先进先出(FIFO)队列。 
(5)发送 NETDEV_UP 通知给 netdev_chain 通知链以通知对设备使能有兴趣的内核组件。

设备驱动的open方法
来看看3com网卡的驱动drivers/net/3c59x.c中的vortex_open,它是在vortex_init()中(即驱动程序初始化的过程中)赋给dev->open函数指针:

Code


关闭网络设备

Code

它由以下几步组成:
(1)发送 NETDEV_GOING_DOWN 通知到 netdev_chain 通知链以通知对设备禁止有兴趣的内核组件。 
(2)调用 dev_deactivate 函数禁止出口队列规则,这样确保设备不再用于传输,并停止
不再需要的监控定时器。 
(3)清除 dev->state 标志的__LINK_STATE_START 标志位,标记设备卸载。 
(4)如果轮询动作被调度在读设备入队列数据包,则等待此动作完成。这是由于__LINK_STATE_START 标志位被清除,不再接受其它轮询在设备上调度,但在标志被清除前已有一个轮询正被调度。 
(5)如果 dev->stop 指针不空则调用它,并非所有的设备驱动都初始化此函数指针。 
(6)清除 dev->flags 的 IFF_UP 标志位标识设备关闭。
(7)发送 NETDEV_DOWN 通知给 netdev_chain 通知链,通知对设备禁止感兴趣的内核组件。

2.2.2、传输数据与接收数据
传输数据
网络子系统中,数据最后由链路层协议调用dev_queue_xmit(),位于net/core/dev.c,完成传输,而dev_queue_xmit又会调用具体网络适配器的驱动程序方法dev->hard_start_xmit(),从而驱动网络适配器最终完成数据传输,参见vortex_start_xmit()。

接收数据
当网络适配器接收一个数据帧时,就会触发一个中断,在中断处理程序(位于设备驱动)中,会分配sk_buff数据结构保存数据帧,最后会调用netif_rx(),将套接字缓冲区放入网络设备的输入队列。对于3c39x.c,其过程如下:
vortex_interrupt( )---> vortex_rx( )--->netif_rx( )。

来看看回环设备的发送与接收过程:

复制代码
//derivers/net/loopback.c
/*首先调用skb_orphan把skb孤立,使它跟发送socket和协议栈不再有任何联系,也即对本机来说,
**这个skb的数据内容已经发送出去了,而skb相当于已经被释放掉了。对于环回设备接口来说,
**数据的发送工作至此已经全部完成,接下来,只要把这个实际上还未被释放的skb传回给协议栈
**的接收函数即可。
*/
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
    struct net_device_stats *lb_stats;
    /////////相当于发送过程////////////////////
    skb_orphan(skb);

    //////////以下相当于接收过程////////////////
    skb->protocol=eth_type_trans(skb,dev);
    skb->dev=dev;
#ifndef LOOPBACK_MUST_CHECKSUM
    skb->ip_summed = CHECKSUM_UNNECESSARY;
#endif

    if (skb_shinfo(skb)->tso_size) {
        BUG_ON(skb->protocol != htons(ETH_P_IP));
        BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);

        emulate_large_send_offload(skb);
        return 0;
    }

    dev->last_rx = jiffies; //接收到数据的时间
    
    //统计信息
    lb_stats = &per_cpu(loopback_stats, get_cpu());
    lb_stats->rx_bytes += skb->len;
    lb_stats->tx_bytes += skb->len;
    lb_stats->rx_packets++;
    lb_stats->tx_packets++;
    put_cpu();

    netif_rx(skb);

    return(0);
}
复制代码

 

 
 
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
目录
相关文章
|
4月前
|
安全 Linux 网络安全
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
151 0
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
|
5月前
|
数据采集 编解码 运维
一文讲完说懂 WowKey -- WowKey 是一款 Linux 类设备的命令行(CLT)运维工具
WowKey 是一款面向 Linux 类设备的命令行运维工具,支持自动登录、批量执行及标准化维护,适用于企业、团队或个人管理多台设备,显著提升运维效率与质量。
|
6月前
|
监控 Linux 开发者
理解Linux操作系统内核中物理设备驱动(phy driver)的功能。
综合来看,物理设备驱动在Linux系统中的作用是至关重要的,它通过与硬件设备的紧密配合,为上层应用提供稳定可靠的通信基础设施。开发一款优秀的物理设备驱动需要开发者具备深厚的硬件知识、熟练的编程技能以及对Linux内核架构的深入理解,以确保驱动程序能在不同的硬件平台和网络条件下都能提供最优的性能。
371 0
|
安全 Linux 网络安全
Web安全-Linux网络协议
Web安全-Linux网络协议
271 4
|
8月前
|
安全 Ubuntu Linux
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
325 0
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
|
9月前
|
运维 安全 Linux
试试Linux设备命令行运维工具——Wowkey
WowKey 是一款专为 Linux 设备设计的命令行运维工具,提供自动化、批量化、标准化、简单化的运维解决方案。它简单易用、高效集成且无依赖,仅需 WIS 指令剧本文件、APT 账号密码文件和 wowkey 命令即可操作。通过分离鉴权内容与执行内容,WowKey 让运维人员专注于决策,摆脱繁琐的交互与执行细节工作,大幅提升运维效率与质量。无论是健康检查、数据采集还是配置更新,WowKey 都能助您轻松应对大规模设备运维挑战。立即从官方资源了解更多信息:https://atsight.top/training。
|
9月前
|
数据采集 运维 安全
Linux设备命令行运维工具WowKey问答
WowKey 是一款用于 Linux 设备运维的工具,可通过命令行手动或自动执行指令剧本,实现批量、标准化操作,如健康检查、数据采集、配置更新等。它简单易用,只需编写 WIS 指令剧本和 APT 帐号密码表文件,学习成本极低。支持不同流派的 Linux 系统,如 RHEL、Debian、SUSE 等,只要使用通用 Shell 命令即可通吃Linux设备。
|
10月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
NoSQL Unix Linux
Linux 设备驱动程序(一)(上)
Linux 设备驱动程序(一)
465 62
|
Java Linux API
Linux设备驱动开发详解2
Linux设备驱动开发详解
273 6