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_ */