From 9350a7520d28d1a38be1f4de0c869b08ceb892eb Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Mon, 4 Mar 2024 07:59:37 +0000 Subject: [PATCH] network: performance tuning and IPv6 checksum fixups --- network/src/lib.rs | 2 +- network/src/proxynat/tcp.rs | 4 ++-- network/src/vbridge.rs | 22 ++++++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/network/src/lib.rs b/network/src/lib.rs index 28ae784..68a82ac 100644 --- a/network/src/lib.rs +++ b/network/src/lib.rs @@ -22,7 +22,7 @@ pub mod proxynat; pub mod raw_socket; pub mod vbridge; -pub const FORCE_MTU: usize = 20000; +pub const FORCE_MTU: usize = 65521; pub struct NetworkService { pub backends: HashMap>, diff --git a/network/src/proxynat/tcp.rs b/network/src/proxynat/tcp.rs index bcc97c4..c348bf3 100644 --- a/network/src/proxynat/tcp.rs +++ b/network/src/proxynat/tcp.rs @@ -194,7 +194,7 @@ impl ProxyTcpHandler { } ProxyTcpAcceptSelect::DoNothing => { - sleeper = Some(tokio::time::sleep(Duration::from_millis(50))); + sleeper = Some(tokio::time::sleep(Duration::from_micros(100))); } ProxyTcpAcceptSelect::Internal(data) => { @@ -398,7 +398,7 @@ impl ProxyTcpHandler { } ProxyTcpDataSelect::DoNothing => { - sleeper = Some(tokio::time::sleep(Duration::from_millis(50))); + sleeper = Some(tokio::time::sleep(Duration::from_micros(100))); } ProxyTcpDataSelect::Close => { diff --git a/network/src/vbridge.rs b/network/src/vbridge.rs index bcd2afc..c0102c4 100644 --- a/network/src/vbridge.rs +++ b/network/src/vbridge.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Result}; use bytes::BytesMut; -use etherparse::{EtherType, Ethernet2Header, IpNumber, Ipv4Header, TcpHeader}; +use etherparse::{EtherType, Ethernet2Header, IpNumber, Ipv4Header, Ipv6Header, TcpHeader}; use log::{debug, trace, warn}; use smoltcp::wire::EthernetAddress; use std::{ @@ -148,13 +148,12 @@ impl VirtualBridge { } }; + // recalculate TCP checksums when routing packets. + // the xen network backend / frontend drivers for linux + // use checksum offloading but since we bypass some layers + // of the kernel we have to do it ourselves. if header.ether_type == EtherType::IPV4 { let (ipv4, payload) = Ipv4Header::from_slice(payload)?; - - // recalculate TCP checksums when routing packets. - // the xen network backend / frontend drivers for linux - // are very stupid and do not calculate these properly - // despite all best attempts at making it do so. if ipv4.protocol == IpNumber::TCP { let (mut tcp, payload) = TcpHeader::from_slice(payload)?; tcp.checksum = tcp.calc_checksum_ipv4(&ipv4, payload)?; @@ -164,6 +163,17 @@ impl VirtualBridge { packet[tcp_header_offset + i] = *b; } } + } else if header.ether_type == EtherType::IPV6 { + let (ipv6, payload) = Ipv6Header::from_slice(payload)?; + if ipv6.next_header == IpNumber::TCP { + let (mut tcp, payload) = TcpHeader::from_slice(payload)?; + tcp.checksum = tcp.calc_checksum_ipv6(&ipv6, payload)?; + let tcp_header_offset = Ethernet2Header::LEN + ipv6.header_len(); + let tcp_header_bytes = tcp.to_bytes(); + for (i, b) in tcp_header_bytes.iter().enumerate() { + packet[tcp_header_offset + i] = *b; + } + } } let destination = EthernetAddress(header.destination);