mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
nic_router: clear ARP cache when domain is down
Whenever a domain looses all its interfaces or the link state of all attached interfaces is down at once, the domain potentially moves to another Ethernet segment and should therefore consider its ARP cache to be outdated. RFC 826 states that "... If a host moves, any connections initiated by that host will work, assuming its own address resolution table is cleared when it moves. ...". Therefore, this commit introduces clearing the ARP cache and the initially stated events. This commit was motivated by an issue with the PinePhone Modem and USB NIC. On the PinePhone, the Modem has its own OS and acts as direct gateway to the outer world for the USB NIC that is driven by Genode. However, whenever the Modem gets restarted, Modem and USB NIC receive a new MAC address. This used to conflict with the NIC routers ARP entry for the Modem that didn't cease to be valid. With this commit, the integrator of such a scenario at least has a convenient way of fixing this by ensuring that all interfaces at the USB NIC domain go down when resetting (e.g. by ensuring that the USB NIC is the only interface at that domain). Fixes #4558
This commit is contained in:
parent
64c81e2846
commit
d5b1d9466a
@ -105,3 +105,17 @@ void Arp_cache::destroy_entries_with_mac(Mac_address const &mac)
|
||||
} catch (Arp_cache_entry_slot::Deref_unconstructed_object) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Arp_cache::destroy_all_entries()
|
||||
{
|
||||
if (_domain.config().verbose()) {
|
||||
log("[", _domain, "] destroy all ARP entries");
|
||||
}
|
||||
while (Arp_cache_entry *entry = first()) {
|
||||
remove(entry);
|
||||
}
|
||||
for (unsigned curr = 0; curr < NR_OF_ENTRIES; curr++) {
|
||||
_entries[curr].destruct();
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ class Net::Arp_cache : public Genode::Avl_tree<Arp_cache_entry>
|
||||
void destroy_entries_with_mac(Mac_address const &mac);
|
||||
|
||||
Arp_cache_entry const &find_by_ip(Ipv4_address const &ip) const;
|
||||
|
||||
void destroy_all_entries();
|
||||
};
|
||||
|
||||
#endif /* _ARP_CACHE_H_ */
|
||||
|
@ -364,9 +364,12 @@ void Domain::detach_interface(Interface &interface)
|
||||
{
|
||||
_interfaces.remove(&interface);
|
||||
_interface_cnt--;
|
||||
if (!_interface_cnt && _ip_config_dynamic) {
|
||||
if (!_interface_cnt) {
|
||||
_arp_cache.destroy_all_entries();
|
||||
if (_ip_config_dynamic) {
|
||||
discard_ip_config();
|
||||
}
|
||||
}
|
||||
if (_config.verbose_domain_state()) {
|
||||
log("[", *this, "] NIC sessions: ", _interface_cnt);
|
||||
}
|
||||
|
@ -930,6 +930,7 @@ void Interface::handle_interface_link_state()
|
||||
throw Keep_ip_config(); }
|
||||
});
|
||||
domain_.discard_ip_config();
|
||||
domain_.arp_cache().destroy_all_entries();
|
||||
}
|
||||
}
|
||||
catch (Pointer<Domain>::Invalid) { }
|
||||
|
Loading…
Reference in New Issue
Block a user