From 7a7cac57d9f4b5523e40f46a28fa858eb08f4e2c Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 8 Nov 2022 13:58:26 +0100 Subject: [PATCH] nic_router: futile ip config updates on dhcp renew If the IP config does not change on updates to the router IP config of a domain change (a common case on DHCP RENEW), prevent detaching from the old config and attaching to the new one. Because this would not only create unnecessary CPU overhead but also force all clients at all interfaces that are listening to this config (via config attribute 'dns_config_from') to restart their networking (re-do DHCP). Ref #4696 --- repos/os/src/server/nic_router/domain.cc | 13 ++++++++++- repos/os/src/server/nic_router/ipv4_config.cc | 22 ++++++++++++++++++- repos/os/src/server/nic_router/ipv4_config.h | 7 ++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 25b5001c90..e6e966f167 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -118,8 +118,19 @@ void Domain::discard_ip_config() void Domain::ip_config_from_dhcp_ack(Dhcp_packet &dhcp_ack) { + /* + * If the IP config didn't change (a common case on DHCP RENEW), prevent + * detaching from the old config and attaching to the new one. Because this + * would not only create unnecessary CPU overhead but also force all + * clients at all interfaces that are listening to this config (via config + * attribute 'dns_config_from') to restart their networking (re-do DHCP). + */ + Ipv4_config const new_ip_config { dhcp_ack, _alloc, *this }; + if (*_ip_config == new_ip_config) { + return; + } _reconstruct_ip_config([&] (Reconstructible &ip_config) { - ip_config.construct(dhcp_ack, _alloc, *this); }); + ip_config.construct(new_ip_config); }); } diff --git a/repos/os/src/server/nic_router/ipv4_config.cc b/repos/os/src/server/nic_router/ipv4_config.cc index 8234e3ebff..00a131e807 100644 --- a/repos/os/src/server/nic_router/ipv4_config.cc +++ b/repos/os/src/server/nic_router/ipv4_config.cc @@ -49,7 +49,27 @@ Ipv4_config::Ipv4_config(Ipv4_config const &ip_config, { ip_config.for_each_dns_server([&] (Dns_server const &dns_server) { Dns_server::construct( - alloc, dns_server.ip(), + _alloc, dns_server.ip(), + [&] /* handle_success */ (Dns_server &server) + { + _dns_servers.insert_as_tail(server); + }, + [&] /* handle_failure */ () { } + ); + }); + _dns_domain_name.set_to(ip_config.dns_domain_name()); +} + + +Ipv4_config::Ipv4_config(Ipv4_config const &ip_config) +: + _alloc { ip_config._alloc }, + _interface { ip_config._interface }, + _gateway { ip_config._gateway } +{ + ip_config.for_each_dns_server([&] (Dns_server const &dns_server) { + Dns_server::construct( + _alloc, dns_server.ip(), [&] /* handle_success */ (Dns_server &server) { _dns_servers.insert_as_tail(server); diff --git a/repos/os/src/server/nic_router/ipv4_config.h b/repos/os/src/server/nic_router/ipv4_config.h index a505b11356..2c3ca3d34b 100644 --- a/repos/os/src/server/nic_router/ipv4_config.h +++ b/repos/os/src/server/nic_router/ipv4_config.h @@ -59,6 +59,8 @@ class Net::Ipv4_config Ipv4_config(Ipv4_config const &ip_config, Genode::Allocator &alloc); + Ipv4_config(Ipv4_config const &ip_config); + Ipv4_config(Genode::Allocator &alloc); ~Ipv4_config(); @@ -71,6 +73,11 @@ class Net::Ipv4_config !_dns_domain_name.equal_to(other._dns_domain_name); } + bool operator == (Ipv4_config const &other) const + { + return !(*this != other); + } + template void for_each_dns_server(FUNC && func) const {