diff --git a/repos/os/src/server/nic_router/dhcp_server.h b/repos/os/src/server/nic_router/dhcp_server.h index 6da911cfed..af0af9fbbb 100644 --- a/repos/os/src/server/nic_router/dhcp_server.h +++ b/repos/os/src/server/nic_router/dhcp_server.h @@ -92,6 +92,7 @@ class Net::Dhcp_server : private Genode::Noncopyable ***************/ Ipv4_address const &dns_server() const; + Domain &dns_server_from() { return _dns_server_from(); } Genode::Microseconds ip_lease_time() const { return _ip_lease_time; } }; diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 95c2f2a79c..0932c56248 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -146,6 +146,11 @@ void Domain::_ip_config_changed() _interfaces.for_each([&] (Interface &interface) { interface.detach_from_ip_config(); }); + _ip_config_dependents.for_each([&] (Domain &domain) { + domain._interfaces.for_each([&] (Interface &interface) { + interface.detach_from_remote_ip_config(); + }); + }); /* log the change */ if (_config.verbose_domain_state()) { if (!ip_config().valid) { @@ -206,10 +211,14 @@ void Domain::init(Domain_tree &domains) log("[", *this, "] cannot be DHCP server and client at the same time"); throw Invalid(); } - _dhcp_server = *new (_alloc) + Dhcp_server &dhcp_server = *new (_alloc) Dhcp_server(dhcp_server_node, _alloc, ip_config().interface, domains); + 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()); } } diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index 29f063ba8f..a0c2d3449d 100644 --- a/repos/os/src/server/nic_router/domain.h +++ b/repos/os/src/server/nic_router/domain.h @@ -78,7 +78,8 @@ class Net::Domain_base }; -class Net::Domain : public Domain_base +class Net::Domain : public Domain_base, + public List::Element { private: @@ -86,25 +87,26 @@ class Net::Domain : public Domain_base Configuration &_config; Genode::Xml_node _node; Genode::Allocator &_alloc; - Ip_rule_list _ip_rules { }; - Forward_rule_tree _tcp_forward_rules { }; - Forward_rule_tree _udp_forward_rules { }; - Transport_rule_list _tcp_rules { }; - Transport_rule_list _udp_rules { }; - Port_allocator _tcp_port_alloc { }; - Port_allocator _udp_port_alloc { }; - Nat_rule_tree _nat_rules { }; - Interface_list _interfaces { }; - unsigned long _interface_cnt { 0 }; - Pointer _dhcp_server { }; + Ip_rule_list _ip_rules { }; + Forward_rule_tree _tcp_forward_rules { }; + Forward_rule_tree _udp_forward_rules { }; + Transport_rule_list _tcp_rules { }; + Transport_rule_list _udp_rules { }; + Port_allocator _tcp_port_alloc { }; + Port_allocator _udp_port_alloc { }; + Nat_rule_tree _nat_rules { }; + Interface_list _interfaces { }; + unsigned long _interface_cnt { 0 }; + Pointer _dhcp_server { }; Genode::Reconstructible _ip_config; - Arp_cache _arp_cache { *this }; - Arp_waiter_list _foreign_arp_waiters { }; - Link_side_tree _tcp_links { }; - Link_side_tree _udp_links { }; - Genode::size_t _tx_bytes { 0 }; - Genode::size_t _rx_bytes { 0 }; - bool const _verbose_packets { false }; + List _ip_config_dependents { }; + Arp_cache _arp_cache { *this }; + Arp_waiter_list _foreign_arp_waiters { }; + Link_side_tree _tcp_links { }; + Link_side_tree _udp_links { }; + Genode::size_t _tx_bytes { 0 }; + Genode::size_t _rx_bytes { 0 }; + bool const _verbose_packets { false }; void _read_forward_rules(Genode::Cstring const &protocol, Domain_tree &domains, @@ -170,6 +172,7 @@ class Net::Domain : public Domain_base bool verbose_packets() const { return _verbose_packets; } Ipv4_config const &ip_config() const { return *_ip_config; } + List &ip_config_dependents() { return _ip_config_dependents; } Domain_name const &name() const { return _name; } Ip_rule_list &ip_rules() { return _ip_rules; } Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; } diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index a31c62bd39..83173c3676 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -309,6 +309,13 @@ void Interface::detach_from_ip_config() } +void Interface::detach_from_remote_ip_config() +{ + /* only the DNS server address of the local DHCP server can be remote */ + Signal_transmitter(_link_state_sigh).submit(); +} + + void Interface::_detach_from_domain() { try { diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 3db14c124d..07f4251e0f 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -318,6 +318,8 @@ class Net::Interface : private Interface_list::Element void detach_from_ip_config(); + void detach_from_remote_ip_config(); + bool link_state(); void link_state_sigh(Genode::Signal_context_capability sigh);