network
network
- 你管这破玩意叫网络
- 22张图详解浏览器请求数据包如何到达web服务器(搞懂网络可以出师了)
- 网卡与Linux网络结构(上)
- 网卡与Linux网络结构(中)
- 网卡与Linux网络结构(下)
- 网卡与数据接收(上)
- 网卡与数据接收(中)
- 源码溯源:网卡队列超时机制
- 通俗理解数据中心CPU和GPU之后的第三颗关键芯片“DPU”
- 字节校招:TCP 和 UDP 可以同时绑定相同的端口吗?
- 59页PPT,全面了解"无线通信原理"
- 【Linux】如何查看网卡驱动
- Linux网络最难理解的五个核心概念
计算机网络
socket
- socket编程入门:1天玩转socket通信技术(非常详细)
- socket缓冲区以及阻塞模式
- Socket缓冲区
- Ubuntu 设置Socket缓冲区大小
- Linux fd 系列 — socket fd 是什么?
- Linux内核 | socket底层的来龙去脉
- 如何学习 Linux 内核网络协议栈
- socket中write和send有什么区别?——拆解大厂面试题(校招)
Netlink
select
epoll
惊群效应
libevent
IO模型
- 聊聊Linux 五种IO模型
- 深入理解Linux I/O系统
- linux文件io缓冲
- Linux 实现原理 — I/O 处理流程与优化手段
- 【Linux】—— Linux下的文件缓冲区
- [基础]同步消息和异步消息传递的区别?
- 终于明白了,一文彻底理解I/O多路复用
- 这次答应我,一举拿下I/O多路复用!
reactor
phy
扫描工具
内网穿透
抓包
-
1
http.host=="www.baidu.com"
收发包
网络数据包的接收过程通常分为硬中断(Hard IRQ)和软中断(Soft IRQ)两个阶段,这是 Linux 网络栈中的典型处理方式,能有效提高性能和响应速度。让我们一步步解释这个流程:
网络数据包的接收流程(发包)
🌟 1. 硬中断阶段(Hard IRQ)
硬中断由网卡(NIC, Network Interface Card)直接触发,处理过程如下:
- 数据包到达网卡:
- 网卡收到网络数据包后,将数据存入网卡的接收环形缓冲区(RX Ring Buffer)。
- 触发硬中断:
- 网卡向 CPU 发送一个硬件中断信号(IRQ, Interrupt Request),通知系统“有新数据包需要处理了”。
- 硬中断处理程序(ISR, Interrupt Service Routine):
- CPU
响应中断,执行网卡驱动程序的硬中断处理逻辑。硬中断处理程序通常做以下工作:
- 禁用网卡中断(避免大量中断拖垮系统)。
- 将数据包的描述符加入 NAPI 列表(NAPI, New API,是
Linux 网络子系统的优化机制)。
- 触发软中断(Soft IRQ)或轮询机制,让后续处理交给软中断来完成。
- 禁用网卡中断(避免大量中断拖垮系统)。
- CPU
响应中断,执行网卡驱动程序的硬中断处理逻辑。硬中断处理程序通常做以下工作:
硬中断要尽量短小精悍,只完成必要的工作,把大部分包处理逻辑交给软中断来做。
⚙️ 2. 软中断阶段(Soft IRQ/NAPI)
软中断是由内核在合适的时机触发的,用来处理大量网络包时的性能瓶颈。流程如下:
- NAPI 轮询机制:
- 在硬中断阶段,网卡驱动程序会将网络接口添加到 NAPI 列表,触发软中断处理逻辑。
- 处理数据包:
- 软中断(
NET_RX_SOFTIRQ
)开始执行,从网卡的 RX 队列取出数据包:- 协议栈处理:解析以太网帧、IP 数据包、TCP/UDP
协议等。
- 分发到上层:根据数据包类型,将数据递交给相应的内核模块(如
socket 层、iptables、防火墙等)。
- 交给用户态:最终数据通过
recv()
系统调用传递给用户态程序。
- 协议栈处理:解析以太网帧、IP 数据包、TCP/UDP
协议等。
- 软中断(
- 恢复中断:
- 数据包处理完成后,软中断会重新开启网卡中断,使得新的数据包到来时,能够再次触发硬中断。
📌 为什么要分硬中断和软中断?
- 减少中断风暴:如果每个数据包都触发硬中断,CPU
会被中断淹没,导致性能下降。
- 批量处理:软中断采用 NAPI
机制,可以在一次软中断处理过程中批量收包,提升效率。
- 更好的调度:软中断可以被内核调度器管控,避免影响其他关键任务的执行。
如果你需要优化网络性能,还可以研究:
- RPS/RFS(Receive Packet Steering/Flow
Steering):多核场景下分散网络流量,减少单核瓶颈。
- XDP(eXpress Data
Path):在网卡驱动层快速处理或丢弃数据包,减少内核协议栈负担。
如果想了解具体代码逻辑,可以看看 net/core/dev.c
文件中的
netif_receive_skb()
、napi_poll()
等函数。
📤 网络数据包的发送流程(发包)
网络数据包的发送也涉及软中断和硬中断,但与收包流程不同,主要由上层协议栈驱动发包,最终由网卡(NIC)负责数据的实际传输。整个流程如下:
1️⃣ 用户态数据准备
在用户态,应用程序(如
ping
、curl
、iperf
或自定义 socket
程序)调用 send()
、write()
等系统调用,向
socket 发送数据: 1
send(sockfd, buffer, len, 0);
2️⃣ 内核协议栈处理
当数据进入内核后,协议栈会依次处理它: ##### (1)TCP/UDP 处理 - UDP:直接封装 IP 头,进入下一步(适用于 DNS、VoIP、视频流等)。 - TCP: - 拆分数据(MSS,最大报文段)。 - 计算 TCP 校验和。 - 维护 TCP 发送队列(适用于重传、流控)。 - 进入 IP 层。
(2)IP 层处理
- 填充源 IP、目的 IP、TTL 等。
- 计算 IP 校验和。
- 进行
路由查找(
fib_lookup()
),决定从哪个网卡发出。
(3)以太网层处理
- 根据 ARP 表查找目标 MAC 地址(如果是第一次发送,可能会先发送 ARP 请求)。
- 组装以太网帧(源 MAC、目的 MAC、协议类型)。
- 数据包进入网卡 TX 队列。
3️⃣ 软中断处理(Soft IRQ / NET_TX_SOFTIRQ)
- 进入
dev_queue_xmit()
- 这个函数检查数据包并调用驱动层的
ndo_start_xmit()
,进入网卡队列。 - 如果队列满了,可能会触发流控(TSO、GSO、Qdisc 等)。
- 这个函数检查数据包并调用驱动层的
- 队列调度(Qdisc, Queueing Discipline)
- 如果开启了
tc
流控(如fq_codel
、pfifo_fast
),数据可能会被重新排序。 - 高速网卡可能会使用 TSO(TCP Segmentation Offload),让网卡直接拆包,提高 CPU 效率。
- 如果开启了
4️⃣ 硬中断触发(Hard IRQ)
数据包最终进入网卡的 发送环形缓冲区(TX Ring
Buffer),这时: 1. 网卡触发硬中断(或 DMA
直接传输)。 2. 网卡驱动调用 xmit_done()
释放已发送的 skb。 3.
网卡将数据发送到物理链路(光纤、电缆、Wi-Fi),数据包真正进入网络。
⚡ 为什么发包时硬中断较少?
相较于收包,发包通常不需要硬中断,原因如下: - TX 采用 DMA 直接传输,只需要在发送完成后通知 CPU。 - 网卡队列(TX Queue)优化,减少 CPU 介入,提高吞吐量。 - GSO/TSO(大包卸载) 让网卡直接拆分 TCP 包,提高效率。
📌 总结
过程 | 触发方式 | 关键函数 |
---|---|---|
用户调用 send() |
用户态 | sys_sendto() |
协议栈处理(TCP/UDP/IP/MAC) | 软中断(NET_TX_SOFTIRQ) | dev_queue_xmit() |
进入网卡队列(TX Queue) | 软中断 | ndo_start_xmit() |
网卡 DMA 传输 | 硬件 | DMA |
发送完成通知(硬中断) | 硬中断 | xmit_done() |
如果你关心具体的优化点,比如 XDP、TSO、GSO、RPS/RFS
等,可以深入研究 net/core/dev.c
、drivers/net/
里的网卡驱动代码。
🌟 收发包中的硬中断与软中断对比
对比项 | 硬中断(Hard IRQ) 🌩️ | 软中断(Soft IRQ) ⚙️ |
---|---|---|
触发时机 | 由硬件事件触发(如网卡收到新数据包或发送完成) | 由内核调度或硬中断触发,批量处理网络事件 |
优先级 | 高,立即打断 CPU 执行当前任务来响应 | 较低,由内核调度器在合适时机运行 |
主要作用 | 快速响应硬件事件,通知系统有新包到达或传输完成 | 批量处理网络数据包,减少中断次数,优化性能 |
收包流程 | 1. 网卡收到数据包,触发硬中断 2. 将包放入 RX 队列 3. 触发软中断来完成后续处理 |
1. 轮询 RX 队列取包 2. 解析协议头(IP、TCP/UDP) 3. 将数据交给上层协议或用户态 |
发包流程 | 1. 发送完成后触发硬中断 2. 通知内核释放发送缓冲区 |
1. 将待发送数据放入 TX 队列 2. 由软中断驱动网卡取包发送 |
处理内容 | - 禁用中断避免风暴 - 通知软中断处理数据包 |
- 批量收发包处理 - 协议栈解析、流控、负载均衡 |
执行时长 | 极短,避免长时间占用 CPU | 相对较长,批量处理多个包 |
性能优化 | - 减少中断频率(NAPI) - 合并多包触发 |
- 使用 NAPI 机制 - 启用 RPS/RFS、XDP 提升性能 |
瓶颈与挑战 | 过多硬中断会导致“中断风暴”,拖垮系统 | 处理量大时易拖慢系统,需配合硬件卸载优化 |
关键机制 | - NAPI(New API) - IRQ 禁用/使能机制 |
- NAPI 轮询 - NET_RX_SOFTIRQ、NET_TX_SOFTIRQ |
总结:
-
硬中断:负责快速响应硬件事件(如新包到达、发送完成),避免
CPU 长时间被打断。
-
软中断:负责批量处理收发包逻辑,减少中断次数,提高系统吞吐量。
- NAPI
机制:结合硬、软中断的优点,通过轮询和批量处理机制,进一步优化高流量场景下的性能。
丢包
在网络收发包过程中,判断一个包是否丢失,通常依赖于协议层面的机制。不同协议有各自的处理方式,下面以常见的 TCP 和 UDP 为例来解释:
🌐 TCP 层的丢包判断机制:
TCP 是可靠传输协议,内置了丢包检测机制,包括以下几种方法:
- 确认机制(ACK):
- TCP 通信是基于序列号(Sequence Number)和确认号(Acknowledgment Number)来跟踪数据包的传输情况。
- 发送方发送一个数据包后,期望接收方返回一个 ACK 确认包。如果在设定的超时时间(RTO, Retransmission Timeout)内未收到 ACK,发送方会认为该包可能丢失,触发重传机制。
- 超时重传(Timeout Retransmission):
- 发送方为每个未确认的数据包启动一个定时器(RTO)。如果超时仍未收到 ACK,发送方认为数据包已丢失,重新发送。
- 快速重传(Fast Retransmit):
- 当接收方收到乱序的包时,会不断发送对最后正确接收的包的 ACK(称为“冗余 ACK”)。如果发送方连续收到 3 个相同的冗余 ACK,就会判断有数据包丢失,触发快速重传。
- 选择性确认(SACK, Selective Acknowledgment):
- 接收方可以通过 SACK 机制告知发送方哪些包已收到,哪些包未收到,从而让发送方仅重传丢失的部分。
📩 UDP 层的丢包判断机制:
UDP 是无连接、不可靠传输协议,本身不提供丢包检测机制。常见的做法包括:
- 应用层序列号:
- 应用程序自行为每个 UDP 包附加序列号,接收方通过序列号判断是否有丢包。
- 超时机制:
- 发送方在发送包后启动超时计时器,如果在一定时间内未收到预期的响应(如 ACK 或心跳包),认为数据包可能丢失。
- 心跳机制(Heartbeat):
- 定期发送探测包,检测链路状态。如果多次探测未响应,则认为有丢包或链路中断。
- FEC(Forward Error Correction,前向纠错):
- 使用冗余信息或校验码(如 Reed-Solomon 编码)来检测并修复丢包,尤其在流媒体、VoIP 等场景常见。
📊 底层机制(链路层/硬件):
- CRC 校验(循环冗余校验):
- 每个数据包附带 CRC 校验码,接收方对收到的包进行校验,发现错误则丢弃该包,依赖上层协议重传。
- 网卡统计:
- 网卡驱动程序维护收发包计数器(如
ifconfig
、ethtool
工具可以查看),包括丢包统计信息,可用来辅助判断。
- 网卡驱动程序维护收发包计数器(如
ovs dpdk
dpdk在用户态收发包是怎么避开内核态的?
DPDK(Data Plane Development Kit)通过以下机制在用户态直接收发包,绕开内核态:
1. 用户态驱动
DPDK使用用户态驱动(PMD)直接与网卡交互,避免了内核态和用户态之间的上下文切换。
2. 轮询模式
DPDK采用轮询模式(Poll Mode),持续检查网卡是否有新数据包到达,而不是依赖内核的中断机制,减少了中断处理的开销。
3. 大页内存
DPDK使用大页内存(HugePages)来减少TLB(Translation Lookaside Buffer)未命中,提升内存访问效率。
4. 零拷贝
DPDK通过零拷贝技术,数据包直接从网卡DMA到用户态内存,无需经过内核缓冲区,减少了数据复制开销。
5. 内存池
DPDK使用预分配的内存池管理数据包缓冲区,避免了频繁的内存分配和释放操作。
6. 网卡队列绑定
DPDK将网卡队列绑定到特定CPU核心,确保数据包处理在固定的CPU上进行,减少上下文切换和缓存失效。
7. 绕过内核协议栈
DPDK绕过内核网络协议栈,直接在用户态处理数据包,减少了内核协议栈的处理开销。
8. 硬件加速
DPDK利用网卡的硬件卸载功能(如校验和计算、TSO等),进一步减少CPU负担。
总结
DPDK通过用户态驱动、轮询模式、大页内存、零拷贝、内存池、队列绑定、绕过内核协议栈和硬件加速等技术,实现了高效的用户态数据包处理,避免了内核态的开销。
pmd一直不陷入内核态?网卡是本机的物理网卡?
1. 用户态驱动(PMD)不陷入内核态
DPDK的用户态驱动(PMD)确实不陷入内核态,它通过以下方式直接与网卡交互:
- 直接访问硬件寄存器:PMD通过映射网卡的硬件寄存器到用户态空间,直接读写这些寄存器来控制网卡。
- DMA(直接内存访问):PMD配置网卡的DMA引擎,使数据包直接从网卡传输到用户态预分配的内存池中,无需内核介入。
- 轮询模式:PMD通过轮询网卡的接收和发送队列来检查数据包,而不是依赖内核的中断机制。
因此,PMD完全运行在用户态,避免了内核态和用户态之间的上下文切换。
2. 网卡是本机的物理网卡
DPDK主要支持本机的物理网卡,但也可以通过虚拟化技术(如SR-IOV)支持虚拟网卡。具体如下:
- 物理网卡:DPDK支持多种物理网卡(如Intel的82599、X710等),并通过PMD直接管理这些网卡。
- 虚拟网卡:在虚拟化环境中,DPDK可以通过SR-IOV(Single Root I/O Virtualization)技术将物理网卡虚拟化为多个虚拟功能(VF),并将这些VF直接分配给虚拟机使用。
- 虚拟设备:DPDK还支持一些虚拟设备(如vhost-user),用于与虚拟机或容器通信。
总结
- PMD不陷入内核态:它通过直接访问硬件寄存器和DMA,完全运行在用户态。
- 网卡类型:DPDK主要支持本机物理网卡,但也支持虚拟化环境中的虚拟网卡。
这种设计使得DPDK能够实现高性能的数据包处理,避免了传统内核网络协议栈的开销。
pmd访问寄存器、DMA不需要调用系统调用?
访问硬件寄存器和配置DMA通常需要特权操作(如访问I/O端口或映射物理内存),这些操作在传统情况下确实需要通过内核态的系统调用来完成。然而,DPDK通过以下机制避免了频繁的系统调用,实现了在用户态直接访问硬件资源:
1. 内存映射(Memory Mapping)
DPDK使用mmap
系统调用将网卡的硬件寄存器和DMA区域映射到用户态地址空间。这是一个一次性的操作:
-
在初始化阶段,DPDK通过mmap
将网卡的寄存器空间和DMA缓冲区映射到用户态。
-
映射完成后,用户态程序可以直接访问这些内存区域,无需每次访问都调用系统调用。
2. UIO(Userspace I/O)或VFIO(Virtual Function I/O)
DPDK依赖于UIO或VFIO框架来实现用户态对硬件的访问: - UIO:通过内核模块将硬件寄存器和中断处理暴露给用户态。 - VFIO:更现代的方式,提供更安全的硬件访问机制,支持DMA和中断处理。
这些框架在初始化阶段通过系统调用完成硬件资源的映射和配置,之后用户态程序可以直接访问硬件资源,无需频繁陷入内核态。
3. 大页内存(HugePages)
DPDK使用大页内存来存储数据包缓冲区。大页内存通过mmap
映射到用户态后,用户态程序可以直接访问这些内存区域,避免了频繁的内存分配和内核态切换。
4. DMA配置
DMA的配置通常需要特权操作,但DPDK在初始化阶段通过以下方式完成: - 使用VFIO或UIO框架配置DMA引擎。 - 将DMA缓冲区映射到用户态内存。 - 之后,用户态程序可以直接操作DMA缓冲区,无需每次DMA传输都调用系统调用。
5. 轮询模式(Poll Mode)
DPDK使用轮询模式检查网卡的接收和发送队列,而不是依赖内核的中断机制。这种方式避免了频繁的中断处理和上下文切换。
总结
- 初始化阶段:DPDK通过
mmap
、UIO/VFIO等机制,将硬件寄存器和DMA区域映射到用户态地址空间。这些操作需要系统调用,但仅在初始化时完成。 - 运行时:映射完成后,用户态程序可以直接访问硬件寄存器和DMA缓冲区,无需频繁调用系统调用。
- 性能优势:通过减少系统调用和上下文切换,DPDK实现了高性能的数据包处理。
因此,DPDK的设计目标是尽量减少运行时对内核态的依赖,而不是完全避免系统调用。
dpdk哪些代码会仅在用户态执行?哪些代码会导致陷入内核态?举例说明
在DPDK中,代码的执行分为用户态和内核态两部分。以下是具体的分类和示例:
1. 仅在用户态执行的代码
这些代码完全运行在用户态,不涉及内核态的切换。
示例:
- 数据包处理逻辑:
1
2
3
4
5
6
7
8
9
10while (1) {
struct rte_mbuf *pkts[BURST_SIZE];
uint16_t nb_rx = rte_eth_rx_burst(port_id, queue_id, pkts, BURST_SIZE);
if (nb_rx == 0) continue;
for (int i = 0; i < nb_rx; i++) {
process_packet(pkts[i]); // 用户态处理数据包
rte_pktmbuf_free(pkts[i]); // 释放数据包缓冲区
}
}rte_eth_rx_burst
:从网卡队列中批量接收数据包。process_packet
:用户态的数据包处理逻辑。rte_pktmbuf_free
:释放数据包缓冲区。
- 内存池操作:
1
struct rte_mempool *mp = rte_pktmbuf_pool_create("mbuf_pool", NUM_MBUFS, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
rte_pktmbuf_pool_create
:创建内存池,用于分配数据包缓冲区。
- 队列操作:
1
struct rte_ring *ring = rte_ring_create("msg_ring", RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);
rte_ring_create
:创建无锁队列,用于线程间通信。
2. 会导致陷入内核态的代码
这些代码涉及与内核的交互,需要通过系统调用或内核模块的支持。
示例:
- 初始化阶段的硬件资源映射:
1
int ret = rte_eal_init(argc, argv);
rte_eal_init
:初始化DPDK环境,包括映射硬件寄存器、配置大页内存等。这些操作需要通过mmap
系统调用将硬件资源映射到用户态。
- 网卡配置:
1
ret = rte_eth_dev_configure(port_id, nb_rx_queue, nb_tx_queue, &port_conf);
rte_eth_dev_configure
:配置网卡的接收和发送队列。在底层可能通过UIO/VFIO框架与内核交互。
- 中断处理:
1
rte_eth_dev_rx_intr_ctl(port_id, queue_id, RTE_EPOLL_PER_THREAD, 1);
rte_eth_dev_rx_intr_ctl
:配置网卡的中断处理。虽然DPDK主要使用轮询模式,但在某些场景下可能涉及中断处理,需要内核支持。
- 大页内存分配:
1
struct rte_memseg *ms = rte_malloc_virt2memseg(ptr, NULL);
rte_malloc_virt2memseg
:将虚拟地址转换为大页内存段。底层依赖于mmap
系统调用。
3. 总结
- 仅在用户态执行的代码:
- 数据包接收、处理和释放。
- 内存池和队列的操作。
- 用户态的业务逻辑。
- 会导致陷入内核态的代码:
- 硬件资源映射和初始化。
- 网卡配置和中断处理。
- 大页内存分配和管理。
DPDK的设计目标是尽量减少运行时的内核态切换,大部分高性能数据路径代码都运行在用户态,只有在初始化和配置阶段才需要与内核交互。
dpdk在内核有对应的驱动吗?
是的,DPDK 在内核中确实有对应的驱动支持,但这些驱动的作用与传统内核网络协议栈的驱动不同。DPDK 依赖的驱动主要用于将硬件资源暴露给用户态,而不是直接处理数据包。以下是 DPDK 在内核中的驱动及其作用:
1. UIO(Userspace I/O)驱动
UIO 是 DPDK 最早使用的驱动框架,它的作用是将硬件资源(如网卡的寄存器、内存映射区域等)暴露给用户态程序。
主要功能:
- 硬件资源映射:将网卡的寄存器空间和 DMA 区域映射到用户态地址空间。
- 中断处理:UIO 驱动可以处理硬件中断,并将中断信息传递给用户态程序。
示例:
igb_uio
或uio_pci_generic
是常用的 UIO 驱动模块。
使用方式:
1 |
|
2. VFIO(Virtual Function I/O)驱动
VFIO 是一个更现代的驱动框架,支持更安全和灵活的硬件访问机制。DPDK 通常优先使用 VFIO 而不是 UIO。
主要功能:
- 安全的硬件访问:VFIO 使用 IOMMU(Input-Output Memory Management Unit)来隔离用户态程序对硬件的访问,防止非法内存访问。
- 支持 SR-IOV:VFIO 可以管理虚拟功能(VF),适用于虚拟化环境。
- 中断和 DMA 支持:VFIO 支持将中断和 DMA 配置暴露给用户态程序。
示例:
vfio-pci
是常用的 VFIO 驱动模块。
使用方式:
1 |
|
3. DPDK 与内核驱动的关系
- 内核驱动的作用:
- 初始化硬件(如网卡)。
- 将硬件资源(寄存器、内存区域、中断等)暴露给用户态。
- 不参与数据包的处理(数据包处理完全由用户态程序完成)。
- 用户态程序的作用:
- 通过映射的硬件资源直接操作网卡。
- 使用轮询模式接收和发送数据包。
- 完全绕过内核网络协议栈。
4. 与传统内核驱动的区别
传统内核网络驱动(如
igb
、ixgbe
)会直接处理数据包,并将数据包传递给内核网络协议栈。而
DPDK 使用的驱动(如 igb_uio
或
vfio-pci
)只是将硬件资源暴露给用户态,数据包的处理完全由用户态程序完成。
5. 总结
- DPDK 在内核中有对应的驱动(如
igb_uio
或vfio-pci
),但这些驱动的作用与传统内核驱动不同。 - 内核驱动的主要任务是将硬件资源暴露给用户态,而不是处理数据包。
- 数据包的处理完全由用户态程序完成,绕过了内核网络协议栈。
通过这种设计,DPDK 实现了高性能的用户态网络数据包处理。
ovs也是运行在用户态?
是的,Open vSwitch (OVS) 的主要数据路径(fast path)运行在用户态,而控制路径(control path)则运行在内核态或用户态,具体取决于 OVS 的部署方式。以下是对 OVS 架构的详细说明:
1. OVS 的架构
OVS 分为两个主要部分: - 用户态组件:负责高性能的数据包处理。 - 内核态组件:负责与内核交互和管理。
2. 用户态组件
OVS 用户态数据路径(fast path)
- DPDK 加速模式:
- 当 OVS 使用 DPDK 时,数据包处理完全运行在用户态。
- OVS 通过 DPDK 的 PMD(Poll Mode Driver)直接与网卡交互,绕过内核网络协议栈。
- 数据包的处理(如匹配流表、执行动作)完全在用户态完成。
- 内核加速模式:
- 当 OVS 不使用 DPDK
时,数据包处理仍然主要运行在用户态,但部分操作可能依赖内核模块(如
openvswitch.ko
)。
- 当 OVS 不使用 DPDK
时,数据包处理仍然主要运行在用户态,但部分操作可能依赖内核模块(如
用户态组件的主要功能:
- 流表匹配:根据数据包的特征匹配流表项。
- 执行动作:根据流表项的指令执行动作(如转发、修改数据包等)。
- 与控制器通信:通过 OpenFlow 协议与 SDN 控制器通信。
3. 内核态组件
内核模块(openvswitch.ko
)
- 当 OVS 不使用 DPDK 时,内核模块负责以下任务:
- 将数据包从内核网络栈传递到用户态。
- 处理部分控制路径逻辑(如端口管理、VLAN 配置等)。
- 提供与内核网络栈的兼容性。
- 当 OVS 使用 DPDK 时,内核模块的作用被最小化,甚至可以不加载。
内核态组件的主要功能:
- 与硬件交互:在不使用 DPDK 时,内核模块负责与网卡驱动交互。
- 管理端口和 VLAN:配置和管理虚拟交换机端口。
- 提供兼容性:支持传统的内核网络栈功能。
4. OVS 的两种模式
DPDK 加速模式
- 数据路径完全运行在用户态。
- 高性能,适合需要低延迟和高吞吐量的场景。
- 依赖 DPDK 用户态驱动(如
vfio-pci
)。
内核加速模式
- 数据路径主要运行在用户态,但部分操作依赖内核模块。
- 性能较低,但兼容性更好。
- 依赖内核模块(如
openvswitch.ko
)。
5. 总结
- OVS 的主要数据路径运行在用户态,无论是使用 DPDK 还是内核加速模式。
- 当使用 DPDK 时,OVS 完全绕过内核网络栈,数据包处理完全在用户态完成。
- 当不使用 DPDK 时,OVS 仍然主要运行在用户态,但部分操作依赖内核模块。
- 内核态组件主要用于管理和兼容性,而不是数据包处理。
因此,OVS 的设计目标是将高性能的数据路径放在用户态,同时通过内核模块提供兼容性和管理功能。
dns
proxy
macOS Monterey 12.7.5在系统偏好设置-网络-WiFi-代理中修改配置无法保存,clashx中设置为系统代理也无法取消,详情参见下图:

查看内核版本:
1
2uname -a
Darwin MacBook-Pro.local 21.6.0 Darwin Kernel Version 21.6.0: Wed Apr 24 06:02:02 PDT 2024; root:xnu-8020.240.18.708.4~1/RELEASE_X86_64 x86_64
查看系统系统发型版本:
1 |
|
在Finder中查看/Library/Preferences/SystemConfiguration/preferences.plist文件,发现图标左下角有把锁,打开简介,显示已锁定。
移除文件锁定:取消对 preferences.plist 文件的用户不可更改(uchg)标志,使其可被修改:
1
sudo chflags nouchg /Library/Preferences/SystemConfiguration/preferences.plist