Linux网络内核二三层转发流程

📅 2026/8/23 17:55:21
Linux网络内核二三层转发流程
startuml linux网络内核-二三层数据转发 title 网络内核数据转发流程 1. 节点定义 (保持原有 rectangle 风格) --- 接收入口 Bridge 处理 --- rectangle 网卡中断 \ as NIC_irq rectangle netif_receive_skb\n (rx_handler注册?) \ as netif_receive_skb rectangle deliver_skb \ as deliver_skb rectangle br_handle_frame \ as br_handle_frame rectangle br_handle_frame_finish\n目的MAC是本设备? \ as br_handle_frame_finish rectangle br_pass_frame_up \ as br_pass_frame_up rectangle br_netif_receive_skb \ as br_netif_receive_skb --- Bridge 转发路径 --- rectangle br_forward \ as br_forward rectangle br_forward_finish \ as br_forward_finish rectangle br_dev_queue_push_xmit \ as br_dev_queue_push_xmit rectangle dev_queue_xmit \ as dev_queue_xmit rectangle __dev_xmit_skb \ as __dev_xmit_skb rectangle sch_direct_xmit \ as sch_direct_xmit rectangle dev_hard_start_xmit \ as dev_hard_start_xmit rectangle ndo_start_xmit \ as ndo_start_xmit --- IP 层接收路径 (简化冗余节点) --- rectangle netif_receive_skb \ as netif_receive_skb2 rectangle pt_prev-func ip_rcv \ as ip_rcv rectangle ip_rcv_finish \ as ip_rcv_finish rectangle dst_input(skb) \ as dst_input rectangle ip_local_deliver \ as ip_local_deliver rectangle ip_local_deliver_finish \ as ip_local_deliver_finish --- 传输层 上层 --- rectangle 传输层网络(四层) \ as upper_layer --- IP 层转发路径 (简化冗余节点) --- rectangle ip_forward \ as ip_forward rectangle ip_forward_finish \ as ip_forward_finish rectangle dst_output \ as dst_output rectangle br_dev_xmit \ as br_dev_xmit --- 发送路径 (Output) --- rectangle ip_queue_xmit \ as ip_queue_xmit rectangle ip_local_out \ as ip_local_out rectangle ip_output \ as ip_output rectangle ip_finish_output \ as ip_finish_output rectangle neigh_output \ as neigh_output 2. 连接关系 --- 链路层接收流 (向上) --- NIC_irq -u- netif_receive_skb netif_receive_skb -u- br_handle_frame : 是网桥转发 br_handle_frame -u- br_handle_frame_finish netif_receive_skb -u- deliver_skb : 否三层接口\n ptype_base协议链 deliver_skb -u- ip_rcv : 进入三层网络 --- Bridge 决策点 (向右转发 或 向上递交) --- br_handle_frame_finish -u- br_forward : 否转发 br_handle_frame_finish -u- br_pass_frame_up : 是本机 --- Bridge 转发流 (向右 - 向下) --- br_forward -d- br_forward_finish br_forward_finish -d- br_dev_queue_push_xmit dev_queue_xmit -d- __dev_xmit_skb : 终端设备 br_dev_queue_push_xmit -d- __dev_xmit_skb __dev_xmit_skb -d- sch_direct_xmit sch_direct_xmit -d- dev_hard_start_xmit dev_hard_start_xmit -d- ndo_start_xmit --- Bridge 向上递交流 (继续向上) --- br_pass_frame_up -u- br_netif_receive_skb br_netif_receive_skb -u- netif_receive_skb2 netif_receive_skb2 -u- ip_rcv : br三层接口 --- IP 层接收流 (向上) --- ip_rcv -u- ip_rcv_finish ip_rcv_finish -u- dst_input dst_input -u- ip_local_deliver ip_local_deliver -u- ip_local_deliver_finish ip_local_deliver_finish -u- upper_layer --- IP 层转发流 (从 ip_rcv_finish 向右) --- ip_rcv_finish -r- ip_forward ip_forward -r- ip_forward_finish ip_forward_finish -r- dst_output --- 发送路径 (从上层层向下) --- upper_layer -d- ip_queue_xmit ip_queue_xmit -d- ip_local_out 路径 A: 通用路由发送 (包括转发包和本机发往非网桥设备的包) ip_local_out -d- dst_output dst_output -d- ip_output ip_output -d- ip_finish_output ip_finish_output -d- neigh_output neigh_output -d- dev_queue_xmit dev_queue_xmit -d- br_dev_xmit : 网桥设备 br_dev_xmit -d- br_forward 3. 注释 (Notes) note right of netif_receive_skb 设备收包 end note note right of br_handle_frame NF_BR_PRE_ROUTING end note note right of br_forward NF_BR_FORWARD NF_BR_LOCAL_OUT end note note right of br_pass_frame_up NF_BR_LOCAL_IN end note note left of br_forward_finish NF_BR_POST_ROUTING end note note right of ip_rcv NF_INET_PRE_ROUTING end note note right of ip_local_deliver NF_INET_LOCAL_IN end note note top of ip_forward NF_INET_FORWARD end note note left of ip_local_out NF_INET_LOCAL_OUT end note note left of ip_output NF_INET_POST_ROUTING end note note left of ndo_start_xmit 设备发包 end note note left of neigh_output 邻居子系统暂未展开 end note note bottom of br_dev_queue_push_xmit 再次调用dev_queue_xmit end note enduml1. 链路层接收与桥接预处理 (Link Layer Rx Bridge Pre-processing)这一阶段主要处理网卡驱动上报的数据包决定是交给网桥处理还是直接上交协议栈。函数节点主要功能描述对应 Netfilter 钩子netif_receive_skb收包入口核心函数。网卡驱动中断处理后调用此函数将sk_buffskb 放入当前 CPU 的处理队列。它负责查找注册的协议处理器如 802.1Q, Bridge, IP 等并分发给对应的rx_handler。-rx_handler注册的处理回调。这是一个通用指针指向具体协议的处理函数。在网桥场景下它指向br_handle_frame在 VLAN 场景下指向 VLAN 处理函数。-br_handle_frame网桥帧处理入口。检查以太网帧头判断是否为网桥需要处理的帧如学习源 MAC、检查目的 MAC。如果是广播、组播或未知单播准备泛洪如果是已知单播准备转发。NF_BR_PRE_ROUTINGbr_handle_frame_finish网桥决策完成点。在完成基本的帧检查和净荷提取后根据目的地址做出最终决策1.转发 (Forward)调用br_forward将包发往其他端口。2.上交 (Deliver up)调用br_pass_frame_up将包交给上层协议栈如果目的 MAC 是网桥本身。-2. 网桥转发路径 (Bridge Forwarding Path)当网桥决定将数据包从一个端口转发到另一个端口时走此路径。函数节点主要功能描述对应 Netfilter 钩子br_forward执行网桥转发逻辑。构建新的转发上下文更新 skb 的设备指针指向出口设备并调用后续函数完成发送准备。NF_BR_FORWARDbr_forward_finish转发收尾工作。处理转发过程中的统计信息更新并最终调用br_dev_queue_push_xmit将包推入发送队列。-br_dev_queue_push_xmit网桥发送队列推送。处理网桥特有的逻辑如可能的分段、校验和计算然后调用通用的dev_queue_xmit。-dev_queue_xmit通用设备发送入口。所有数据包离开内核去往网卡的必经之路。它负责流量控制Qdisc、调度并最终调用网卡驱动的hard_start_xmit。-br_deliver网桥本地发送。当网桥自身作为源产生数据包如生成树协议 BPDU或本地进程发包经过网桥时使用。它将包传递给转发完成函数模拟内部转发流程。NF_BR_LOCAL_OUT3. 网桥上交与协议分发 (Bridge Deliver Up Protocol Demux)当数据包的目的 MAC 是网桥本身或需由本机处理时从网桥逻辑退出进入标准协议栈。函数节点主要功能描述对应 Netfilter 钩子br_pass_frame_up网桥向上递交。将数据包从网桥上下文剥离重新封装或标记准备交给标准的netif_receive_skb流程继续向上处理此时视为从网桥虚拟接口收到包。NF_BR_LOCAL_INbr_netif_receive_skb网桥内部的二次收包。实际上是再次调用netif_receive_skb的变体或直接逻辑确保包能正确匹配到上层的 IP 协议处理器。-pt_prev-func协议类型分发器。pt_prev是一个packet_type结构体指针其func成员指向具体的协议接收函数。对于 IPv4 包这里通常指向ip_rcv。-4. IP 层接收路径 (IP Layer Receive Path)数据包进入 IP 层进行路由查找、合法性检查和本地交付判断。函数节点主要功能描述对应 Netfilter 钩子ip_rcvIP 层接收入口。进行基本的 IP 头部校验版本、长度、校验和剥离以太网头调用NF_INET_PRE_ROUTING钩子。NF_INET_PRE_ROUTINGip_rcv_finishIP 接收后续处理。执行路由查找ip_route_input确定数据包是发给本机、需要转发还是丢弃。根据结果分流到ip_local_deliver或ip_forward。-dst_input目标缓存输入接口。这是一个间接调用层通过dst_entry结构体中的input函数指针进行调用增加了路由子系统的灵活性。-skb_dst(skb)-input动态路由输入执行。实际执行的是dst_input指向的具体函数通常解析后还是回到ip_local_deliver或ip_forward的逻辑分支。-ip_local_deliver本地交付入口。确认数据包目的地址是本机后重组分片如果需要并调用NF_INET_LOCAL_IN钩子。NF_INET_LOCAL_INip_local_deliver_finish本地交付完成。根据 IP 头部的协议字段Protocol如 TCP6, UDP17查找并调用相应的传输层处理函数。-ipprot-handler(skb)传输层协议分发。ipprot是inet_protocol结构体其handler指向具体的协议处理函数如tcp_v4_rcv或udp_rcv。-5. 传输层及上层 (Transport Upper Layers)数据到达传输层及应用层。函数节点主要功能描述对应 Netfilter 钩子tcp/udp_v4_rcvTCP/UDP 接收处理。处理端口查找、连接状态机TCP、校验和验证、数据拷贝到用户空间缓冲区等。-上层网络应用层/Socket 层。数据最终被放入 Socket 接收队列等待用户态进程如 Nginx, SSH读取。-6. IP 层转发路径 (IP Layer Forwarding Path)当ip_rcv_finish判定数据包不是发给本机而是需要路由到其他网络时走此路径。函数节点主要功能描述对应 Netfilter 钩子ip_forwardIP 转发入口。检查转发是否允许ip_forward参数减少 TTL更新校验和调用NF_INET_FORWARD钩子。NF_INET_FORWARDip_forward_finish转发后续处理。确定输出设备和下一跳网关调用dst_output开始发送流程。-dst_output目标缓存输出接口。类似于dst_input通过dst_entry中的output函数指针进行间接调用指向具体的输出逻辑通常是ip_output。-7. 发送路径 (Output Path)无论是本机产生的数据包Local Out还是转发的数据包Forward最终都会汇聚到此发送路径。函数节点主要功能描述对应 Netfilter 钩子tcp_transmit_skbTCP 发送构建。构造 TCP 头部管理重传队列调用下层 IP 发送接口。-ip_queue_xmitIP 发送排队。通用 IP 发送入口处理路由查找如果是本机新生成的包调用ip_local_out。-ip_local_out本地输出口。处理本机产生的数据包调用NF_INET_LOCAL_OUT钩子然后进入dst_output。NF_INET_LOCAL_OUTdst_output(同上)转发和本地发送的汇聚点指向ip_output。-skb_dst(skb)-output(同上)动态执行路由输出函数。-ip_outputIP 输出处理。调用NF_INET_POST_ROUTING钩子处理 IP 选项准备分片如果需要。NF_INET_POST_ROUTINGip_finish_outputIP 输出完成。执行分片逻辑如果需要解析邻居ARP/NDP调用neigh_output。-neigh_output邻居子系统输出。处理二层地址解析。如果已有缓存直接调用dev_queue_xmit如果没有触发 ARP 请求并排队等待。-8. 特殊回环网桥发送 (Bridge Output Loopback)图中展示了一个特殊的回路用于处理网桥相关的发送逻辑。函数节点主要功能描述对应 Netfilter 钩子neigh_output(见上)当解析到的设备是网桥端口时可能会进入网桥特定的发送逻辑。-br_deliver(见前文)在特定上下文中neigh_output可能调用br_deliver来处理网桥内部的本地输出逻辑例如发往网桥自身的控制包或经过复杂过滤后的包。NF_BR_LOCAL_OUTbr_forward_finish(见前文)br_deliver最终会将包导向br_forward_finish从而进入dev_queue_xmit真正发送到物理介质。-总结流程图关键逻辑收包 (Rx):netif_receive_skb-rx_handler(Bridge) -br_handle_frame- 决策 (ForwardvsLocal In)。桥接转发:br_forward-dev_queue_xmit(直接发往其他端口)。桥接上交:br_pass_frame_up-ip_rcv(进入 IP 栈)。IP 路由:ip_rcv_finish是核心分叉口本机:ip_local_deliver-TCP/UDP-App。转发:ip_forward-dst_output。发包 (Tx):本机生成:tcp_transmit_skb-ip_local_out。转发/本地汇聚:dst_output-ip_output-neigh_output-dev_queue_xmit。Netfilter 介入点: 图中明确标注了PRE_ROUTING,LOCAL_IN,FORWARD,LOCAL_OUT,POST_ROUTING以及网桥特有的BR_系列钩子这是防火墙 (iptables/nftables) 发挥作用的关键位置。