Skip to content

Commit

Permalink
Merge pull request #1008 from Jc0x7D3/main
Browse files Browse the repository at this point in the history
Fix the error of specific length IP packets not being fragmented
  • Loading branch information
Dirbaio authored Nov 2, 2024
2 parents e9b66ea + aba9add commit 3e61c90
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/iface/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ impl InterfaceInner {
#[cfg(feature = "proto-ipv4")]
IpRepr::Ipv4(repr) => {
// If we have an IPv4 packet, then we need to check if we need to fragment it.
if total_ip_len > self.caps.max_transmission_unit {
if total_ip_len > self.caps.ip_mtu() {
#[cfg(feature = "proto-ipv4-fragmentation")]
{
net_debug!("start fragmentation");
Expand Down
76 changes: 76 additions & 0 deletions src/iface/interface/tests/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,82 @@ fn test_handle_igmp(#[case] medium: Medium) {
}
}

#[rstest]
#[case(Medium::Ip)]
#[cfg(all(feature = "proto-ipv4-fragmentation", feature = "medium-ip"))]
#[case(Medium::Ethernet)]
#[cfg(all(feature = "proto-ipv4-fragmentation", feature = "medium-ethernet"))]
fn test_packet_len(#[case] medium: Medium) {
use crate::config::FRAGMENTATION_BUFFER_SIZE;

let (mut iface, _, _) = setup(medium);

struct TestTxToken {
max_transmission_unit: usize,
}

impl TxToken for TestTxToken {
fn consume<R, F>(self, len: usize, f: F) -> R
where
F: FnOnce(&mut [u8]) -> R,
{
net_debug!("TxToken get len: {}", len);
assert!(len <= self.max_transmission_unit);
let mut junk = [0; 1536];
f(&mut junk[..len])
}
}

iface.inner.neighbor_cache.fill(
IpAddress::Ipv4(Ipv4Address::new(127, 0, 0, 1)),
HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[
0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
])),
Instant::ZERO,
);

for ip_packet_len in [
100,
iface.inner.ip_mtu(),
iface.inner.ip_mtu() + 1,
FRAGMENTATION_BUFFER_SIZE,
] {
net_debug!("ip_packet_len: {}", ip_packet_len);

let mut ip_repr = Ipv4Repr {
src_addr: Ipv4Address::new(127, 0, 0, 1),
dst_addr: Ipv4Address::new(127, 0, 0, 1),
next_header: IpProtocol::Udp,
payload_len: 0,
hop_limit: 64,
};
let udp_repr = UdpRepr {
src_port: 12345,
dst_port: 54321,
};

let ip_packet_payload_len = ip_packet_len - ip_repr.buffer_len();
let udp_packet_payload_len = ip_packet_payload_len - udp_repr.header_len();
ip_repr.payload_len = ip_packet_payload_len;

let udp_packet_payload = vec![1; udp_packet_payload_len];
let ip_payload = IpPayload::Udp(udp_repr, &udp_packet_payload);
let ip_packet = Packet::new_ipv4(ip_repr, ip_payload);

assert_eq!(
iface.inner.dispatch_ip(
TestTxToken {
max_transmission_unit: iface.inner.caps.max_transmission_unit
},
PacketMeta::default(),
ip_packet,
&mut iface.fragmenter,
),
Ok(())
);
}
}

#[rstest]
#[case(Medium::Ip)]
#[cfg(all(feature = "socket-raw", feature = "medium-ip"))]
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub mod config {
pub const DNS_MAX_NAME_SIZE: usize = 255;
pub const DNS_MAX_RESULT_COUNT: usize = 1;
pub const DNS_MAX_SERVER_COUNT: usize = 1;
pub const FRAGMENTATION_BUFFER_SIZE: usize = 1500;
pub const FRAGMENTATION_BUFFER_SIZE: usize = 4096;
pub const IFACE_MAX_ADDR_COUNT: usize = 8;
pub const IFACE_MAX_MULTICAST_GROUP_COUNT: usize = 4;
pub const IFACE_MAX_ROUTE_COUNT: usize = 4;
Expand Down

0 comments on commit 3e61c90

Please sign in to comment.