nic_router: add trace_packets config option

genodelabs/genode#4352
This commit is contained in:
Johannes Schlatow 2022-05-18 12:17:40 +02:00 committed by Christian Helmuth
parent cee0c9858c
commit 810bbc0484
7 changed files with 47 additions and 2 deletions

View File

@ -743,7 +743,7 @@ Whether to log router decisions and optional hints.
! <config verbose_packets="no" ... >
! <domain verbose_packets="no" ... />
! <config/>
! </config>
Whether to log most important protocol header fields of each packet that is
received or sent (ETH, IPv4, ARP, UDP, TCP, DHCP, ICMP). The <config> value
@ -751,7 +751,7 @@ affects all domains without a <domain> local value.
! <config verbose_packet_drop="no" ... >
! <domain verbose_packet_drop="no" ... />
! <config/>
! </config>
Whether to log each packet drop and the rational behind it. The <config> value
affects all domains without a <domain> local value.
@ -762,6 +762,28 @@ Whether to log most important changes in the state of a domain (number of
interfaces assigned, current IPv4 config).
Tracing
~~~~~~~
You can use Genode's TRACE service to capture all packets that traverse the
router. This requires a monitor component such as the trace-recorder component
that provides and activates a corresponding trace buffer and trace policy.
More precisely, packet tracing is realised via the 'trace_eth_packet()' hook
that needs to be implemented by the trace policy. Note that packet tracing must
also be enabled in the router configuration.
This is how you can configure whether to trace packets (default values shown):
! <config trace_packets="no">
! <domain trace_packets="no" ... />
! </config>
If enabled, 'trace_eth_packet()' is called for every packet received or sent by
the router. The attribute in the <domain> tag applies only for packets
received and sent by that domain. The attribute in the <config> tag sets the
default value for all <domain> tags without a local setting.
Other configuration attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -171,6 +171,7 @@
<xs:attribute name="gateway" type="Ipv4_address" />
<xs:attribute name="verbose_packets" type="Boolean" />
<xs:attribute name="verbose_packet_drop" type="Boolean" />
<xs:attribute name="trace_packets" type="Boolean" />
<xs:attribute name="label" type="Session_label" />
<xs:attribute name="icmp_echo_server" type="Boolean" />
<xs:attribute name="use_arp" type="Boolean" />
@ -182,6 +183,7 @@
<xs:attribute name="verbose" type="Boolean" />
<xs:attribute name="verbose_packets" type="Boolean" />
<xs:attribute name="verbose_packet_drop" type="Boolean" />
<xs:attribute name="trace_packets" type="Boolean" />
<xs:attribute name="verbose_domain_state" type="Boolean" />
<xs:attribute name="dhcp_discover_timeout_sec" type="Seconds" />
<xs:attribute name="dhcp_request_timeout_sec" type="Seconds" />

View File

@ -36,6 +36,7 @@ Configuration::Configuration(Xml_node const node,
_verbose_packets { false },
_verbose_packet_drop { false },
_verbose_domain_state { false },
_trace_packets { false },
_icmp_echo_server { false },
_icmp_type_3_code_on_fragm_ipv4 { 0 },
_dhcp_discover_timeout { 0 },
@ -116,6 +117,7 @@ Configuration::Configuration(Env &env,
_verbose_packets { node.attribute_value("verbose_packets", false) },
_verbose_packet_drop { node.attribute_value("verbose_packet_drop", false) },
_verbose_domain_state { node.attribute_value("verbose_domain_state", false) },
_trace_packets { node.attribute_value("trace_packets", false) },
_icmp_echo_server { node.attribute_value("icmp_echo_server", true) },
_icmp_type_3_code_on_fragm_ipv4 { _init_icmp_type_3_code_on_fragm_ipv4(node) },
_dhcp_discover_timeout { read_sec_attr(node, "dhcp_discover_timeout_sec", 10) },

View File

@ -39,6 +39,7 @@ class Net::Configuration
bool const _verbose_packets;
bool const _verbose_packet_drop;
bool const _verbose_domain_state;
bool const _trace_packets;
bool const _icmp_echo_server;
Icmp_packet::Code const _icmp_type_3_code_on_fragm_ipv4;
Genode::Microseconds const _dhcp_discover_timeout;
@ -92,6 +93,7 @@ class Net::Configuration
bool verbose_packets() const { return _verbose_packets; }
bool verbose_packet_drop() const { return _verbose_packet_drop; }
bool verbose_domain_state() const { return _verbose_domain_state; }
bool trace_packets() const { return _trace_packets; }
bool icmp_echo_server() const { return _icmp_echo_server; }
Icmp_packet::Code icmp_type_3_code_on_fragm_ipv4() const { return _icmp_type_3_code_on_fragm_ipv4; }
Genode::Microseconds dhcp_discover_timeout() const { return _dhcp_discover_timeout; }

View File

@ -196,6 +196,8 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
config.verbose_packets()) },
_verbose_packet_drop { node.attribute_value("verbose_packet_drop",
config.verbose_packet_drop()) },
_trace_packets { node.attribute_value("trace_packets",
config.trace_packets()) },
_icmp_echo_server { node.attribute_value("icmp_echo_server",
config.icmp_echo_server()) },
_use_arp { _node.attribute_value("use_arp", true) },

View File

@ -142,6 +142,7 @@ class Net::Domain : public Domain_base,
Genode::size_t _rx_bytes { 0 };
bool const _verbose_packets;
bool const _verbose_packet_drop;
bool const _trace_packets;
bool const _icmp_echo_server;
bool const _use_arp;
Genode::Session_label const _label;
@ -236,6 +237,7 @@ class Net::Domain : public Domain_base,
bool verbose_packets() const { return _verbose_packets; }
bool verbose_packet_drop() const { return _verbose_packet_drop; }
bool trace_packets() const { return _trace_packets; }
bool icmp_echo_server() const { return _icmp_echo_server; }
bool use_arp() const { return _use_arp; }
Genode::Session_label const &label() const { return _label; }

View File

@ -1756,6 +1756,12 @@ void Interface::_handle_eth(void *const eth_base,
if (local_domain.verbose_packets()) {
log("[", local_domain, "] rcv ", eth); }
if (local_domain.trace_packets())
Genode::Trace::Ethernet_packet(local_domain.name().string(),
Genode::Trace::Ethernet_packet::Direction::RECV,
eth_base,
size_guard.total_size());
/* try to handle ethernet frame */
try { _handle_eth(eth, size_guard, pkt, local_domain); }
catch (Free_resources_and_retry_handle_eth) {
@ -1871,6 +1877,13 @@ void Interface::_send_submit_pkt(Packet_descriptor &pkt,
}
catch (Size_guard::Exceeded) { log("[", local_domain, "] snd ?"); }
}
if (local_domain.trace_packets())
Genode::Trace::Ethernet_packet(local_domain.name().string(),
Genode::Trace::Ethernet_packet::Direction::SENT,
pkt_base,
pkt_size);
_source.try_submit_packet(pkt);
}