nic_router: keep dyn IP when updating domain obj

When updating the domain object of interfaces that stay with the same domain
during a reconfiguration, until now, the normal "detach raw" function was used.
This caused the old domain object to discard a dynamic IP config as all
interfaces detached. This caused interfaces also to discard network links
established with the old configuration although it wasn't necessary. Thus, now
we use a dedicated "detach" in case that an interface actually stays with its
domain. This new "detach" doesn't decrease the interface counter of the domain,
so, it'll not discard its dynamic IP config. If, however, during a
reconfiguration, there's no interface calling this function (all interfaces
move to another or no domain), the dynamic IP config is still discarded as
expected.

Fixes #3686
This commit is contained in:
Martin Stein 2020-03-09 16:23:31 +01:00 committed by Norman Feske
parent f3185de7f5
commit ba55409c86
4 changed files with 35 additions and 3 deletions

View File

@ -355,6 +355,13 @@ void Domain::detach_interface(Interface &interface)
}
}
void Domain::interface_updates_domain_object(Interface &interface)
{
_interfaces.remove(&interface);
}
void Domain::report(Xml_generator &xml)
{
xml.node("domain", [&] () {

View File

@ -179,6 +179,8 @@ class Net::Domain : public Domain_base,
void detach_interface(Interface &interface);
void interface_updates_domain_object(Interface &interface);
void raise_rx_bytes(Genode::size_t bytes) { _rx_bytes += bytes; }
void raise_tx_bytes(Genode::size_t bytes) { _tx_bytes += bytes; }

View File

@ -340,6 +340,29 @@ void Interface::_detach_from_domain_raw()
}
void Interface::_update_domain_object(Domain &new_domain) {
/* detach raw */
Domain &old_domain = _domain();
old_domain.interface_updates_domain_object(*this);
_interfaces.insert(this);
_domain = Pointer<Domain>();
Signal_transmitter(_session_link_state_sigh).submit();
old_domain.tcp_stats().dissolve_interface(_tcp_stats);
old_domain.udp_stats().dissolve_interface(_udp_stats);
old_domain.icmp_stats().dissolve_interface(_icmp_stats);
old_domain.arp_stats().dissolve_interface(_arp_stats);
old_domain.dhcp_stats().dissolve_interface(_dhcp_stats);
/* attach raw */
_domain = new_domain;
Signal_transmitter(_session_link_state_sigh).submit();
_interfaces.remove(this);
new_domain.attach_interface(*this);
}
void Interface::attach_to_domain()
{
try {
@ -1992,9 +2015,7 @@ void Interface::handle_config_2()
}
return;
}
/* move to new domain object without considering any state objects */
_detach_from_domain_raw();
_attach_to_domain_raw(new_domain);
_update_domain_object(new_domain);
/* destruct or construct DHCP client if IP-config type changes */
if (old_domain.ip_config_dynamic() &&

View File

@ -332,6 +332,8 @@ class Net::Interface : private Interface_list::Element
void _destroy_link(Link &link);
void _update_domain_object(Domain &new_domain);
void _detach_from_domain_raw();
void _detach_from_domain();