nic_router: get DNS server from dynamic IP config

If available, read and remember DNS server address from DHCP replies per
domain.

Issue #2730
This commit is contained in:
Martin Stein 2018-03-23 00:30:04 +01:00 committed by Christian Helmuth
parent 04c3ae56ed
commit fec53690d7
5 changed files with 34 additions and 21 deletions

View File

@ -138,17 +138,21 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp)
break;
case State::REQUEST:
if (msg_type != Message_type::ACK) {
throw Drop_packet_inform("DHCP client expects an acknowledgement");
{
if (msg_type != Message_type::ACK) {
throw Drop_packet_inform("DHCP client expects an acknowledgement");
}
_lease_time_sec = dhcp.option<Dhcp_packet::Ip_lease_time>().value();
_set_state(State::BOUND, _rerequest_timeout(1));
Ipv4_address dns_server;
try { dns_server = dhcp.option<Dhcp_packet::Dns_server_ipv4>().value(); }
catch (Dhcp_packet::Option_not_found) { }
_domain().ip_config(dhcp.yiaddr(),
dhcp.option<Dhcp_packet::Subnet_mask>().value(),
dhcp.option<Dhcp_packet::Router_ipv4>().value(),
dns_server);
break;
}
_lease_time_sec = dhcp.option<Dhcp_packet::Ip_lease_time>().value();
_set_state(State::BOUND, _rerequest_timeout(1));
_domain().ip_config(dhcp.yiaddr(),
dhcp.option<Dhcp_packet::Subnet_mask>().value(),
dhcp.option<Dhcp_packet::Router_ipv4>().value());
break;
case State::RENEW:
case State::REBIND:

View File

@ -51,9 +51,11 @@ Domain_base::Domain_base(Xml_node const node)
void Domain::ip_config(Ipv4_address ip,
Ipv4_address subnet_mask,
Ipv4_address gateway)
Ipv4_address gateway,
Ipv4_address dns_server)
{
_ip_config.construct(Ipv4_address_prefix(ip, subnet_mask), gateway);
_ip_config.construct(Ipv4_address_prefix(ip, subnet_mask), gateway,
dns_server);
_ip_config_changed();
}
@ -109,8 +111,9 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
:
Domain_base(node), _avl_member(_name, *this), _config(config),
_node(node), _alloc(alloc),
_ip_config(_node.attribute_value("interface", Ipv4_address_prefix()),
_node.attribute_value("gateway", Ipv4_address())),
_ip_config(_node.attribute_value("interface", Ipv4_address_prefix()),
_node.attribute_value("gateway", Ipv4_address()),
Ipv4_address()),
_verbose_packets(_node.attribute_value("verbose_packets", false) ||
_config.verbose_packets())
{
@ -151,7 +154,8 @@ void Domain::_ip_config_changed()
} else {
log("[", *this, "] IP config:"
" interface ", ip_config().interface,
", gateway ", ip_config().gateway);
", gateway ", ip_config().gateway,
", DNS server ", ip_config().dns_server);
}
}
}

View File

@ -139,7 +139,8 @@ class Net::Domain : public Domain_base
void ip_config(Ipv4_address ip,
Ipv4_address subnet_mask,
Ipv4_address gateway);
Ipv4_address gateway,
Ipv4_address dns_server);
void discard_ip_config();

View File

@ -21,9 +21,10 @@ using namespace Genode;
using namespace Net;
Ipv4_config::Ipv4_config(Ipv4_address_prefix interface,
Ipv4_address gateway)
Ipv4_address gateway,
Ipv4_address dns_server)
:
interface(interface), gateway(gateway)
interface(interface), gateway(gateway), dns_server(dns_server)
{
if (!valid && (interface_valid || gateway_valid)) {
error("Bad IP configuration");

View File

@ -25,19 +25,22 @@ struct Net::Ipv4_config
bool const interface_valid { interface.valid() };
Ipv4_address const gateway { };
bool const gateway_valid { gateway.valid() };
Ipv4_address const dns_server { };
bool const valid { interface_valid &&
(!gateway_valid ||
interface.prefix_matches(gateway)) };
Ipv4_config(Ipv4_address_prefix interface,
Ipv4_address gateway);
Ipv4_address gateway,
Ipv4_address dns_server);
Ipv4_config() { }
bool operator != (Ipv4_config const &other) const
{
return interface != other.interface ||
gateway != other.gateway;
return interface != other.interface ||
gateway != other.gateway ||
dns_server != other.dns_server;
}
};