5

Can we use zero-copy for TCP send/recv with the default linux TCP/IP-stack?

Example:

int packet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); // raw-sockets

struct tpacket_req3 req;  
setsockopt(packet_socket, SOL_PACKET , PACKET_RX_RING , (void*)&req , sizeof(req));
mapped_buffer = (uint8_t*)mmap(NULL, req.tp_block_size * req.tp_block_nr,
    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, packet_socket, 0);

enter image description here

So can we map part of socket-buffer with received payload from kernel-space to user-space to avoid zero-copy?

Alex
  • 12,578
  • 15
  • 99
  • 195

2 Answers2

5

4.18 merged zero-copy receive support for the in-kernel TCP stack, see:

0

Technically it is impossible to implement zero-copy TCP.

Assume there are multiple application using TCP stack, each app owns a memory region where tcp data is supposed to be written.

When a packet is coming, the NIC hardware doesn't know which connection the packet is belonged to, so the NIC can't determine which memory region to write the packet.

So the only way is first writes to a kernel region and then copy to the app region later.

Zang MingJie
  • 5,164
  • 1
  • 14
  • 27
  • 1
    Kernel could prepare physical memory space for incoming frames/packets and point it to NIC. Then, after packet received, this memory region could be remapped to use by user process (via mmap) on some counterpart of `read` function. Then user could use some smart iterators to access multiple packets/frames data without copying it to create contiguous buffer. – AgainPsychoX Nov 04 '19 at 20:57
  • @AgainPsychoX is correct. That's how zero-copy receive is supposed to be implemented in kernel. But as far as I know, few NICs could support header-data splitting required by this feature. – Bob Mar 01 '23 at 07:28