From ed69c11b0129609c83b94c0390cb828409adf377 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Thu, 10 May 2018 13:38:45 +0200 Subject: [PATCH] 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 #2815 --- repos/os/src/server/nic_router/README | 21 ++++++++ repos/os/src/server/nic_router/config.xsd | 1 + repos/os/src/server/nic_router/domain.cc | 3 +- repos/os/src/server/nic_router/domain.h | 42 ++++++++------- repos/os/src/server/nic_router/main.cc | 66 ++++++++++++++++------- repos/os/src/server/nic_router/uplink.cc | 16 +++--- repos/os/src/server/nic_router/uplink.h | 16 +++--- 7 files changed, 113 insertions(+), 52 deletions(-) diff --git a/repos/os/src/server/nic_router/README b/repos/os/src/server/nic_router/README index c125ebb485..20b3141c72 100644 --- a/repos/os/src/server/nic_router/README +++ b/repos/os/src/server/nic_router/README @@ -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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/repos/os/src/server/nic_router/config.xsd b/repos/os/src/server/nic_router/config.xsd index 10bfaca339..530425c429 100644 --- a/repos/os/src/server/nic_router/config.xsd +++ b/repos/os/src/server/nic_router/config.xsd @@ -147,6 +147,7 @@ + diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index a213a331e2..78b48c3791 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -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"); diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index fd8154396f..005fcf5ef3 100644 --- a/repos/os/src/server/nic_router/domain.h +++ b/repos/os/src/server/nic_router/domain.h @@ -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 &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 &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; } }; diff --git a/repos/os/src/server/nic_router/main.cc b/repos/os/src/server/nic_router/main.cc index 78c1691589..a0b1840e72 100644 --- a/repos/os/src/server/nic_router/main.cc +++ b/repos/os/src/server/nic_router/main.cc @@ -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 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.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.init(); + Uplink &uplink = _uplink(); + if (config.verbose()) { + log("[uplink] close NIC session \"", uplink.label(), "\""); } + + destroy(_heap, &uplink); + _uplink = Pointer(); } - catch (Domain_tree::No_match) { } + catch (Pointer::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::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(); - } - } - catch (Pointer::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(); }); diff --git a/repos/os/src/server/nic_router/uplink.cc b/repos/os/src/server/nic_router/uplink.cc index 97b8f602a9..4160c49136 100644 --- a/repos/os/src/server/nic_router/uplink.cc +++ b/repos/os/src/server/nic_router/uplink.cc @@ -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); diff --git a/repos/os/src/server/nic_router/uplink.h b/repos/os/src/server/nic_router/uplink.h index 30a1375a14..b23b3c0301 100644 --- a/repos/os/src/server/nic_router/uplink.h +++ b/repos/os/src/server/nic_router/uplink.h @@ -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_ */