network/protocols: Set and check L3/L4_CHECKSUM_VALID flags.

iperf3 TCP on loopback, 1 core (in VMware) goes from ~7.2 Gbits/sec
to ~9.4 Gbits/sec.

Change-Id: I0c93254fab9ee1b5040ef5f71000982bac1a5d15
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7917
Haiku-Format: Haiku-format Bot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-07-30 14:54:49 +00:00
committed by waddlesplash
parent 258ae0c892
commit 2a2f213fde
3 changed files with 12 additions and 7 deletions
@@ -1559,6 +1559,7 @@ ipv4_send_routed_data(net_protocol* _protocol, struct net_route* route,
if (checksumNeeded) {
*IPChecksumField(buffer) = gBufferModule->checksum(buffer, 0,
sizeof(ipv4_header), true);
buffer->buffer_flags |= NET_BUFFER_L3_CHECKSUM_VALID;
}
if ((buffer->msg_flags & MSG_MCAST) != 0
@@ -1741,9 +1742,10 @@ ipv4_receive_data(net_buffer* buffer)
|| headerLength < sizeof(ipv4_header))
return B_BAD_DATA;
// TODO: would be nice to have a direct checksum function somewhere
if (gBufferModule->checksum(buffer, 0, headerLength, true) != 0)
return B_BAD_DATA;
if ((buffer->buffer_flags & NET_BUFFER_L3_CHECKSUM_VALID) == 0) {
if (gBufferModule->checksum(buffer, 0, headerLength, true) != 0)
return B_BAD_DATA;
}
// lower layers notion of broadcast or multicast have no relevance to us
// other than deciding whether to send an ICMP error
@@ -435,6 +435,7 @@ add_tcp_header(net_address_module_info* addressModule,
*TCPChecksumField(buffer) = Checksum::PseudoHeader(addressModule,
gBufferModule, buffer, IPPROTO_TCP);
buffer->buffer_flags |= NET_BUFFER_L4_CHECKSUM_VALID;
return B_OK;
}
@@ -698,9 +699,10 @@ tcp_receive_data(net_buffer* buffer)
if (headerLength < sizeof(tcp_header))
return B_BAD_DATA;
if (Checksum::PseudoHeader(addressModule, gBufferModule, buffer,
IPPROTO_TCP) != 0)
return B_BAD_DATA;
if ((buffer->buffer_flags & NET_BUFFER_L4_CHECKSUM_VALID) == 0) {
if (Checksum::PseudoHeader(addressModule, gBufferModule, buffer, IPPROTO_TCP) != 0)
return B_BAD_DATA;
}
addressModule->set_port(buffer->source, header.source_port);
addressModule->set_port(buffer->destination, header.destination_port);
@@ -828,7 +828,7 @@ UdpEndpointManager::Deframe(net_buffer* buffer)
if (buffer->size > udpLength)
gBufferModule->trim(buffer, udpLength);
if (header.udp_checksum != 0) {
if (header.udp_checksum != 0 && (buffer->buffer_flags & NET_BUFFER_L4_CHECKSUM_VALID) == 0) {
// check UDP-checksum (simulating a so-called "pseudo-header"):
uint16 sum = Checksum::PseudoHeader(addressModule, gBufferModule,
buffer, IPPROTO_UDP);
@@ -1042,6 +1042,7 @@ UdpEndpoint::SendRoutedData(net_buffer *buffer, net_route *route)
calculatedChecksum = 0xffff;
*UDPChecksumField(buffer) = calculatedChecksum;
buffer->buffer_flags |= NET_BUFFER_L4_CHECKSUM_VALID;
return next->module->send_routed_data(next, route, buffer);
}