diff --git a/repos/os/src/server/nic_router/dhcp_server.cc b/repos/os/src/server/nic_router/dhcp_server.cc index 65cf000c5b..9344f091a0 100644 --- a/repos/os/src/server/nic_router/dhcp_server.cc +++ b/repos/os/src/server/nic_router/dhcp_server.cc @@ -150,9 +150,27 @@ void Dhcp_server::alloc_ip(Ipv4_address const &ip) } -void Dhcp_server::free_ip(Ipv4_address const &ip) +void Dhcp_server::free_ip(Domain const &domain, + Ipv4_address const &ip) { - _ip_alloc.free(ip.to_uint32_little_endian() - _ip_first_raw); + try { + _ip_alloc.free(ip.to_uint32_little_endian() - _ip_first_raw); + } + catch (Bit_allocator_dynamic::Out_of_indices) { + + /* + * This message is printed independent from the routers + * verbosity configuration in order to track down an exception + * of type Bit_allocator_dynamic::Out_of_indices that was + * previously not caught. We have observed this exception once, + * but without a specific use pattern that would + * enable for a systematic reproduction of the issue. + * The uncaught exception was observed in a 21.03 Sculpt OS + * with a manually configured router, re-configuration involved. + */ + log("[", domain, "] DHCP server: failed to free IP ", + ip, " (IP range: first ", _ip_first, " last ", _ip_last, ")"); + } } diff --git a/repos/os/src/server/nic_router/dhcp_server.h b/repos/os/src/server/nic_router/dhcp_server.h index 6f9888d068..c31f286178 100644 --- a/repos/os/src/server/nic_router/dhcp_server.h +++ b/repos/os/src/server/nic_router/dhcp_server.h @@ -100,7 +100,8 @@ class Net::Dhcp_server : private Genode::Noncopyable, void alloc_ip(Ipv4_address const &ip); - void free_ip(Ipv4_address const &ip); + void free_ip(Domain const &domain, + Ipv4_address const &ip); bool ready() const; diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 7b26e9379f..25e0380a2f 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -258,16 +258,42 @@ void Domain::init(Domain_tree &domains) if (_ip_config_dynamic) { _invalid("DHCP server and client at once"); } - Dhcp_server &dhcp_server = *new (_alloc) - Dhcp_server(dhcp_server_node, *this, _alloc, - ip_config().interface, domains); + try { + Dhcp_server &dhcp_server = *new (_alloc) + Dhcp_server(dhcp_server_node, *this, _alloc, + ip_config().interface, domains); - try { dhcp_server.dns_server_from().ip_config_dependents().insert(this); } - catch (Pointer::Invalid) { } + try { + dhcp_server. + dns_server_from().ip_config_dependents().insert(this); + } + catch (Pointer::Invalid) { } - _dhcp_server = dhcp_server; - if (_config.verbose()) { - log("[", *this, "] DHCP server: ", _dhcp_server()); } + _dhcp_server = dhcp_server; + if (_config.verbose()) { + log("[", *this, "] DHCP server: ", _dhcp_server()); } + } + catch (Bit_allocator_dynamic::Out_of_indices) { + + /* + * This message is printed independent from the routers + * verbosity configuration in order to track down an exception + * of type Bit_allocator_dynamic::Out_of_indices that was + * previously not caught. We have observed this exception once, + * but without a specific use pattern that would + * enable for a systematic reproduction of the issue. + * The uncaught exception was observed in a 21.03 Sculpt OS + * with a manually configured router, re-configuration involved. + */ + log("[", *this, "] DHCP server: failed to initialize ", + "(IP range: first ", + dhcp_server_node.attribute_value("ip_first", Ipv4_address()), + " last ", + dhcp_server_node.attribute_value("ip_last", Ipv4_address()), + ")"); + + throw Dhcp_server::Invalid { }; + } } catch (Xml_node::Nonexistent_sub_node) { } catch (Dhcp_server::Invalid) { _invalid("invalid DHCP server"); } diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index b5969e1cc5..6e9d3c9910 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -1488,7 +1488,7 @@ void Interface::_ready_to_ack() void Interface::_destroy_dhcp_allocation(Dhcp_allocation &allocation, Domain &local_domain) { - try { local_domain.dhcp_server().free_ip(allocation.ip()); } + try { local_domain.dhcp_server().free_ip(local_domain, allocation.ip()); } catch (Pointer::Invalid) { } destroy(_alloc, &allocation); }