network

network

计算机网络

socket

select

epoll

惊群效应

libevent

IO模型

reactor

phy

扫描工具

内网穿透

抓包

收发包

网络数据包的接收过程通常分为硬中断(Hard IRQ)软中断(Soft IRQ)两个阶段,这是 Linux 网络栈中的典型处理方式,能有效提高性能和响应速度。让我们一步步解释这个流程:


网络数据包的接收流程(发包)

🌟 1. 硬中断阶段(Hard IRQ)

硬中断由网卡(NIC, Network Interface Card)直接触发,处理过程如下:

  1. 数据包到达网卡:
    • 网卡收到网络数据包后,将数据存入网卡的接收环形缓冲区(RX Ring Buffer)
  2. 触发硬中断:
    • 网卡向 CPU 发送一个硬件中断信号(IRQ, Interrupt Request),通知系统“有新数据包需要处理了”。
  3. 硬中断处理程序(ISR, Interrupt Service Routine):
    • CPU 响应中断,执行网卡驱动程序的硬中断处理逻辑。硬中断处理程序通常做以下工作:
      • 禁用网卡中断(避免大量中断拖垮系统)。
      • 将数据包的描述符加入 NAPI 列表(NAPI, New API,是 Linux 网络子系统的优化机制)。
      • 触发软中断(Soft IRQ)或轮询机制,让后续处理交给软中断来完成。

硬中断要尽量短小精悍,只完成必要的工作,把大部分包处理逻辑交给软中断来做。


⚙️ 2. 软中断阶段(Soft IRQ/NAPI)

软中断是由内核在合适的时机触发的,用来处理大量网络包时的性能瓶颈。流程如下:

  1. NAPI 轮询机制:
    • 在硬中断阶段,网卡驱动程序会将网络接口添加到 NAPI 列表,触发软中断处理逻辑。
  2. 处理数据包:
    • 软中断(NET_RX_SOFTIRQ)开始执行,从网卡的 RX 队列取出数据包:
      • 协议栈处理:解析以太网帧、IP 数据包、TCP/UDP 协议等。
      • 分发到上层:根据数据包类型,将数据递交给相应的内核模块(如 socket 层、iptables、防火墙等)。
      • 交给用户态:最终数据通过 recv() 系统调用传递给用户态程序。
  3. 恢复中断:
    • 数据包处理完成后,软中断会重新开启网卡中断,使得新的数据包到来时,能够再次触发硬中断。

📌 为什么要分硬中断和软中断?

  1. 减少中断风暴:如果每个数据包都触发硬中断,CPU 会被中断淹没,导致性能下降。
  2. 批量处理:软中断采用 NAPI 机制,可以在一次软中断处理过程中批量收包,提升效率。
  3. 更好的调度:软中断可以被内核调度器管控,避免影响其他关键任务的执行。

如果你需要优化网络性能,还可以研究:
- RPS/RFS(Receive Packet Steering/Flow Steering):多核场景下分散网络流量,减少单核瓶颈。
- XDP(eXpress Data Path):在网卡驱动层快速处理或丢弃数据包,减少内核协议栈负担。

如果想了解具体代码逻辑,可以看看 net/core/dev.c 文件中的 netif_receive_skb()napi_poll() 等函数。

📤 网络数据包的发送流程(发包)

网络数据包的发送也涉及软中断硬中断,但与收包流程不同,主要由上层协议栈驱动发包,最终由网卡(NIC)负责数据的实际传输。整个流程如下:


1️⃣ 用户态数据准备

在用户态,应用程序(如 pingcurliperf 或自定义 socket 程序)调用 send()write() 等系统调用,向 socket 发送数据:

1
send(sockfd, buffer, len, 0);
这时,数据进入 TCP/UDP 层 进行处理。


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)

  1. 进入 dev_queue_xmit()
    • 这个函数检查数据包并调用驱动层的 ndo_start_xmit(),进入网卡队列。
    • 如果队列满了,可能会触发流控(TSO、GSO、Qdisc 等)。
  2. 队列调度(Qdisc, Queueing Discipline)
    • 如果开启了 tc 流控(如 fq_codelpfifo_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.cdrivers/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 机制:结合硬、软中断的优点,通过轮询和批量处理机制,进一步优化高流量场景下的性能。

丢包

在网络收发包过程中,判断一个包是否丢失,通常依赖于协议层面的机制。不同协议有各自的处理方式,下面以常见的 TCPUDP 为例来解释:

🌐 TCP 层的丢包判断机制:

TCP 是可靠传输协议,内置了丢包检测机制,包括以下几种方法:

  1. 确认机制(ACK):
    • TCP 通信是基于序列号(Sequence Number)和确认号(Acknowledgment Number)来跟踪数据包的传输情况。
    • 发送方发送一个数据包后,期望接收方返回一个 ACK 确认包。如果在设定的超时时间(RTO, Retransmission Timeout)内未收到 ACK,发送方会认为该包可能丢失,触发重传机制。
  2. 超时重传(Timeout Retransmission):
    • 发送方为每个未确认的数据包启动一个定时器(RTO)。如果超时仍未收到 ACK,发送方认为数据包已丢失,重新发送。
  3. 快速重传(Fast Retransmit):
    • 当接收方收到乱序的包时,会不断发送对最后正确接收的包的 ACK(称为“冗余 ACK”)。如果发送方连续收到 3 个相同的冗余 ACK,就会判断有数据包丢失,触发快速重传。
  4. 选择性确认(SACK, Selective Acknowledgment):
    • 接收方可以通过 SACK 机制告知发送方哪些包已收到,哪些包未收到,从而让发送方仅重传丢失的部分。

📩 UDP 层的丢包判断机制:

UDP 是无连接、不可靠传输协议,本身不提供丢包检测机制。常见的做法包括:

  1. 应用层序列号:
    • 应用程序自行为每个 UDP 包附加序列号,接收方通过序列号判断是否有丢包。
  2. 超时机制:
    • 发送方在发送包后启动超时计时器,如果在一定时间内未收到预期的响应(如 ACK 或心跳包),认为数据包可能丢失。
  3. 心跳机制(Heartbeat):
    • 定期发送探测包,检测链路状态。如果多次探测未响应,则认为有丢包或链路中断。
  4. FEC(Forward Error Correction,前向纠错):
    • 使用冗余信息或校验码(如 Reed-Solomon 编码)来检测并修复丢包,尤其在流媒体、VoIP 等场景常见。

📊 底层机制(链路层/硬件):

  1. CRC 校验(循环冗余校验):
    • 每个数据包附带 CRC 校验码,接收方对收到的包进行校验,发现错误则丢弃该包,依赖上层协议重传。
  2. 网卡统计:
    • 网卡驱动程序维护收发包计数器(如 ifconfigethtool 工具可以查看),包括丢包统计信息,可用来辅助判断。

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
    10
    while (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_uiouio_pci_generic 是常用的 UIO 驱动模块。
使用方式:
1
modprobe uio_pci_generic

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
modprobe vfio-pci

3. DPDK 与内核驱动的关系

  • 内核驱动的作用
    • 初始化硬件(如网卡)。
    • 将硬件资源(寄存器、内存区域、中断等)暴露给用户态。
    • 不参与数据包的处理(数据包处理完全由用户态程序完成)。
  • 用户态程序的作用
    • 通过映射的硬件资源直接操作网卡。
    • 使用轮询模式接收和发送数据包。
    • 完全绕过内核网络协议栈。

4. 与传统内核驱动的区别

传统内核网络驱动(如 igbixgbe)会直接处理数据包,并将数据包传递给内核网络协议栈。而 DPDK 使用的驱动(如 igb_uiovfio-pci)只是将硬件资源暴露给用户态,数据包的处理完全由用户态程序完成。


5. 总结

  • DPDK 在内核中有对应的驱动(如 igb_uiovfio-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)。
用户态组件的主要功能
  • 流表匹配:根据数据包的特征匹配流表项。
  • 执行动作:根据流表项的指令执行动作(如转发、修改数据包等)。
  • 与控制器通信:通过 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
2
uname -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
2
3
4
sw_vers
ProductName: macOS
ProductVersion: 12.7.5
BuildVersion: 21H1222

在Finder中查看/Library/Preferences/SystemConfiguration/preferences.plist文件,发现图标左下角有把锁,打开简介,显示已锁定。

移除文件锁定:取消对 preferences.plist 文件的用户不可更改(uchg)标志,使其可被修改:

1
sudo chflags nouchg /Library/Preferences/SystemConfiguration/preferences.plist

wifi


network
https://realwujing.github.io/linux/kernel/net/network/
作者
Wu Jing
发布于
2025年3月28日
许可协议