@@ -1065,6 +1065,76 @@ fn test_raw_socket_with_udp_socket(#[case] medium: Medium) {
10651065 ) ;
10661066}
10671067
1068+ #[ rstest]
1069+ #[ case( Medium :: Ip ) ]
1070+ #[ cfg( all(
1071+ feature = "socket-raw" ,
1072+ feature = "proto-ipv4-fragmentation" ,
1073+ feature = "medium-ip"
1074+ ) ) ]
1075+ #[ case( Medium :: Ethernet ) ]
1076+ #[ cfg( all(
1077+ feature = "socket-raw" ,
1078+ feature = "proto-ipv4-fragmentation" ,
1079+ feature = "medium-ethernet"
1080+ ) ) ]
1081+ fn test_raw_socket_tx_fragmentation ( #[ case] medium : Medium ) {
1082+ use std:: panic:: AssertUnwindSafe ;
1083+
1084+ let ( mut iface, mut sockets, device) = setup ( medium) ;
1085+ let mtu = device. capabilities ( ) . max_transmission_unit ;
1086+
1087+ let packets = 5 ;
1088+ let rx_buffer = raw:: PacketBuffer :: new (
1089+ vec ! [ raw:: PacketMetadata :: EMPTY ; packets] ,
1090+ vec ! [ 0 ; mtu * packets] ,
1091+ ) ;
1092+ let tx_buffer = raw:: PacketBuffer :: new (
1093+ vec ! [ raw:: PacketMetadata :: EMPTY ; packets] ,
1094+ vec ! [ 0 ; mtu * packets] ,
1095+ ) ;
1096+ let socket = raw:: Socket :: new (
1097+ Some ( IpVersion :: Ipv4 ) ,
1098+ Some ( IpProtocol :: Udp ) ,
1099+ rx_buffer,
1100+ tx_buffer,
1101+ ) ;
1102+ let _handle = sockets. add ( socket) ;
1103+
1104+ let tx_packet_sizes = vec ! [
1105+ mtu * 3 / 4 , // Smaller than MTU
1106+ mtu * 5 / 4 , // Larger than MTU, requires fragmentation
1107+ mtu * 9 / 4 , // Much larger, requires two fragments
1108+ ] ;
1109+ for packet_size in tx_packet_sizes {
1110+ let payload_len = packet_size - IPV4_HEADER_LEN ;
1111+ let payload = vec ! [ 0u8 ; payload_len] ;
1112+
1113+ let ip_repr = Ipv4Repr {
1114+ src_addr : Ipv4Address :: new ( 192 , 168 , 1 , 3 ) ,
1115+ dst_addr : Ipv4Address :: BROADCAST ,
1116+ next_header : IpProtocol :: Unknown ( 92 ) ,
1117+ hop_limit : 64 ,
1118+ payload_len,
1119+ } ;
1120+ let ip_payload = IpPayload :: Raw ( & payload) ;
1121+ let packet = Packet :: new_ipv4 ( ip_repr, ip_payload) ;
1122+
1123+ // This should not panic for any payload size
1124+ let result = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
1125+ iface. inner . dispatch_ip (
1126+ MockTxToken { } ,
1127+ PacketMeta :: default ( ) ,
1128+ packet,
1129+ & mut iface. fragmenter ,
1130+ )
1131+ } ) ) ;
1132+
1133+ // All transmissions should succeed without panicking
1134+ assert ! ( result. is_ok( ) , "Failed for packet size: {}" , packet_size, ) ;
1135+ }
1136+ }
1137+
10681138#[ rstest]
10691139#[ case( Medium :: Ip ) ]
10701140#[ cfg( all( feature = "socket-udp" , feature = "medium-ip" ) ) ]
0 commit comments