首页 > 其他分享 >接收网络包的过程——从硬件网卡解析到IP层

接收网络包的过程——从硬件网卡解析到IP层

时间:2024-09-18 20:22:23浏览次数:10  
标签:调用 中断 IP ixgb 网络 网卡 skb poll 解析

当一些网络包到来触发了中断,内核处理完这些网络包之后,我们可以先进入主动轮询 poll 网卡的方式,主动去接收到来的网络包。如果一直有,就一直处理,等处理告一段落,就返回干其他的事情。当再有下一批网络包到来的时候,再中断,再轮询 poll。这样就会大大减少中断的数量,提升网络处理的效率,这种处理方式我们称为 NAPI。

在网卡驱动程序初始化的时候,我们会调用 ixgb_init_module,注册一个驱动 ixgb_driver,并且调用它的 probe 函数 ixgb_probe。

在 ixgb_probe 中,我们会创建一个 struct net_device 表示这个网络设备,并且 netif_napi_add 函数为这个网络设备注册一个轮询 poll 函数 ixgb_clean,将来一旦出现网络包的时候,就是要通过它来轮询了。

当一个网卡被激活的时候,我们会调用函数 ixgb_open->ixgb_up,在这里面注册一个硬件的中断处理函数。

如果一个网络包到来,触发了硬件中断,就会调用 ixgb_intr,这里面会调用 __napi_schedule。

__napi_schedule 是处于中断处理的关键部分,在他被调用的时候,中断是暂时关闭的,但是处理网络包是个复杂的过程,需要到延迟处理部分,所以 ____napi_schedule 将当前设备放到 struct softnet_data 结构的 poll_list 里面,说明在延迟处理部分可以接着处理这个 poll_list 里面的网络设备。

然后 ____napi_schedule 触发一个软中断 NET_RX_SOFTIRQ,通过软中断触发中断处理的延迟处理部分,也是常用的手段。

在 net_rx_action 中,会得到 struct softnet_data 结构,这个结构在发送的时候我们也遇到过。当时它的 output_queue 用于网络包的发送,这里的 poll_list 用于网络包的接收。

在 net_rx_action 中,接下来是一个循环,在 poll_list 里面取出网络包到达的设备,然后调用 napi_poll 来轮询这些设备,napi_poll 会调用最初设备初始化的时候,注册的 poll 函数,对于 ixgb_driver,对应的函数是 ixgb_clean。

在网络设备的驱动层,有一个用于接收网络包的 rx_ring。它是一个环,从网卡硬件接收的包会放在这个环里面。这个环里面的 buffer_info[]是一个数组,存放的是网络包的内容。i 和 j 是这个数组的下标,在 ixgb_clean_rx_irq 里面的 while 循环中,依次处理环里面的数据。在这里面,我们看到了 i 和 j 加一之后,如果超过了数组的大小,就跳回下标 0,就说明这是一个环。

ixgb_check_copybreak 函数将 buffer_info 里面的内容,拷贝到 struct sk_buff *skb,从而可以作为一个网络包进行后续的处理,然后调用 netif_receive_skb。

从 netif_receive_skb 函数开始,我们就进入了内核的网络协议栈。

接下来的调用链为:netif_receive_skb->netif_receive_skb_internal->__netif_receive_skb->__netif_receive_skb_core。

在 __netif_receive_skb_core 中,我们先是处理了二层的一些逻辑。例如,对于 VLAN 的处理,接下来要想办法交给第三层。

在网络包 struct sk_buff 里面,二层的头里面有一个 protocol,表示里面一层,也即三层是什么协议。deliver_ptype_list_skb 在一个协议列表中逐个匹配。如果能够匹配到,就返回。

网络协议栈的 IP 层,从 ip_rcv 函数开始,我们的处理逻辑就从二层到了三层,IP 层。

在 ip_rcv 中,得到 IP 头,然后又遇到了我们见过多次的 NF_HOOK,这次因为是接收网络包,第一个 hook 点是 NF_INET_PRE_ROUTING,也就是 iptables 的 PREROUTING 链。如果里面有规则,则执行规则,然后调用 ip_rcv_finish。

ip_rcv_finish 得到网络包对应的路由表,然后调用 dst_input,在 dst_input 中,调用的是 struct rtable 的成员的 dst 的 input 函数。在 rt_dst_alloc 中,我们可以看到,input 函数指向的是 ip_local_deliver。

在 ip_local_deliver 函数中,如果 IP 层进行了分段,则进行重新的组合。接下来就是我们熟悉的 NF_HOOK。hook 点在 NF_INET_LOCAL_IN,对应 iptables 里面的 INPUT 链。在经过 iptables 规则处理完毕后,我们调用 ip_local_deliver_finish。

在 IP 头中,有一个字段 protocol 用于指定里面一层的协议,在这里应该是 TCP 协议。于是,从 inet_protos 数组中,找出 TCP 协议对应的处理函数。这个数组的定义如下,里面的内容是 struct net_protocol。

在系统初始化的时候,网络协议栈的初始化调用的是 inet_init,它会调用 inet_add_protocol,将 TCP 协议对应的处理函数 tcp_protocol、UDP 协议对应的处理函数 udp_protocol,放到 inet_protos 数组中。

在上面的网络包的接收过程中,会取出 TCP 协议对应的处理函数 tcp_protocol,然后调用 handler 函数,也即 tcp_v4_rcv 函数。

接收网络包的上半部分,分以下几个层次。

  • 硬件网卡接收到网络包之后,通过 DMA 技术,将网络包放入 Ring Buffer。
  • 硬件网卡通过中断通知 CPU 新的网络包的到来。
  • 网卡驱动程序会注册中断处理函数 ixgb_intr。
  • 中断处理函数处理完需要暂时屏蔽中断的核心流程之后,通过软中断 NET_RX_SOFTIRQ 触发接下来的处理过程。
  • NET_RX_SOFTIRQ 软中断处理函数 net_rx_action,net_rx_action 会调用 napi_poll,进而调用 ixgb_clean_rx_irq,从 Ring Buffer 中读取数据到内核 struct sk_buff。
  • 调用 netif_receive_skb 进入内核网络协议栈,进行一些关于 VLAN 的二层逻辑处理后,调用 ip_rcv 进入三层 IP 层。
  • 在 IP 层,会处理 iptables 规则,然后调用 ip_local_deliver,交给更上层 TCP 层。
  • 在 TCP 层调用 tcp_v4_rcv。

接收网络包的过程——从硬件网卡解析到IP层_数据包

标签:调用,中断,IP,ixgb,网络,网卡,skb,poll,解析
From: https://blog.51cto.com/key3feng/12048336

相关文章

  • 论文解读《MobileCLIP: Fast Image-Text Models through Multi-Modal Reinforced Trai
    系列文章目录文章目录系列文章目录论文细节理解1、研究背景2、论文贡献3、方法框架4、研究思路5、实验6、限制论文细节理解Ensembleteacher.在深度学习领域,什么意思?在深度学习领域,“ensembleteacher”通常指的是一种模型集成的方法,其中多个模型(教师模型)共同训......
  • WPF WebBrowser suppress script errors
    ScriptError,Anerrorhasoccuredinthescriptonthispage.Doyouwanttocontinuerunningscriptsonthispage?   //xaml<Windowx:Class="WpfApp378.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/present......
  • WPF CheckBox ToolTip Image
    <Windowx:Class="WpfApp377.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft......
  • Caliper Edit Control - WP Editor
    卡钳(Caliper)编辑控件为CogCaliperTool及其组件提供了一个图形用户界面。卡钳工具在投影区域内搜索边缘或边缘对。卡钳编辑控件有两种模式:单边缘(SingleEdge)模式或边缘对(EdgePair)模式,您可以在“设置(Settings)”选项卡中进行设置。单边缘模式用于定位边缘,而边缘对模式用于定位边......
  • 中国企业数据资产入表情况跟踪全文解析
    随着数字经济的蓬勃发展,数据已成为企业的重要资产。2023年8月,中国财政部发布的《企业数据资源相关会计处理暂行规定》标志着数据资源正式纳入会计核算体系,为企业数据资产的管理和运用提供了政策支持。本文将详细分析2024年第一季度中国企业数据资产入表的现状、挑战与未来趋势。一......
  • 【他山之石】优化 JavaScript 的乐趣与价值(下)
    前言继本文的上篇发表之后,没想到反响还挺好,看来大家在JS优化的问题上越来越注重“与国际接轨”了。一起来看本文的下篇,也是干货满满。文章目录6.AvoidlargeobjectsWhattheeffshouldIdoaboutthis?7.Useeval8.Usestrings,carefullyWhattheeffs......
  • vulnhub(9):sickos1.2(深挖靶机的各个细节、文件管道反弹shell详解、base64编码反弹shell
    端口nmap主机发现nmap-sn192.168.148.0/24​Nmapscanreportfor192.168.148.131Hostisup(0.00020slatency).​131是新出现的机器,他就是靶机nmap端口扫描nmap-Pn192.168.148.131-p---min-rate10000-oAnmap/scan扫描开放端口保存到nmap/scan下​......
  • 安卓手机改ip地址改到其他市
    在数字化时代,IP地址作为设备在网络上的唯一标识,其重要性不言而喻。有时,出于测试、学习或特定服务访问的需求,用户可能希望将安卓手机的IP地址修改为其他城市的地址。本文旨在探讨如何在安卓手机上修改IP地址至其他城市,并提供合规使用的建议。一、修改IP地址的方法要在安卓手......
  • 菜鸟笔记之PWN入门(1.1.0)ELF 文件格式和程序段解析(简版)
    ELF(ExecutableandLinkableFormat):是一种用于可执行文件、目标文件和库的文件格式,类似于Windows下的PE文件格式。ELF主要包括三种类型的文件:可重定位文件(relocatable):编译器和汇编器产生的 .o 文件,由 Linker 处理。可执行文件(executable): Linker ......
  • Javaweb之SpringBootWeb案例之修改员工的修改回显的详细解析
     3.修改员工需求:修改员工信息编辑在进行修改员工信息的时候,我们首先先要根据员工的ID查询员工的信息用于页面回显展示,然后用户修改员工数据之后,点击保存按钮,就可以将修改的数据提交到服务端,保存到数据库。具体操作为:根据ID查询员工信息保存修改的员工信息3.1查询回显3.1.1接口......