gpt4 book ai didi

linux - 捕获数据包后会发生什么?

转载 作者:IT王子 更新时间:2023-10-29 00:05:52 26 4
gpt4 key购买 nike

我一直在阅读 NIC 捕获数据包后发生的情况,但我阅读的越多,我就越困惑。

首先,我读到传统上,在 NIC 捕获数据包后,它会被复制到内核空间中的一 block 内存,然后复制到用户空间,供随后处理数据包数据的任何应用程序使用。然后我读到了 DMA,其中 NIC 绕过 CPU 直接将数据包复制到内存中。那么 NIC -> 内核内存 -> 用户空间内存流是否仍然有效?另外,大多数NIC(例如Myricom)是否使用DMA来提高数据包捕获率?

其次,RSS(Receive Side Scaling)在 Windows 和 Linux 系统中的工作方式是否相似?我只能在 MSDN 文章中找到关于 RSS 如何工作的详细解释,他们在其中谈论 RSS(和 MSI-X)如何在 Windows Server 2008 上工作。但是 RSS 和 MSI-X 的相同概念应该仍然适用于 linux 系统,对吧?

谢谢。

问候,雷恩

最佳答案

这个过程如何进行主要取决于驱动程序作者和硬件,但对于我看过或编写的驱动程序以及我使用过的硬件,通常是这样工作的:

  1. 在驱动程序初始化时,它将分配一些缓冲区并将它们提供给 NIC。
  2. 当 NIC 收到数据包时,它会从其缓冲区列表中提取下一个地址,将数据直接通过 DMA 写入其中,并通过中断通知驱动程序。
  3. 驱动程序获得中断,可以将缓冲区移交给内核,或者分配一个新的内核缓冲区并复制数据。 “零拷贝网络”是前者,显然需要操作系统的支持。 (更多内容见下文)
  4. 驱动程序需要分配一个新的缓冲区(在零拷贝的情况下)或者重新使用缓冲区。在任何一种情况下,缓冲区都会返回给 NIC 以供将来的数据包使用。

内核中的零拷贝网络并不是那么糟糕。一直到用户空间的零复制要困难得多。。 Userland 获取数据,但网络数据包由 header 和数据组成。至少,真正的零拷贝一直到用户空间需要 NIC 的支持,以便它可以将数据包 DMA 到单独的 header /数据缓冲区中。一旦内核将数据包路由到其目的地并验证校验和(对于 TCP,如果 NIC 支持则在硬件中,否则在软件中,否则 header 将被回收;请注意,如果内核必须自己计算校验和,它会也可以复制数据:查看数据会导致缓存未命中,并且可以通过调整代码免费将其复制到其他地方。

即使假设所有星星都对齐,当系统接收到数据时,数据实际上并不在您的用户缓冲区中。在应用程序请求数据之前,内核不知道数据会在哪里结束。考虑像 Apache 这样的多进程守护进程的情况。有很多子进程,都在同一个套接字上监听。您还可以建立一个连接,fork(),这两个进程都能够recv() 传入数据。

Internet 上的 TCP 数据包通常是 1460 字节的有效负载(1500 的 MTU = 20 字节的 IP header + 20 字节的 TCP header + 1460 字节的数据)。 1460 不是 2 的幂,并且与您将找到的任何系统上的页面大小都不匹配。这为数据流的重组带来了问题。请记住,TCP 是面向流的。发送方写入之间没有区别,在接收方等待的两个 1000 字节写入将完全消耗在 2000 字节读取中。

更进一步,考虑用户缓冲区。这些由应用程序分配。为了一直用于零拷贝,缓冲区需要页面对齐并且不与其他任何东西共享该内存页面。在 recv() 时间,内核理论上可以将旧页面重新映射到包含数据的页面并将其“翻转”到位,但是上面的重组问题使这变得复杂,因为连续的数据包将打开单独的页面。内核可以限制它返回给每个数据包有效负载的数据,但这将意味着大量额外的系统调用、页面重新映射和可能降低的整体吞吐量。

我真的只是触及了这个话题的表面。 2000 年代初,我曾在几家公司工作,试图将零拷贝概念扩展到用户领域。我们甚至在用户空间中实现了一个 TCP 堆栈,并为使用该堆栈的应用程序完全绕过了内核,但这带来了一系列问题,而且从来都不是生产质量问题。这是一个很难解决的问题。

关于linux - 捕获数据包后会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2542654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com