From edf1f9d84953e7ca5b5bdb9bf1c66c07d3d3772c Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Thu, 14 Dec 2017 16:24:42 +0100 Subject: [PATCH] nic_router: report some useful information The NIC router can now be configured to periodically send reports. Configuration example (shows default values): If the 'report' tag is not available, no reports are send. The attributes of the 'report' tag: 'bytes' : Boolean : Whether to report sent bytes and received bytes per domain 'config' : Boolean : Whether to report ipv4 interface and gateway per domain 'interval_sec' : 1..3600 : Interval of sending reports in seconds Issue #2614 --- repos/libports/run/nic_router.run | 15 ++++- repos/os/recipes/src/nic_router/used_apis | 1 + repos/os/src/server/nic_router/README | 21 +++++++ repos/os/src/server/nic_router/config.xsd | 8 +++ .../os/src/server/nic_router/configuration.cc | 30 ++++----- .../os/src/server/nic_router/configuration.h | 9 ++- repos/os/src/server/nic_router/domain.cc | 21 +++++++ repos/os/src/server/nic_router/domain.h | 14 ++++- repos/os/src/server/nic_router/interface.cc | 3 + repos/os/src/server/nic_router/main.cc | 3 +- repos/os/src/server/nic_router/report.cc | 51 +++++++++++++++ repos/os/src/server/nic_router/report.h | 62 +++++++++++++++++++ repos/os/src/server/nic_router/target.mk | 2 +- repos/os/src/server/nic_router/xml_node.cc | 29 +++++++++ repos/os/src/server/nic_router/xml_node.h | 29 +++++++++ 15 files changed, 274 insertions(+), 24 deletions(-) create mode 100644 repos/os/src/server/nic_router/report.cc create mode 100644 repos/os/src/server/nic_router/report.h create mode 100644 repos/os/src/server/nic_router/xml_node.cc create mode 100644 repos/os/src/server/nic_router/xml_node.h diff --git a/repos/libports/run/nic_router.run b/repos/libports/run/nic_router.run index a19196ae6..2822af5f1 100644 --- a/repos/libports/run/nic_router.run +++ b/repos/libports/run/nic_router.run @@ -12,6 +12,8 @@ proc enable_test_7 { } { return 0 } source ${genode_dir}/repos/libports/run/nic_router.inc +lappend targets server/report_rom + build $targets create_boot_directory @@ -210,6 +212,8 @@ append config { tcp_idle_timeout_sec="30" tcp_max_segm_lifetime_sec="15"> + + @@ -229,6 +233,7 @@ append config { + @@ -245,11 +250,17 @@ append config { - + + + + + + + } [test_1_config] { } [test_2_config] { } [test_3_config] { @@ -262,6 +273,8 @@ append config { install_config $config +lappend boot_modules report_rom + build_boot_image $boot_modules for {set i 0} {$i < $nr_of_clients} {incr i 1} { diff --git a/repos/os/recipes/src/nic_router/used_apis b/repos/os/recipes/src/nic_router/used_apis index d96822280..64e9a0773 100644 --- a/repos/os/recipes/src/nic_router/used_apis +++ b/repos/os/recipes/src/nic_router/used_apis @@ -2,3 +2,4 @@ base os nic_session timer_session +report_session diff --git a/repos/os/src/server/nic_router/README b/repos/os/src/server/nic_router/README index 64a67b568..83b4eaf04 100644 --- a/repos/os/src/server/nic_router/README +++ b/repos/os/src/server/nic_router/README @@ -336,6 +336,27 @@ router: ! dhcp_request_timeout_sec="6"> +Configuring reporting functionality +################################### + +The NIC router can be configured to periodically send reports. + +Configuration example (shows default values of attributes): + + + + + +If the 'report' tag is not available, no reports are send. +The attributes of the 'report' tag: + +'bytes' : Boolean : Whether to report sent bytes and received bytes per + domain +'config' : Boolean : Whether to report ipv4 interface and gateway per + domain +'interval_sec' : 1..3600 : Interval of sending reports in seconds + + Examples ######## diff --git a/repos/os/src/server/nic_router/config.xsd b/repos/os/src/server/nic_router/config.xsd index b7618a601..7eecca649 100644 --- a/repos/os/src/server/nic_router/config.xsd +++ b/repos/os/src/server/nic_router/config.xsd @@ -89,6 +89,14 @@ + + + + + + + + diff --git a/repos/os/src/server/nic_router/configuration.cc b/repos/os/src/server/nic_router/configuration.cc index 6a01f3f5d..50b95a491 100644 --- a/repos/os/src/server/nic_router/configuration.cc +++ b/repos/os/src/server/nic_router/configuration.cc @@ -13,9 +13,9 @@ /* local includes */ #include +#include /* Genode includes */ -#include #include #include @@ -23,28 +23,14 @@ using namespace Net; using namespace Genode; -/*************** - ** Utilities ** - ***************/ - -Microseconds read_sec_attr(Xml_node const node, - char const *name, - unsigned long const default_sec) -{ - unsigned long sec = node.attribute_value(name, 0UL); - if (!sec) { - sec = default_sec; - } - return Microseconds(sec * 1000 * 1000); -} - - /******************* ** Configuration ** *******************/ -Configuration::Configuration(Xml_node const node, - Allocator &alloc) +Configuration::Configuration(Env &env, + Xml_node const node, + Allocator &alloc, + Timer::Connection &timer) : _alloc(alloc), _verbose(node.attribute_value("verbose", false)), _verbose_domain_state(node.attribute_value("verbose_domain_state", false)), @@ -56,6 +42,7 @@ Configuration::Configuration(Xml_node const node, _tcp_max_segm_lifetime(read_sec_attr(node, "tcp_max_segm_lifetime_sec", DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC)), _node(node) { + /* read domains */ node.for_each_sub_node("domain", [&] (Xml_node const node) { try { _domains.insert(*new (_alloc) Domain(*this, node, _alloc)); } @@ -68,4 +55,9 @@ Configuration::Configuration(Xml_node const node, domain.create_rules(_domains); }); + /* if configured, create a report generator */ + try { + _report.set(*new (_alloc) Report(env, node.sub_node("report"), timer, + _domains)); + } catch (Genode::Xml_node::Nonexistent_sub_node) { } } diff --git a/repos/os/src/server/nic_router/configuration.h b/repos/os/src/server/nic_router/configuration.h index 9eb326c04..798b36dd8 100644 --- a/repos/os/src/server/nic_router/configuration.h +++ b/repos/os/src/server/nic_router/configuration.h @@ -16,6 +16,7 @@ /* local includes */ #include +#include /* Genode includes */ #include @@ -38,11 +39,13 @@ class Net::Configuration Genode::Microseconds const _udp_idle_timeout; Genode::Microseconds const _tcp_idle_timeout; Genode::Microseconds const _tcp_max_segm_lifetime; + Pointer _report; Domain_tree _domains; Genode::Xml_node const _node; public: + enum { DEFAULT_REPORT_INTERVAL_SEC = 5 }; enum { DEFAULT_DHCP_DISCOVER_TIMEOUT_SEC = 10 }; enum { DEFAULT_DHCP_REQUEST_TIMEOUT_SEC = 10 }; enum { DEFAULT_DHCP_OFFER_TIMEOUT_SEC = 10 }; @@ -50,7 +53,10 @@ class Net::Configuration enum { DEFAULT_TCP_IDLE_TIMEOUT_SEC = 600 }; enum { DEFAULT_TCP_MAX_SEGM_LIFETIME_SEC = 30 }; - Configuration(Genode::Xml_node const node, Genode::Allocator &alloc); + Configuration(Genode::Env &env, + Genode::Xml_node const node, + Genode::Allocator &alloc, + Timer::Connection &timer); /*************** @@ -66,6 +72,7 @@ class Net::Configuration Genode::Microseconds tcp_idle_timeout() const { return _tcp_idle_timeout; } Genode::Microseconds tcp_max_segm_lifetime() const { return _tcp_max_segm_lifetime; } Domain_tree &domains() { return _domains; } + Report &report() { return _report.deref(); } Genode::Xml_node node() const { return _node; } }; diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 7d2a0f668..3447016c7 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -17,6 +17,7 @@ #include /* Genode includes */ +#include #include #include #include @@ -233,6 +234,26 @@ void Domain::dissolve_interface(Interface &interface) } } +void Domain::report(Xml_generator &xml) +{ + bool const bytes = _config.report().bytes(); + bool const config = _config.report().config(); + if (!bytes && !config) { + return; + } + xml.node("domain", [&] () { + xml.attribute("name", _name); + if (bytes) { + xml.attribute("rx_bytes", _tx_bytes); + xml.attribute("tx_bytes", _rx_bytes); + } + if (config) { + xml.attribute("ipv4", String<19>(ip_config().interface)); + xml.attribute("gw", String<16>(ip_config().gateway)); + } + }); +} + /***************** ** Domain_tree ** diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index 7bfcb973d..11f909af4 100644 --- a/repos/os/src/server/nic_router/domain.h +++ b/repos/os/src/server/nic_router/domain.h @@ -30,7 +30,11 @@ #include #include -namespace Genode { class Allocator; } +namespace Genode { + + class Xml_generator; + class Allocator; +} namespace Net { @@ -98,6 +102,8 @@ class Net::Domain : public Domain_base Arp_waiter_list _foreign_arp_waiters; Link_side_tree _tcp_links; Link_side_tree _udp_links; + Genode::size_t _tx_bytes { 0 }; + Genode::size_t _rx_bytes { 0 }; void _read_forward_rules(Genode::Cstring const &protocol, Domain_tree &domains, @@ -140,6 +146,12 @@ class Net::Domain : public Domain_base void dissolve_interface(Interface &interface); + void raise_rx_bytes(Genode::size_t bytes) { _rx_bytes += bytes; } + + void raise_tx_bytes(Genode::size_t bytes) { _tx_bytes += bytes; } + + void report(Genode::Xml_generator &xml); + /********* ** log ** diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index ab14a1567..507482689 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -862,6 +862,8 @@ void Interface::_handle_eth(void *const eth_base, size_t const eth_size, Packet_descriptor const &pkt) { + _domain.raise_rx_bytes(eth_size); + /* do garbage collection over transport-layer links and DHCP allocations */ _destroy_dissolved_links(_dissolved_udp_links, _alloc); _destroy_dissolved_links(_dissolved_tcp_links, _alloc); @@ -936,6 +938,7 @@ void Interface::send(Ethernet_frame ð, Genode::size_t const size) char *content = _source().packet_content(pkt); Genode::memcpy((void *)content, (void *)ð, size); _source().submit_packet(pkt); + _domain.raise_tx_bytes(size); } catch (Packet_stream_source::Packet_alloc_failed) { if (_config().verbose()) { diff --git a/repos/os/src/server/nic_router/main.cc b/repos/os/src/server/nic_router/main.cc index 588079670..a007029ad 100644 --- a/repos/os/src/server/nic_router/main.cc +++ b/repos/os/src/server/nic_router/main.cc @@ -47,7 +47,8 @@ class Main Main::Main(Env &env) : _timer(env), _heap(&env.ram(), &env.rm()), _config_rom(env, "config"), - _config(_config_rom.xml(), _heap), _uplink(env, _timer, _heap, _config), + _config(env, _config_rom.xml(), _heap, _timer), + _uplink(env, _timer, _heap, _config), _root(env.ep(), _timer, _heap, _uplink.router_mac(), _config, env.ram(), env.rm()) { diff --git a/repos/os/src/server/nic_router/report.cc b/repos/os/src/server/nic_router/report.cc new file mode 100644 index 000000000..5ff8f4a03 --- /dev/null +++ b/repos/os/src/server/nic_router/report.cc @@ -0,0 +1,51 @@ +/* + * \brief Report generation unit + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include +#include +#include + +using namespace Net; +using namespace Genode; + + +Net::Report::Report(Env &env, + Xml_node const node, + Timer::Connection &timer, + Domain_tree &domains) +: + _config(node.attribute_value("config", true)), + _bytes (node.attribute_value("bytes", true)), + _reporter(env, "state"), + _domains(domains), + _timeout(timer, *this, &Report::_handle_report_timeout, + read_sec_attr(node, "interval_sec", 5)) +{ + _reporter.enabled(true); +} + + + +void Net::Report::_handle_report_timeout(Duration) +{ + try { + Reporter::Xml_generator xml(_reporter, [&] () { + _domains.for_each([&] (Domain &domain) { + domain.report(xml); + }); + }); + } catch (Xml_generator::Buffer_exceeded) { + Genode::warning("Failed to generate report"); + } +} diff --git a/repos/os/src/server/nic_router/report.h b/repos/os/src/server/nic_router/report.h new file mode 100644 index 000000000..754c429ab --- /dev/null +++ b/repos/os/src/server/nic_router/report.h @@ -0,0 +1,62 @@ +/* + * \brief Report generation unit + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _REPORT_H_ +#define _REPORT_H_ + +/* Genode */ +#include +#include + +namespace Genode { + + class Xml_node; + class Env; +} + +namespace Net { + + class Domain_tree; + class Report; +} + + +class Net::Report +{ + private: + + bool const _config; + bool const _bytes; + Genode::Reporter _reporter; + Domain_tree &_domains; + Timer::Periodic_timeout _timeout; + + void _handle_report_timeout(Genode::Duration); + + public: + + Report(Genode::Env &env, + Genode::Xml_node const node, + Timer::Connection &timer, + Domain_tree &domains); + + + /*************** + ** Accessors ** + ***************/ + + bool config() const { return _config; } + bool bytes() const { return _bytes; } +}; + +#endif /* _REPORT_H_ */ diff --git a/repos/os/src/server/nic_router/target.mk b/repos/os/src/server/nic_router/target.mk index a4fb15f4d..31a6d3863 100644 --- a/repos/os/src/server/nic_router/target.mk +++ b/repos/os/src/server/nic_router/target.mk @@ -8,7 +8,7 @@ SRC_CC += nat_rule.cc mac_allocator.cc main.cc ipv4_config.cc SRC_CC += uplink.cc interface.cc arp_cache.cc configuration.cc SRC_CC += domain.cc l3_protocol.cc direct_rule.cc link.cc SRC_CC += transport_rule.cc leaf_rule.cc permit_rule.cc -SRC_CC += dhcp_client.cc dhcp_server.cc +SRC_CC += dhcp_client.cc dhcp_server.cc report.cc xml_node.cc INC_DIR += $(PRG_DIR) diff --git a/repos/os/src/server/nic_router/xml_node.cc b/repos/os/src/server/nic_router/xml_node.cc new file mode 100644 index 000000000..be7d7b80c --- /dev/null +++ b/repos/os/src/server/nic_router/xml_node.cc @@ -0,0 +1,29 @@ +/* + * \brief Genode XML nodes plus local utilities + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +using namespace Genode; + + +Microseconds Genode::read_sec_attr(Xml_node const node, + char const *name, + unsigned long const default_sec) +{ + unsigned long sec = node.attribute_value(name, 0UL); + if (!sec) { + sec = default_sec; + } + return Microseconds(sec * 1000 * 1000); +} diff --git a/repos/os/src/server/nic_router/xml_node.h b/repos/os/src/server/nic_router/xml_node.h new file mode 100644 index 000000000..86f3840a6 --- /dev/null +++ b/repos/os/src/server/nic_router/xml_node.h @@ -0,0 +1,29 @@ +/* + * \brief Genode XML nodes plus local utilities + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _XML_NODE_H_ +#define _XML_NODE_H_ + +/* Genode includes */ +#include +#include + + +namespace Genode { + + Microseconds read_sec_attr(Xml_node const node, + char const *name, + unsigned long const default_sec); +} + +#endif /* _XML_NODE_H_ */