type
status
date
slug
summary
tags
category
icon
password
Property
Jun 17, 2025 05:34 AM
这篇文章只是个笔记,大部分都是网上摘的,不过如果后续折腾软路由以及相关协议开发还是相当有用的:
 

一、硬件层:物理信号的接收与转换

外部流量(如以太网帧)通过物理介质(网线/光纤)传输,最终到达服务器的网络接口卡(NIC,Network Interface Card)。网卡的核心功能是将物理信号(电/光)转换为数字信号,并完成初步的数据封装/校验。

关键硬件处理步骤:

  1. 信号接收与数字化
    1. 网卡的PHY(物理层芯片)将光/电信号转换为二进制数字信号(比特流),并通过MAC(介质访问控制)子层组装成以太网帧(包含MAC头、IP头、传输层头、数据负载、CRC校验码)。
  1. 硬件校验与过滤
      • CRC校验:网卡硬件自动验证以太网帧尾部的CRC校验码,若校验失败则丢弃该帧(避免无效数据进入系统)。
      • MAC地址过滤:网卡检查目标MAC地址是否为本机MAC(单播)、广播地址(FF:FF:FF:FF:FF:FF)或多播地址(若网卡启用了多播接收)。非目标MAC的帧会被丢弃(除非网卡处于混杂模式)。
  1. DMA传输到内存
    1. 若帧有效,网卡通过DMA(直接内存访问)将数据直接写入内核预分配的接收缓冲区(RX Ring Buffer),避免CPU频繁参与数据拷贝,提升效率。

二、中断与软中断:通知内核处理数据

DMA完成后,网卡通过硬中断(Hardware Interrupt)通知CPU:“有新数据到达!”。为避免硬中断频繁打断CPU(影响性能),现代Linux采用NAPI(New API)机制优化中断处理流程。

关键中断处理步骤:

  1. 硬中断触发
    1. 网卡的IRQ(中断请求)线向CPU发送信号,CPU暂停当前任务,跳转到网卡驱动注册的中断服务例程(ISR, Interrupt Service Routine)
  1. ISR快速处理
    1. ISR的主要任务是确认数据已通过DMA写入内存,并触发软中断(Softirq)(一种延迟执行的软中断,由内核线程ksoftirqd处理),然后将CPU控制权交还。
      注:现代网卡驱动普遍启用NAPI,ISR仅标记“有数据待处理”,由软中断统一处理批量数据包,减少硬中断次数。
  1. 软中断处理
    1. 内核的软中断子系统(net_rx_action)被触发,从RX Ring Buffer中读取数据包,并传递给网络驱动进一步处理。

三、驱动层:数据包的初步解析与传递

网卡驱动(如e1000eixgbe)负责将硬件层面的原始数据转换为内核可识别的sk_buff(Socket Buffer)结构,并传递给上层协议栈。

关键驱动处理步骤:

  1. 数据包校验与完整性检查
    1. 驱动验证以太网帧的完整性(如CRC已由硬件完成,此处可能跳过),并剥离链路层头部(MAC头),提取IP数据报(若为IPv4/IPv6)。
  1. 传递给网络协议栈
    1. 驱动将封装好的sk_buff传递给内核网络子系统的入口函数(如netif_rx()),进入协议栈处理流程。

四、内核协议栈:分层处理与路由决策

内核网络协议栈按OSI模型分层处理数据包,从链路层→网络层→传输层逐步向上,最终到达应用层。在此过程中,netfilter等模块会介入进行流量控制或修改。

1. 链路层(Link Layer)处理

  • 功能:处理以太网帧的头部(源/目标MAC地址、类型字段),判断上层协议类型(如IPv4的类型字段为0x0800)。
  • 关键操作
    • 若帧类型为ARP(地址解析协议),则传递给ARP模块处理(解析IP到MAC的映射)。
    • 若为IP协议(IPv4/IPv6),则剥离链路层头部,将IP数据报传递给网络层。

2. 网络层(Network Layer,IP处理)

IP协议栈根据IP头部的目标IP地址,决定数据包是本机接收还是转发(若本机启用了路由功能)。

关键处理步骤:

  • 校验和验证:检查IP头部的校验和(防止传输过程中数据损坏),失败则丢弃。
  • 选项处理:处理IP头部的可选字段(如记录路由、时间戳等,通常默认忽略)。
  • 路由决策
    • 本地接收:若目标IP是本机配置的IP地址(或广播/多播地址),则进入传输层处理。
    • 转发:若本机是路由器且目标IP不在本地网络,则根据路由表转发至其他接口(需启用ip_forward)。

Netfilter介入点:PREROUTING链

在IP数据报进入网络层后、路由决策前(或路由决策后,取决于数据包方向),netfilter框架的PREROUTING链会被触发。常见操作包括:
  • DNAT(目的地址转换):修改目标IP/端口(如将公网IP映射到内网服务器)。
  • 过滤(Filter):通过iptables/nftables规则丢弃或接受数据包(如阻止特定IP的访问)。
  • 标记(Mark):为数据包打标签(如MARK目标),供后续模块(如tc)使用。

3. 传输层(Transport Layer)处理

根据IP头部的协议字段(如TCP=6,UDP=17),数据包被传递给对应的传输层协议处理模块(如TCP调用tcp_v4_rcv()函数)。

TCP协议处理示例:

  • 校验和验证:检查TCP头部的校验和(基于伪IP头+TCP头+数据计算),失败则丢弃。
  • 端口分发:根据TCP头部的目标端口,找到对应的socket(应用程序通过socket注册的监听端口)。
  • 连接状态管理:若为已建立连接(ESTABLISHED),将数据放入socket的接收缓冲区(sk_buff队列);若为新连接(SYN),则触发三次握手流程。

UDP协议处理示例:

  • 无连接特性,直接根据目标端口查找socket,将数据包放入接收缓冲区(无需建立连接)。

五、流量控制(Traffic Control, tc

tc(Traffic Control)是Linux的流量整形工具,通过qdisc(排队规则)、class(分类)和filter(过滤)对流量进行调度、限速、优先级调整。其介入位置通常在链路层与网络层之间(入队前)或传输层与协议栈之间(出队后),具体取决于配置。

关键处理场景:

  • 入队控制(Ingress Shaping):在数据包进入协议栈前(如通过ifb虚拟设备),对流量进行限速、丢弃或重新标记(如配合netfilterMARK)。
  • 出队控制(Egress Shaping):在数据包离开网卡前,根据优先级调度(如优先保证VoIP流量),避免拥塞丢包。
注:tc通常用于出口流量控制,但通过ifb等虚拟设备也可实现入口流量管理。

六、应用层:数据传递给用户空间

传输层将数据包放入socket的接收缓冲区后,应用程序通过系统调用(如recv()read())从用户空间触发数据拷贝。

关键步骤:

  1. 系统调用触发:应用程序调用recv(sockfd, buf, len, 0),内核检查socket的接收缓冲区是否有数据。
  1. 数据拷贝:若有数据,内核将sk_buff中的负载从内核空间拷贝到用户空间的buf中。
  1. 唤醒进程:若应用程序因等待数据而阻塞(如调用recv()时处于睡眠状态),内核会唤醒该进程继续执行。

总结:完整处理流程图

软路由更新日志又双叒叕来改造软路由
Loading...