Prechádzať zdrojové kódy

Merge #710

710: Fix panic when using IPv4 fragmentation with Layer 3 networks. r=Dirbaio a=KOLANICH

```console
7:     0x7fe44617f300 - smoltcp::iface::interface::InterfaceInner::lookup_hardware_addr::h640efcd865d49106
						at ~/sio-smoltcp/smoltcp/src/iface/interface/mod.rs:2007:15
18:     0x7fe44618039a - smoltcp::iface::interface::InterfaceInner::dispatch_ip::h477a4410ea082342
						at ~/sio-smoltcp/smoltcp/src/iface/interface/mod.rs:2133:19
19:     0x7fe44617cd0f - smoltcp::iface::interface::Interface::socket_egress::{{closure}}::h0b25e0ce461b54e7
						at ~/sio-smoltcp/smoltcp/src/iface/interface/mod.rs:1241:17
20:     0x7fe44617d346 - smoltcp::iface::interface::Interface::socket_egress::{{closure}}::h3e55a2ce63c16877
						at ~/sio-smoltcp/smoltcp/src/iface/interface/mod.rs:1274:21
21:     0x7fe4461a24b4 - smoltcp::socket::udp::Socket::dispatch::{{closure}}::h52b2f159c6047eb1
						at ~/sio-smoltcp/smoltcp/src/socket/udp.rs:465:13
22:     0x7fe4461a4fa8 - smoltcp::storage::packet_buffer::PacketBuffer<H>::dequeue_with::{{closure}}::{{closure}}::ha53ebbf3d6d0e373
						at ~/sio-smoltcp/smoltcp/src/storage/packet_buffer.rs:200:27
23:     0x7fe446185b41 - smoltcp::storage::ring_buffer::RingBuffer<T>::dequeue_many_with::h4769dc1f2ccd50aa
						at ~/sio-smoltcp/smoltcp/src/storage/ring_buffer.rs:245:30
24:     0x7fe4461a4b16 - smoltcp::storage::packet_buffer::PacketBuffer<H>::dequeue_with::{{closure}}::h9789743e8966cfbe
						at ~/sio-smoltcp/smoltcp/src/storage/packet_buffer.rs:196:13
25:     0x7fe4461851cd - smoltcp::storage::ring_buffer::RingBuffer<T>::dequeue_one_with::h1201370f614614d2
						at ~/sio-smoltcp/smoltcp/src/storage/ring_buffer.rs:154:19
26:     0x7fe4461a494c - smoltcp::storage::packet_buffer::PacketBuffer<H>::dequeue_with::h62d428db6c52466d
						at ~/sio-smoltcp/smoltcp/src/storage/packet_buffer.rs:190:9
27:     0x7fe4461a1ca6 - smoltcp::socket::udp::Socket::dispatch::h3345cb3f2e0a28c5
						at ~/sio-smoltcp/smoltcp/src/socket/udp.rs:431:19
28:     0x7fe44617c75e - smoltcp::iface::interface::Interface::socket_egress::h4832c80b5e44260b
						at ~/sio-smoltcp/smoltcp/src/iface/interface/mod.rs:1273:40
29:     0x7fe44617b8b4 - smoltcp::iface::interface::Interface::poll::h3576f55b9ff8b575
						at ~/sio-smoltcp/smoltcp/src/iface/interface/mod.rs:1088:31
```

Co-authored-by: KOLANICH <kolan_n@mail.ru>
bors[bot] 2 rokov pred
rodič
commit
b7a7c4b1c5
2 zmenil súbory, kde vykonal 27 pridanie a 9 odobranie
  1. 1 0
      src/iface/interface/ipv4.rs
  2. 26 9
      src/iface/interface/mod.rs

+ 1 - 0
src/iface/interface/ipv4.rs

@@ -466,6 +466,7 @@ impl<'a> InterfaceInner<'a> {
         }
 
         // Emit function for the Ethernet header.
+        #[cfg(feature = "medium-ethernet")]
         let emit_ethernet = |repr: &IpRepr, tx_buffer: &mut [u8]| {
             let mut frame = EthernetFrame::new_unchecked(tx_buffer);
 

+ 26 - 9
src/iface/interface/mod.rs

@@ -91,6 +91,7 @@ pub(crate) struct Ipv4OutPacket<'a> {
     /// The IPv4 representation.
     repr: Ipv4Repr,
     /// The destination hardware address.
+    #[cfg(feature = "medium-ethernet")]
     dst_hardware_addr: EthernetAddress,
     /// The offset of the next fragment.
     frag_offset: u16,
@@ -112,6 +113,7 @@ impl<'a> Ipv4OutPacket<'a> {
                 payload_len: 0,
                 hop_limit: 0,
             },
+            #[cfg(feature = "medium-ethernet")]
             dst_hardware_addr: EthernetAddress::default(),
             frag_offset: 0,
             ident: 0,
@@ -141,7 +143,10 @@ impl<'a> Ipv4OutPacket<'a> {
             payload_len: 0,
             hop_limit: 0,
         };
-        self.dst_hardware_addr = EthernetAddress::default();
+        #[cfg(feature = "medium-ethernet")]
+        {
+            self.dst_hardware_addr = EthernetAddress::default();
+        }
     }
 }
 
@@ -2129,12 +2134,20 @@ impl<'a> InterfaceInner<'a> {
 
         // If the medium is Ethernet, then we need to retrieve the destination hardware address.
         #[cfg(feature = "medium-ethernet")]
-        let (dst_hardware_addr, tx_token) =
-            match self.lookup_hardware_addr(tx_token, &ip_repr.src_addr(), &ip_repr.dst_addr())? {
-                (HardwareAddress::Ethernet(addr), tx_token) => (addr, tx_token),
-                #[cfg(feature = "medium-ieee802154")]
-                (HardwareAddress::Ieee802154(_), _) => unreachable!(),
-            };
+        let (dst_hardware_addr, tx_token) = match self.caps.medium {
+            Medium::Ethernet => {
+                match self.lookup_hardware_addr(
+                    tx_token,
+                    &ip_repr.src_addr(),
+                    &ip_repr.dst_addr(),
+                )? {
+                    (HardwareAddress::Ethernet(addr), tx_token) => (addr, tx_token),
+                    #[cfg(feature = "medium-ieee802154")]
+                    (HardwareAddress::Ieee802154(_), _) => unreachable!(),
+                }
+            }
+            _ => (EthernetAddress([0; 6]), tx_token),
+        };
 
         // Emit function for the Ethernet header.
         #[cfg(feature = "medium-ethernet")]
@@ -2186,7 +2199,8 @@ impl<'a> InterfaceInner<'a> {
                             repr: out_packet_repr,
                             frag_offset,
                             ident,
-                            dst_hardware_addr: dst_address,
+                            #[cfg(feature = "medium-ethernet")]
+                                dst_hardware_addr: dst_address,
                         } = &mut _out_packet.unwrap().ipv4_out_packet;
 
                         // Calculate how much we will send now (including the Ethernet header).
@@ -2203,7 +2217,10 @@ impl<'a> InterfaceInner<'a> {
                             return Err(Error::Exhausted);
                         }
 
-                        *dst_address = dst_hardware_addr;
+                        #[cfg(feature = "medium-ethernet")]
+                        {
+                            *dst_address = dst_hardware_addr;
+                        }
 
                         // Save the total packet len (without the Ethernet header, but with the first
                         // IP header).