nic_router: label attribute for uplink domain

The new attribute config.domain.label has effect only at the uplink
domain-tag. It determines which label the NIC router shall use when
requesting the NIC session for the uplink domain. If value of this
attribute changes at the uplink domain-tag, the NIC router closes and
re-requests the NIC session of the uplink with the new label.

Issue 
This commit is contained in:
Martin Stein 2018-05-10 13:38:45 +02:00 committed by Christian Helmuth
parent 1cfcab536c
commit ed69c11b01
7 changed files with 113 additions and 52 deletions

@ -411,6 +411,27 @@ router:
! dhcp_request_timeout_sec="6">
The uplink domain
~~~~~~~~~~~~~~~~~
The uplink domain is treated like every other domain wherever possible.
However, there are still some differences that are visible to the user:
* 'policy' tags that target the uplink domain have no effect at all
* The domain tag of the uplink is the only domain tag in which the
'label' attribute has an effect
* The uplink domain, as long as existant, has exactly one NIC session in which
the NIC router is the session client
* When the uplink 'domain' tag appears, the uplink NIC session is requested by
the NIC router using the label denoted in the 'label' attribute of the
uplink 'domain' tag (default label "")
* When the 'label' attribute of the uplink 'domain' tag changes, the NIC
router closes the uplink NIC session and requests it again with the new
label
* When the uplink 'domain' tag disappears, the NIC router closes the uplink
NIC session
Configuring reporting functionality
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@ -147,6 +147,7 @@
<xs:attribute name="interface" type="Ipv4_address_prefix" />
<xs:attribute name="gateway" type="Ipv4_address" />
<xs:attribute name="verbose_packets" type="Boolean" />
<xs:attribute name="label" type="Session_label" />
</xs:complexType>
</xs:element><!-- domain -->

@ -115,7 +115,8 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
_node.attribute_value("gateway", Ipv4_address()),
Ipv4_address()),
_verbose_packets(_node.attribute_value("verbose_packets", false) ||
_config.verbose_packets())
_config.verbose_packets()),
_label(_node.attribute_value("label", String<160>()).string())
{
if (_name == Domain_name()) {
log("[?] Missing name attribute in domain node");

@ -110,6 +110,7 @@ class Net::Domain : public Domain_base,
Genode::size_t _tx_bytes { 0 };
Genode::size_t _rx_bytes { 0 };
bool const _verbose_packets { false };
Genode::Session_label const _label;
void _read_forward_rules(Genode::Cstring const &protocol,
Domain_tree &domains,
@ -173,26 +174,27 @@ class Net::Domain : public Domain_base,
** Accessors **
***************/
bool verbose_packets() const { return _verbose_packets; }
Ipv4_config const &ip_config() const { return *_ip_config; }
List<Domain> &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; }
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
Transport_rule_list &tcp_rules() { return _tcp_rules; }
Transport_rule_list &udp_rules() { return _udp_rules; }
Ip_rule_list &icmp_rules() { return _icmp_rules; }
Nat_rule_tree &nat_rules() { return _nat_rules; }
Interface_list &interfaces() { return _interfaces; }
Configuration &config() const { return _config; }
Domain_avl_member &avl_member() { return _avl_member; }
Dhcp_server &dhcp_server();
Arp_cache &arp_cache() { return _arp_cache; }
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
Link_side_tree &tcp_links() { return _tcp_links; }
Link_side_tree &udp_links() { return _udp_links; }
Link_side_tree &icmp_links() { return _icmp_links; }
bool verbose_packets() const { return _verbose_packets; }
Genode::Session_label const &label() const { return _label; }
Ipv4_config const &ip_config() const { return *_ip_config; }
List<Domain> &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; }
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
Transport_rule_list &tcp_rules() { return _tcp_rules; }
Transport_rule_list &udp_rules() { return _udp_rules; }
Ip_rule_list &icmp_rules() { return _icmp_rules; }
Nat_rule_tree &nat_rules() { return _nat_rules; }
Interface_list &interfaces() { return _interfaces; }
Configuration &config() const { return _config; }
Domain_avl_member &avl_member() { return _avl_member; }
Dhcp_server &dhcp_server();
Arp_cache &arp_cache() { return _arp_cache; }
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
Link_side_tree &tcp_links() { return _tcp_links; }
Link_side_tree &udp_links() { return _udp_links; }
Link_side_tree &icmp_links() { return _icmp_links; }
};

@ -47,7 +47,12 @@ class Net::Main
Configuration &_init_config();
void _try_init_uplink(Configuration &config);
void _deinit_uplink(Configuration &config);
void _init_uplink(Configuration &config,
Session_label const &label);
void _uplink_handle_config(Configuration &config);
template <typename FUNC>
void _for_each_interface(FUNC && functor)
@ -83,21 +88,55 @@ Configuration &Net::Main::_init_config()
Net::Main::Main(Env &env) : _env(env)
{
_try_init_uplink(_config());
_uplink_handle_config(_config());
_config_rom.sigh(_config_handler);
env.parent().announce(env.ep().manage(_root));
}
void Net::Main::_try_init_uplink(Configuration &config)
void Net::Main::_init_uplink(Configuration &config,
Session_label const &label)
{
if (config.verbose()) {
log("[uplink] request NIC session \"", label, "\""); }
Uplink &uplink = *new (_heap) Uplink(_env, _timer, _heap, _interfaces,
config, label);
_uplink = Pointer<Uplink>(uplink);
uplink.init();
}
void Net::Main::_deinit_uplink(Configuration &config)
{
try {
config.domains().find_by_name("uplink");
Uplink &uplink = *new (_heap) Uplink(_env, _timer, _heap, _interfaces, config);
_uplink = Pointer<Uplink>(uplink);
uplink.init();
Uplink &uplink = _uplink();
if (config.verbose()) {
log("[uplink] close NIC session \"", uplink.label(), "\""); }
destroy(_heap, &uplink);
_uplink = Pointer<Uplink>();
}
catch (Domain_tree::No_match) { }
catch (Pointer<Uplink>::Invalid) { }
}
void Net::Main::_uplink_handle_config(Configuration &config)
{
try {
Session_label const &label =
config.domains().find_by_name("uplink").label();
try {
if (label == _uplink().label()) {
return;
}
_deinit_uplink(config);
_init_uplink(config, label);
}
catch (Pointer<Uplink>::Invalid) { _init_uplink(config, label); }
}
catch (Domain_tree::No_match) { _deinit_uplink(config); }
}
@ -107,16 +146,7 @@ void Net::Main::_handle_config()
Configuration &config = *new (_heap)
Configuration(_env, _config_rom.xml(), _heap, _timer, _config());
try {
Uplink &uplink = _uplink();
try { config.domains().find_by_name("uplink"); }
catch (Domain_tree::No_match) {
destroy(_heap, &uplink);
_uplink = Pointer<Uplink>();
}
}
catch (Pointer<Uplink>::Invalid) { _try_init_uplink(config); }
_uplink_handle_config(config);
_root.handle_config(config);
_for_each_interface([&] (Interface &intf) { intf.handle_config(config); });
_for_each_interface([&] (Interface &intf) { intf.handle_config_aftermath(); });

@ -23,16 +23,18 @@ using namespace Net;
using namespace Genode;
Net::Uplink::Uplink(Env &env,
Timer::Connection &timer,
Genode::Allocator &alloc,
Interface_list &interfaces,
Configuration &config)
Net::Uplink::Uplink(Env &env,
Timer::Connection &timer,
Genode::Allocator &alloc,
Interface_list &interfaces,
Configuration &config,
Session_label const &label)
:
Nic::Packet_allocator(&alloc),
Nic::Connection(env, this, BUF_SIZE, BUF_SIZE),
Nic::Connection(env, this, BUF_SIZE, BUF_SIZE, label.string()),
Net::Interface(env.ep(), timer, mac_address(), alloc, Mac_address(),
config, interfaces, _intf_policy)
config, interfaces, _intf_policy),
_label(label)
{
rx_channel()->sigh_ready_to_ack(_sink_ack);
rx_channel()->sigh_packet_avail(_sink_submit);

@ -62,6 +62,8 @@ class Net::Uplink : public Uplink_base,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PKT_SIZE,
};
Genode::Session_label const &_label;
Ipv4_address_prefix _read_interface();
@ -74,18 +76,20 @@ class Net::Uplink : public Uplink_base,
public:
Uplink(Genode::Env &env,
Timer::Connection &timer,
Genode::Allocator &alloc,
Interface_list &interfaces,
Configuration &config);
Uplink(Genode::Env &env,
Timer::Connection &timer,
Genode::Allocator &alloc,
Interface_list &interfaces,
Configuration &config,
Genode::Session_label const &label);
/***************
** Accessors **
***************/
Mac_address const &router_mac() const { return _router_mac; }
Mac_address const &router_mac() const { return _router_mac; }
Genode::Session_label const &label() const { return _label; }
};
#endif /* _UPLINK_H_ */