arp: Do not fill cache from random packets.
On paper this looks great, and in a sane network it should work. However the world out there is full of horribly broken, screwed up networks, which *of course* ruin this. I've seen a customer's network where the router is IP 192.168.1.1, MAC addr xx:03. However, every 1 minute the router broadcasts some "mikrotik discovery" UDP garbage with source IP 192.168.1.1, source MAC addr xx:02 (one less!). This accidentally poisons smoltcp's ARP cache, which then sends all traffic for the default gateway to xx:02, which unsurprisingly blackholes it. And, of course, the broadcast is every 1min and the ARP cache lifetime is 1min. This means the cache is almsot all the time poisoned, and the smoltcp device barely works. Fantastic. Screw you mikrotik.master
parent
6fee12dcee
commit
f98a89ba61
|
@ -952,43 +952,12 @@ impl<'a> InterfaceInner<'a> {
|
|||
#[cfg(feature = "proto-ipv4")]
|
||||
EthernetProtocol::Ipv4 => {
|
||||
let ipv4_packet = Ipv4Packet::new_checked(eth_frame.payload())?;
|
||||
if eth_frame.src_addr().is_unicast() && ipv4_packet.src_addr().is_unicast() {
|
||||
// Fill the neighbor cache from IP header of unicast frames.
|
||||
let ip_addr = IpAddress::Ipv4(ipv4_packet.src_addr());
|
||||
if self.in_same_network(&ip_addr) {
|
||||
self.neighbor_cache.as_mut().unwrap().fill(
|
||||
ip_addr,
|
||||
eth_frame.src_addr(),
|
||||
cx.now,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.process_ipv4(cx, sockets, &ipv4_packet)
|
||||
.map(|o| o.map(EthernetPacket::Ip))
|
||||
}
|
||||
#[cfg(feature = "proto-ipv6")]
|
||||
EthernetProtocol::Ipv6 => {
|
||||
let ipv6_packet = Ipv6Packet::new_checked(eth_frame.payload())?;
|
||||
if eth_frame.src_addr().is_unicast() && ipv6_packet.src_addr().is_unicast() {
|
||||
// Fill the neighbor cache from IP header of unicast frames.
|
||||
let ip_addr = IpAddress::Ipv6(ipv6_packet.src_addr());
|
||||
if self.in_same_network(&ip_addr)
|
||||
&& self
|
||||
.neighbor_cache
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.lookup(&ip_addr, cx.now)
|
||||
.found()
|
||||
{
|
||||
self.neighbor_cache.as_mut().unwrap().fill(
|
||||
ip_addr,
|
||||
eth_frame.src_addr(),
|
||||
cx.now,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.process_ipv6(cx, sockets, &ipv6_packet)
|
||||
.map(|o| o.map(EthernetPacket::Ip))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue