nic_router: read DHCP-server config only once

Until now, the DHCP server of a domain was re-constructed each time the
IP config changed. This is not necessary as a domain that acts as DHCP
server must have a static IP config as it would be senseless to act as
DHCP server and client at the same time. Now, a configured DHCP server
is constructed only when the Domain gets constructed and stays alive
until the domain gets destructed. Furthermore, we now throw Domain::Invalid
if there is no static IP config plus a DHCP server configured. However, by
now, this exception is not caught as it is not trivial to destruct the
domain at this point.

Issue #2730
This commit is contained in:
Martin Stein 2018-03-22 21:06:11 +01:00 committed by Christian Helmuth
parent 7d50219902
commit 04c3ae56ed
3 changed files with 32 additions and 26 deletions

View File

@ -58,12 +58,12 @@ Configuration::Configuration(Env &env,
try { _domains.insert(*new (_alloc) Domain(*this, node, _alloc)); }
catch (Domain::Invalid) { warning("invalid domain"); }
});
/* as they must resolve domain names, create rules after domains */
/* do those parts of domain init that require the domain tree to be complete */
_domains.for_each([&] (Domain &domain) {
if (_verbose) {
log("Domain: ", domain); }
domain.create_rules(_domains);
domain.init(_domains);
});
try {
/* check whether we shall create a report generator */

View File

@ -140,33 +140,20 @@ Link_side_tree &Domain::links(L3_protocol const protocol)
void Domain::_ip_config_changed()
{
/* detach all dependent interfaces from old IP config */
_interfaces.for_each([&] (Interface &interface) {
interface.detach_from_ip_config();
});
if (!ip_config().valid) {
if (_config.verbose_domain_state()) {
log("[", *this, "] IP config: none");
}
return;
}
/* log the change */
if (_config.verbose_domain_state()) {
log("[", *this, "] IP config:"
" interface ", ip_config().interface,
", gateway ", ip_config().gateway);
if (!ip_config().valid) {
log("[", *this, "] IP config: none");
} else {
log("[", *this, "] IP config:"
" interface ", ip_config().interface,
", gateway ", ip_config().gateway);
}
}
/* try to find configuration for DHCP server role */
try {
_dhcp_server = *new (_alloc)
Dhcp_server(_node.sub_node("dhcp-server"), _alloc,
ip_config().interface);
if (_config.verbose()) {
log("DHCP server at domain \"", *this, "\": ", _dhcp_server()); }
}
catch (Xml_node::Nonexistent_sub_node) { }
catch (Dhcp_server::Invalid) {
error("Invalid DHCP server configuration at domain \"", *this, "\""); }
}
@ -197,8 +184,27 @@ void Domain::__FIXME__dissolve_foreign_arp_waiters()
}
void Domain::create_rules(Domain_tree &domains)
void Domain::init(Domain_tree &domains)
{
/* read DHCP server configuration */
try {
Xml_node const dhcp_server_node = _node.sub_node("dhcp-server");
if (!ip_config().valid) {
log("[", *this, "] cannot be DHCP server and client at the same time");
throw Invalid();
}
_dhcp_server = *new (_alloc)
Dhcp_server(dhcp_server_node, _alloc, ip_config().interface);
if (_config.verbose()) {
log("[", *this, "] DHCP server: ", _dhcp_server()); }
}
catch (Xml_node::Nonexistent_sub_node) { }
catch (Dhcp_server::Invalid) {
log("[", *this, "] invalid DHCP server configuration");
throw Invalid();
}
/* read forward rules */
_read_forward_rules(tcp_name(), domains, _node, "tcp-forward",
_tcp_forward_rules);

View File

@ -133,7 +133,7 @@ class Net::Domain : public Domain_base
~Domain();
void create_rules(Domain_tree &domains);
void init(Domain_tree &domains);
Ipv4_address const &next_hop(Ipv4_address const &ip) const;