mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-31 14:40:54 +00:00
nic_router: DHCP server considers dns_server_from
The dns_server_from attribute of the dhcp-server tag has effect only if the dns_server attribute of the same tag is not set. If this is the case, the dns_server_from attribute states the domain from whose IP config to take the DNS server address. This is useful, for instance, if the stated domain receives the address of a local DNS server via DHCP. Whenever the IP config of the stated domain becomes invalid, the DHCP server switches to a mode where it drops all requests unanswered until the IP config becomes valid again. Issue #2730
This commit is contained in:
parent
fec53690d7
commit
4bee38ea62
@ -292,18 +292,26 @@ this:
|
|||||||
<dhcp-server ip_first="10.0.1.80"
|
<dhcp-server ip_first="10.0.1.80"
|
||||||
ip_last="10.0.1.100"
|
ip_last="10.0.1.100"
|
||||||
ip_lease_time_sec="3600"
|
ip_lease_time_sec="3600"
|
||||||
dns_server="10.0.0.2"/>
|
dns_server="10.0.0.2"
|
||||||
|
dns_server_from="uplink" />
|
||||||
...
|
...
|
||||||
</domain>
|
</domain>
|
||||||
|
|
||||||
The attributes ip_first and ip_last define the available IPv4 address
|
The attributes ip_first and ip_last define the available IPv4 address range
|
||||||
range while ip_lease_time_sec defines the lifetime of an IPv4 address
|
while ip_lease_time_sec defines the lifetime of an IPv4 address assignment in
|
||||||
assignment in seconds. The IPv4 address range must be in the subnet
|
seconds. The IPv4 address range must be in the subnet defined by the interface
|
||||||
defined by the interface attribute of the domain tag and must not cover
|
attribute of the domain tag and must not cover the IPv4 address in this
|
||||||
the IPv4 address in this attribute. The dns_server attribute gives the
|
attribute. The dns_server attribute gives the IPv4 address of the DNS server
|
||||||
IPv4 address of the DNS server that might also be in another subnet.
|
that might also be in another subnet. The dns_server_from attribute has effect
|
||||||
The lifetime of an assignment that was yet only offered to the client
|
only if the dns_server attribute is not set. If this is the case, the
|
||||||
can be configured for all domains in the <config> tag of the router:
|
dns_server_from attribute states the domain from whose IP config to take the
|
||||||
|
DNS server address. This is useful, for instance, if the stated domain
|
||||||
|
receives the address of a local DNS server via DHCP. Whenever the IP config
|
||||||
|
of the stated domain becomes invalid, the DHCP server switches to a mode where
|
||||||
|
it drops all requests unanswered until the IP config becomes valid again.
|
||||||
|
|
||||||
|
The lifetime of an assignment that was yet only offered to the client can be
|
||||||
|
configured for all domains in the <config> tag of the router:
|
||||||
|
|
||||||
! <config dhcp_offer_timeout_sec="6">
|
! <config dhcp_offer_timeout_sec="6">
|
||||||
|
|
||||||
|
@ -131,6 +131,7 @@
|
|||||||
<xs:attribute name="ip_last" type="Ipv4_address" />
|
<xs:attribute name="ip_last" type="Ipv4_address" />
|
||||||
<xs:attribute name="ip_lease_time_sec" type="Seconds" />
|
<xs:attribute name="ip_lease_time_sec" type="Seconds" />
|
||||||
<xs:attribute name="dns_server" type="Ipv4_address" />
|
<xs:attribute name="dns_server" type="Ipv4_address" />
|
||||||
|
<xs:attribute name="dns_server_from" type="Domain_name" />
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element><!-- dhcp-server -->
|
</xs:element><!-- dhcp-server -->
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
/* local includes */
|
/* local includes */
|
||||||
#include <dhcp_server.h>
|
#include <dhcp_server.h>
|
||||||
#include <interface.h>
|
#include <interface.h>
|
||||||
|
#include <domain.h>
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -25,9 +26,11 @@ using namespace Genode;
|
|||||||
|
|
||||||
Dhcp_server::Dhcp_server(Xml_node const node,
|
Dhcp_server::Dhcp_server(Xml_node const node,
|
||||||
Allocator &alloc,
|
Allocator &alloc,
|
||||||
Ipv4_address_prefix const &interface)
|
Ipv4_address_prefix const &interface,
|
||||||
|
Domain_tree &domains)
|
||||||
:
|
:
|
||||||
_dns_server(node.attribute_value("dns_server", Ipv4_address())),
|
_dns_server(node.attribute_value("dns_server", Ipv4_address())),
|
||||||
|
_dns_server_from(_init_dns_server_from(node, domains)),
|
||||||
_ip_lease_time (_init_ip_lease_time(node)),
|
_ip_lease_time (_init_ip_lease_time(node)),
|
||||||
_ip_first(node.attribute_value("ip_first", Ipv4_address())),
|
_ip_first(node.attribute_value("ip_first", Ipv4_address())),
|
||||||
_ip_last(node.attribute_value("ip_last", Ipv4_address())),
|
_ip_last(node.attribute_value("ip_last", Ipv4_address())),
|
||||||
@ -59,8 +62,11 @@ Microseconds Dhcp_server::_init_ip_lease_time(Xml_node const node)
|
|||||||
void Dhcp_server::print(Output &output) const
|
void Dhcp_server::print(Output &output) const
|
||||||
{
|
{
|
||||||
if (_dns_server.valid()) {
|
if (_dns_server.valid()) {
|
||||||
Genode::print(output, "DNS server ", _dns_server, " ");
|
Genode::print(output, "DNS server ", _dns_server, ", ");
|
||||||
}
|
}
|
||||||
|
try { Genode::print(output, "DNS server from ", _dns_server_from(), ", "); }
|
||||||
|
catch (Pointer<Domain>::Invalid) { }
|
||||||
|
|
||||||
Genode::print(output, "IP first ", _ip_first,
|
Genode::print(output, "IP first ", _ip_first,
|
||||||
", last ", _ip_last,
|
", last ", _ip_last,
|
||||||
", count ", _ip_count,
|
", count ", _ip_count,
|
||||||
@ -94,6 +100,42 @@ void Dhcp_server::free_ip(Ipv4_address const &ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Pointer<Domain> Dhcp_server::_init_dns_server_from(Genode::Xml_node const node,
|
||||||
|
Domain_tree &domains)
|
||||||
|
{
|
||||||
|
if (_dns_server.valid()) {
|
||||||
|
return Pointer<Domain>();
|
||||||
|
}
|
||||||
|
Domain_name dns_server_from =
|
||||||
|
node.attribute_value("dns_server_from", Domain_name());
|
||||||
|
|
||||||
|
if (dns_server_from == Domain_name()) {
|
||||||
|
return Pointer<Domain>();
|
||||||
|
}
|
||||||
|
try { return domains.find_by_name(dns_server_from); }
|
||||||
|
catch (Domain_tree::No_match) { throw Invalid(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ipv4_address const &Dhcp_server::dns_server() const
|
||||||
|
{
|
||||||
|
try { return _dns_server_from().ip_config().dns_server; }
|
||||||
|
catch (Pointer<Domain>::Invalid) { }
|
||||||
|
return _dns_server;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Dhcp_server::ready() const
|
||||||
|
{
|
||||||
|
if (_dns_server.valid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try { return _dns_server_from().ip_config().valid; }
|
||||||
|
catch (Pointer<Domain>::Invalid) { }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
** Dhcp_allocation **
|
** Dhcp_allocation **
|
||||||
*********************/
|
*********************/
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <ipv4_address_prefix.h>
|
#include <ipv4_address_prefix.h>
|
||||||
#include <bit_allocator_dynamic.h>
|
#include <bit_allocator_dynamic.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
|
#include <pointer.h>
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <net/mac_address.h>
|
#include <net/mac_address.h>
|
||||||
@ -35,6 +36,8 @@ namespace Net {
|
|||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
class Interface;
|
class Interface;
|
||||||
|
class Domain;
|
||||||
|
class Domain_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -43,6 +46,7 @@ class Net::Dhcp_server : private Genode::Noncopyable
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Ipv4_address const _dns_server;
|
Ipv4_address const _dns_server;
|
||||||
|
Pointer<Domain> const _dns_server_from;
|
||||||
Genode::Microseconds const _ip_lease_time;
|
Genode::Microseconds const _ip_lease_time;
|
||||||
Ipv4_address const _ip_first;
|
Ipv4_address const _ip_first;
|
||||||
Ipv4_address const _ip_last;
|
Ipv4_address const _ip_last;
|
||||||
@ -52,6 +56,9 @@ class Net::Dhcp_server : private Genode::Noncopyable
|
|||||||
|
|
||||||
Genode::Microseconds _init_ip_lease_time(Genode::Xml_node const node);
|
Genode::Microseconds _init_ip_lease_time(Genode::Xml_node const node);
|
||||||
|
|
||||||
|
Pointer<Domain> _init_dns_server_from(Genode::Xml_node const node,
|
||||||
|
Domain_tree &domains);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum { DEFAULT_IP_LEASE_TIME_SEC = 3600 };
|
enum { DEFAULT_IP_LEASE_TIME_SEC = 3600 };
|
||||||
@ -61,7 +68,8 @@ class Net::Dhcp_server : private Genode::Noncopyable
|
|||||||
|
|
||||||
Dhcp_server(Genode::Xml_node const node,
|
Dhcp_server(Genode::Xml_node const node,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Ipv4_address_prefix const &interface);
|
Ipv4_address_prefix const &interface,
|
||||||
|
Domain_tree &domains);
|
||||||
|
|
||||||
Ipv4_address alloc_ip();
|
Ipv4_address alloc_ip();
|
||||||
|
|
||||||
@ -69,6 +77,8 @@ class Net::Dhcp_server : private Genode::Noncopyable
|
|||||||
|
|
||||||
void free_ip(Ipv4_address const &ip);
|
void free_ip(Ipv4_address const &ip);
|
||||||
|
|
||||||
|
bool ready() const;
|
||||||
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** log **
|
** log **
|
||||||
@ -81,7 +91,7 @@ class Net::Dhcp_server : private Genode::Noncopyable
|
|||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
Ipv4_address const &dns_server() const { return _dns_server; }
|
Ipv4_address const &dns_server() const;
|
||||||
Genode::Microseconds ip_lease_time() const { return _ip_lease_time; }
|
Genode::Microseconds ip_lease_time() const { return _ip_lease_time; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,7 +128,6 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
|
|||||||
if (_config.verbose_domain_state()) {
|
if (_config.verbose_domain_state()) {
|
||||||
log("[", *this, "] NIC sessions: ", _interface_cnt);
|
log("[", *this, "] NIC sessions: ", _interface_cnt);
|
||||||
}
|
}
|
||||||
_ip_config_changed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -188,6 +187,16 @@ void Domain::__FIXME__dissolve_foreign_arp_waiters()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dhcp_server &Domain::dhcp_server()
|
||||||
|
{
|
||||||
|
Dhcp_server &dhcp_server = _dhcp_server();
|
||||||
|
if (!dhcp_server.ready()) {
|
||||||
|
throw Pointer<Dhcp_server>::Invalid();
|
||||||
|
}
|
||||||
|
return dhcp_server;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Domain::init(Domain_tree &domains)
|
void Domain::init(Domain_tree &domains)
|
||||||
{
|
{
|
||||||
/* read DHCP server configuration */
|
/* read DHCP server configuration */
|
||||||
@ -198,7 +207,8 @@ void Domain::init(Domain_tree &domains)
|
|||||||
throw Invalid();
|
throw Invalid();
|
||||||
}
|
}
|
||||||
_dhcp_server = *new (_alloc)
|
_dhcp_server = *new (_alloc)
|
||||||
Dhcp_server(dhcp_server_node, _alloc, ip_config().interface);
|
Dhcp_server(dhcp_server_node, _alloc, ip_config().interface,
|
||||||
|
domains);
|
||||||
|
|
||||||
if (_config.verbose()) {
|
if (_config.verbose()) {
|
||||||
log("[", *this, "] DHCP server: ", _dhcp_server()); }
|
log("[", *this, "] DHCP server: ", _dhcp_server()); }
|
||||||
|
@ -180,7 +180,7 @@ class Net::Domain : public Domain_base
|
|||||||
Interface_list &interfaces() { return _interfaces; }
|
Interface_list &interfaces() { return _interfaces; }
|
||||||
Configuration &config() const { return _config; }
|
Configuration &config() const { return _config; }
|
||||||
Domain_avl_member &avl_member() { return _avl_member; }
|
Domain_avl_member &avl_member() { return _avl_member; }
|
||||||
Dhcp_server &dhcp_server() { return _dhcp_server(); }
|
Dhcp_server &dhcp_server();
|
||||||
Arp_cache &arp_cache() { return _arp_cache; }
|
Arp_cache &arp_cache() { return _arp_cache; }
|
||||||
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
|
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
|
||||||
Link_side_tree &tcp_links() { return _tcp_links; }
|
Link_side_tree &tcp_links() { return _tcp_links; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user