在没有根访问权限的linux上是否可以使用packet_mmap?

在没有根访问权限的linux上是否可以使用packet_mmap?,c,linux,linux-kernel,udp,packet-capture,C,Linux,Linux Kernel,Udp,Packet Capture,Linux允许通过在内核和用户之间映射共享缓冲区来高效捕获网络数据包。我试图以一种不需要root访问的方式使用这个接口(因为我没有root访问) 通常,packet_mmap用于直接查看网络上需要根访问的所有数据包。我的应用程序只需要使用标准的linux UDP套接字接口。我希望使用packet_mmap纯粹是为了提高效率——现在系统调用占用了我50%以上的CPU周期 有没有一种方法可以配置packet_mmap,这样就可以从用户空间使用它?虽然这并不能真正回答问题(因为它是专门关于packet

Linux允许通过在内核和用户之间映射共享缓冲区来高效捕获网络数据包。我试图以一种不需要root访问的方式使用这个接口(因为我没有root访问)

通常,packet_mmap用于直接查看网络上需要根访问的所有数据包。我的应用程序只需要使用标准的linux UDP套接字接口。我希望使用packet_mmap纯粹是为了提高效率——现在系统调用占用了我50%以上的CPU周期


有没有一种方法可以配置packet_mmap,这样就可以从用户空间使用它?

虽然这并不能真正回答问题(因为它是专门关于packet_mmap的),但考虑到您的参数:

  • 接收UDP数据包
  • 想减少系统调用,别无其他
  • 愿意使用Linux特定功能,但没有root用户
  • 数据包mmap的功能不是真正需要或期望的
  • 我建议您完全忘记packet_mmap,而是查看一下(注意拼写,而不是拼写错误)


    recvmmsg
    不需要特殊权限,它非常直观(没有晦涩的东西,它的工作原理就像
    readv
    ),它允许您在一次调用中接收多个数据包,大大减少了系统调用开销。

    查看Linux内核Git存储库,似乎
    PF_INET
    sockets和
    PF_INET6
    sockets都不支持内存映射访问,因此如果

    我的应用程序只需要使用标准的linux UDP套接字接口。我希望使用packet_mmap纯粹是为了提高效率——现在系统调用占用了我50%以上的CPU周期

    您的意思是希望对普通UDP或TCP套接字使用内存映射访问,不幸的是,您不能。这同样适用于原始IP套接字

    pfu数据包
    sockets确实支持内存映射访问,但无论您是否使用内存映射访问,它们都需要提升的权限。它们不是
    PF_INET
    PF_INET6
    插座的替代品;它们是一种读写链路层数据包的机制,因此,如果您想在其上运行正常的Internet应用程序,祝您好运:

  • 您必须自己重新实现IP和正在使用的任何传输协议(UDP、TCP等)
  • 您必须以某种方式防止内核的IP和传输协议栈处理这些数据包 你真的不想试着这么做


    (请注意,“提升的权限”并不一定是指“根权限”;
    CAP\u NET\u RAW
    权限应该足够了。但是,正如我所指出的,如果您试图替换常规套接字访问,您不想使用
    PF\u PACKET
    sockets。)

    在Unix中,权限提升的标准方法是setuid位。我认为不需要提升就使用这种功能是错误的。我想知道是否有一种方法可以限制我可以使用它,这样我就可以从用户空间使用它。有趣的是,我来看看。我想我必须生成一个工作线程来调用
    recvmmsg
    ,并将结果放入一个ringbuffer。(我需要一个环形缓冲区来实现高效的多线程)可以,也可以先使用,这样就不会阻塞
    recvmmsg
    。这通常和启动一个额外的线程一样好(但不那么复杂)。我考虑过使用它,但是当多个线程同时尝试读取时,它不会引起很多争用吗?此外,一个线程可能会一次接收多个数据包,而其他线程则一个数据包也没有?单线程很容易就足以接收通过千兆或10G电缆传输的任何内容。如果您想利用并行性,通常会让一个线程什么也不做,只接收数据,还可以选择让另一个线程(或其他几个线程)处理数据。让多个线程同时接收数据没有性能优势,而且可能会更慢(大量上下文切换)。这就是为什么我说我必须创建一个线程来将传入的数据包读入环形缓冲区。您可以使用此接口发送标准UDP数据包(SOCK_DGRAM)“如果模式为SOCK_RAW,则可以捕获原始接口的链接级别信息,如果不支持链接级别信息捕获,并且内核提供了链接级别伪头,则可以捕获熟食接口的链接级别信息或SOCK_DGRAM。“可以,但您必须自己构造IP头,至于接收标准UDP数据包,如果有进程监听UDP端口,即使您使用的是
    pfu数据包
    socket,它也会得到这些数据包,如果UDP端口上没有进程监听,内核将发送ICMP端口无法访问的消息即使您使用的是
    PF_数据包
    socket。这里的数据包mmap与常规
    PF_数据包
    sockets没有区别,也不是常规
    PF_INET
    /
    PF_INET6
    sockets的替代品。