On 3/8/24 13:42, David Gibson wrote: ...
The payload can be TCP + data or TCP + flags:
struct tcp_l2_flags_t { struct tcphdr th; char opts[OPT_MSS_LEN + OPT_WS_LEN + 1]; };
struct tcp_l2_payload_t { struct tcphdr th; /* 20 bytes */ uint8_t data[MSS]; /* 65516 bytes */ #ifdef __AVX2__ } __attribute__ ((packed, aligned(32))); #else } __attribute__ ((packed, aligned(__alignof__(unsigned int)))); #endif
Not sure if we'd be better off with this approach, or having both IP and L4 headers together, and the L4 payload in another. The latter would mean duplicating the TCP or UDP headers between the IPv4 and IPv6 cases, but it allows the data buffers - which will be used directly on the socket side.
The main idea behind using iovec is to separate tcphdr and iphdr structures, allowing for direct access to the pointers of tcphdr and iphdr without concerns about pointer alignment. Moreover, having tcphdr and TCP payload in the same vector can make sense when computing the TCP checksum, as the checksum includes tcphdr and the payload. Thanks, Laurent