diff --git a/rust/relay/ebpf-turn-router/src/error.rs b/rust/relay/ebpf-turn-router/src/error.rs index 94b6b9a0f..2ffa731db 100644 --- a/rust/relay/ebpf-turn-router/src/error.rs +++ b/rust/relay/ebpf-turn-router/src/error.rs @@ -12,9 +12,9 @@ pub enum Error { BadChannelDataLength, NoEntry(SupportedChannel), UnsupportedChannel(UnsupportedChannel), - XdpLoadBytesFailed, - XdpAdjustHeadFailed, - XdpStoreBytesFailed, + XdpLoadBytesFailed(i64), + XdpAdjustHeadFailed(i64), + XdpStoreBytesFailed(i64), } #[derive(Debug, Clone, Copy)] @@ -36,45 +36,66 @@ pub enum UnsupportedChannel { impl aya_log_ebpf::WriteToBuf for Error { #[inline(always)] fn write(self, buf: &mut [u8]) -> Option { - let msg = match self { - Error::PacketTooShort => "Packet is too short", - Error::NotUdp => "Not a UDP packet", - Error::NotTurn => "Not TURN traffic", - Error::NotIp => "Not an IP packet", - Error::NoMacAddress => "No MAC address", - Error::Ipv4PacketWithOptions => "IPv4 packet has options", - Error::NotAChannelDataMessage => "Not a channel data message", - Error::BadChannelDataLength => "Channel data length does not match packet length", + match self { + Error::PacketTooShort => "Packet is too short".write(buf), + Error::NotUdp => "Not a UDP packet".write(buf), + Error::NotTurn => "Not TURN traffic".write(buf), + Error::NotIp => "Not an IP packet".write(buf), + Error::NoMacAddress => "No MAC address".write(buf), + Error::Ipv4PacketWithOptions => "IPv4 packet has options".write(buf), + Error::NotAChannelDataMessage => "Not a channel data message".write(buf), + Error::BadChannelDataLength => { + "Channel data length does not match packet length".write(buf) + } Error::NoEntry(SupportedChannel::UdpToChan44) => { - "No entry in UDPv4 to channel IPv4 map" + "No entry in UDPv4 to channel IPv4 map.write(buf)".write(buf) } Error::NoEntry(SupportedChannel::ChanToUdp44) => { - "No entry in channel IPv4 to UDPv4 map" + "No entry in channel IPv4 to UDPv4 map.write(buf)".write(buf) } Error::NoEntry(SupportedChannel::UdpToChan66) => { - "No entry in UDPv6 to channel IPv6 map" + "No entry in UDPv6 to channel IPv6 map.write(buf)".write(buf) } Error::NoEntry(SupportedChannel::ChanToUdp66) => { - "No entry in channel IPv6 to UDPv6 map" + "No entry in channel IPv6 to UDPv6 map.write(buf)".write(buf) } Error::UnsupportedChannel(UnsupportedChannel::UdpToChan46) => { - "Relaying UDPv4 to channel IPv6 is not supported" + "Relaying UDPv4 to channel IPv6 is not supported.write(buf)".write(buf) } Error::UnsupportedChannel(UnsupportedChannel::ChanToUdp46) => { - "Relaying channel IPv4 to UDPv6 is not supported" + "Relaying channel IPv4 to UDPv6 is not supported.write(buf)".write(buf) } Error::UnsupportedChannel(UnsupportedChannel::UdpToChan64) => { - "Relaying UDPv6 to channel IPv4 is not supported" + "Relaying UDPv6 to channel IPv4 is not supported.write(buf)".write(buf) } Error::UnsupportedChannel(UnsupportedChannel::ChanToUdp64) => { - "Relaying channel IPv6 to UDPv4 is not supported" + "Relaying channel IPv6 to UDPv4 is not supported.write(buf)".write(buf) } - Error::XdpLoadBytesFailed => "Failed to load bytes", - Error::XdpAdjustHeadFailed => "Failed to adjust head", - Error::XdpStoreBytesFailed => "Failed to store bytes", - }; + Error::XdpLoadBytesFailed(ret) => { + let mut written = 0; - msg.write(buf) + written += "Failed to load bytes: ".write(buf)?.get(); + written += ret.write(buf)?.get(); + + NonZeroUsize::new(written) + } + Error::XdpAdjustHeadFailed(ret) => { + let mut written = 0; + + written += "Failed to adjust head: ".write(buf)?.get(); + written += ret.write(buf)?.get(); + + NonZeroUsize::new(written) + } + Error::XdpStoreBytesFailed(ret) => { + let mut written = 0; + + written += "Failed to store bytes: ".write(buf)?.get(); + written += ret.write(buf)?.get(); + + NonZeroUsize::new(written) + } + } } } diff --git a/rust/relay/ebpf-turn-router/src/main.rs b/rust/relay/ebpf-turn-router/src/main.rs index 01b17f07a..787ff157b 100644 --- a/rust/relay/ebpf-turn-router/src/main.rs +++ b/rust/relay/ebpf-turn-router/src/main.rs @@ -85,9 +85,9 @@ pub fn handle_turn(ctx: XdpContext) -> u32 { } Error::BadChannelDataLength - | Error::XdpStoreBytesFailed - | Error::XdpAdjustHeadFailed - | Error::XdpLoadBytesFailed => { + | Error::XdpStoreBytesFailed(_) + | Error::XdpAdjustHeadFailed(_) + | Error::XdpLoadBytesFailed(_) => { debug!(&ctx, "Dropping packet: {}", e); xdp_action::XDP_DROP diff --git a/rust/relay/ebpf-turn-router/src/move_headers.rs b/rust/relay/ebpf-turn-router/src/move_headers.rs index 6810c7a52..93017e71f 100644 --- a/rust/relay/ebpf-turn-router/src/move_headers.rs +++ b/rust/relay/ebpf-turn-router/src/move_headers.rs @@ -24,8 +24,9 @@ pub fn add_channel_data_header_ipv4(ctx: &XdpContext, mut header: [u8; 4]) -> Re let header_ptr = &mut header as *mut _ as *mut c_void; let header_len = CdHdr::LEN as u32; - if unsafe { bpf_xdp_store_bytes(ctx.ctx, offset, header_ptr, header_len) } < 0 { - return Err(Error::XdpStoreBytesFailed); + let ret = unsafe { bpf_xdp_store_bytes(ctx.ctx, offset, header_ptr, header_len) }; + if ret < 0 { + return Err(Error::XdpStoreBytesFailed(ret)); } Ok(()) @@ -44,8 +45,9 @@ pub fn add_channel_data_header_ipv6(ctx: &XdpContext, mut header: [u8; 4]) -> Re let header_ptr = &mut header as *mut _ as *mut c_void; let header_len = CdHdr::LEN as u32; - if unsafe { bpf_xdp_store_bytes(ctx.ctx, offset, header_ptr, header_len) } < 0 { - return Err(Error::XdpStoreBytesFailed); + let ret = unsafe { bpf_xdp_store_bytes(ctx.ctx, offset, header_ptr, header_len) }; + if ret < 0 { + return Err(Error::XdpStoreBytesFailed(ret)); } Ok(()) @@ -68,17 +70,20 @@ fn move_headers( let headers_len = (EthHdr::LEN + IP_HEADER_LEN + UdpHdr::LEN) as u32; // Copy headers into buffer. - if unsafe { bpf_xdp_load_bytes(ctx.ctx, 0, headers_ptr, headers_len) } < 0 { - return Err(Error::XdpLoadBytesFailed); + let ret = unsafe { bpf_xdp_load_bytes(ctx.ctx, 0, headers_ptr, headers_len) }; + if ret < 0 { + return Err(Error::XdpLoadBytesFailed(ret)); } - if unsafe { bpf_xdp_adjust_head(ctx.ctx, DELTA) } < 0 { - return Err(Error::XdpAdjustHeadFailed); + let ret = unsafe { bpf_xdp_adjust_head(ctx.ctx, DELTA) }; + if ret < 0 { + return Err(Error::XdpAdjustHeadFailed(ret)); } // Copy the headers back. - if unsafe { bpf_xdp_store_bytes(ctx.ctx, 0, headers_ptr, headers_len) } < 0 { - return Err(Error::XdpStoreBytesFailed); + let ret = unsafe { bpf_xdp_store_bytes(ctx.ctx, 0, headers_ptr, headers_len) }; + if ret < 0 { + return Err(Error::XdpStoreBytesFailed(ret)); } Ok(())