nic_router: report dropped fragmented IPv4

If the new attribute 'dropped_fragm_ipv4' of the <report> tag in the NIC router
config is set "yes", the router will report the number of packets that were
dropped per interface respectively domain because fragmented IPv4 is not
supported. The default is not to report the counter. The behavior is tested by
the 'nic_router_ipv4_fragm' test.

Ref #4236
This commit is contained in:
Martin Stein 2021-08-02 12:17:13 +02:00 committed by Christian Helmuth
parent 619474bc90
commit 06a4608f4a
9 changed files with 55 additions and 2 deletions

View File

@ -45,7 +45,9 @@ create_boot_directory
import_from_depot [depot_user]/pkg/[drivers_nic_pkg]
build { core init timer server/nic_router app/ping test/lwip/udp }
build {
core init timer server/nic_router app/ping test/lwip/udp
server/report_rom }
append config {
@ -83,6 +85,12 @@ append config {
</route>
</start>
<start name="report_rom">
<resource name="RAM" quantum="32M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"/>
</start>
<start name="nic_router" caps="200">
<resource name="RAM" quantum="10M"/>
<provides>
@ -96,6 +104,9 @@ append config {
<policy label_prefix="drivers" domain="uplink"/>
<policy label_prefix="test-lwip-udp-server" domain="downlink"/>
<report interval_sec="1" config="no" bytes="no" stats="no"
quota="no" dropped_fragm_ipv4="yes"/>
<domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1">
<nat domain="downlink" udp-ports="100"/>
@ -135,7 +146,7 @@ append config {
install_config $config
build_boot_image {
core init timer nic_router ping test-lwip-udp-server ld.lib.so libc.lib.so
libm.lib.so vfs.lib.so vfs_lwip.lib.so }
libm.lib.so vfs.lib.so vfs_lwip.lib.so report_rom }
# wait for server ip stack to come up
run_genode_until {.*lwIP Nic interface up.*\n} 30
@ -158,4 +169,5 @@ set pattern_string ""
append pattern_string {.*drop packet .fragmented IPv4 not supported.*\n}
append pattern_string {.*drop packet .fragmented IPv4 not supported.*\n}
append pattern_string {.*drop packet .fragmented IPv4 not supported.*\n}
append pattern_string {.*<dropped-fragm-ipv4 value="3"\/>.*\n}
run_genode_until $pattern_string 30 $genode_id

View File

@ -528,6 +528,7 @@ Configuration example (shows default values of attributes):
! <config>
! <report bytes="yes"
! stats="yes"
! dropped_fragm_ipv4="yes"
! quota="yes"
! config="yes"
! config_triggers="no"
@ -578,6 +579,7 @@ A complete state report of the NIC router is structured the following way
! <destroyed value="4"/>
! </dhcp-allocations>
! <arp-waiters> ... </arp-waiters>
! <dropped-fragm-ipv4 value="3"/>
!
! </interface>
! <interface ...> ... </interface>
@ -595,6 +597,7 @@ A complete state report of the NIC router is structured the following way
! <destroyed value="16"/>
! </dhcp-allocations>
! <arp-waiters> ... </arp-waiters>
! <dropped-fragm-ipv4 value="1"/>
!
! </domain>
! <domain ...> ... </domain>
@ -652,6 +655,15 @@ in an <interface> tag. When in a <domain> tag, they only list the number of
already destroyed objects of these types that can't be correlated anymore to
any interface of the domain.
'dropped-fragm-ipv4'
A boolean value that controls whether the subtag <dropped-fragm-ipv4> is
generated in the tags <interface> and <domain>. When in an <interface> tag, the
value shows the number of packets that were dropped at the corresponding
interface because they were fragmented IPv4 (which is not supported). When in a
<domain> tag, the value refers to the number of dropped fragmented IPv4 packets
that can't be correlated to any interface of the domain anymore.
'quota'
A boolean value that controls whether the subtags <ram> and <cap> of the

View File

@ -65,6 +65,7 @@
<xs:attribute name="link_state_triggers" type="Boolean" />
<xs:attribute name="quota" type="Boolean" />
<xs:attribute name="interval_sec" type="Seconds" />
<xs:attribute name="dropped_fragm_ipv4" type="Boolean" />
</xs:complexType>
</xs:element><!-- report -->

View File

@ -417,6 +417,12 @@ void Domain::report(Xml_generator &xml)
try { xml.node("arp-waiters", [&] () { _arp_stats.report(xml); }); empty = false; } catch (Report::Empty) { }
try { xml.node("dhcp-allocations", [&] () { _dhcp_stats.report(xml); }); empty = false; } catch (Report::Empty) { }
}
if (_config.report().dropped_fragm_ipv4() && _dropped_fragm_ipv4) {
xml.node("dropped-fragm-ipv4", [&] () {
xml.attribute("value", _dropped_fragm_ipv4);
});
empty = false;
}
_interfaces.for_each([&] (Interface &interface) {
try {
interface.report(xml);
@ -429,6 +435,12 @@ void Domain::report(Xml_generator &xml)
}
void Domain::add_dropped_fragm_ipv4(unsigned long dropped_fragm_ipv4)
{
_dropped_fragm_ipv4 += dropped_fragm_ipv4;
}
/***********************
** Domain_link_stats **
***********************/

View File

@ -126,6 +126,7 @@ class Net::Domain : public Domain_base,
Domain_link_stats _icmp_stats { };
Domain_object_stats _arp_stats { };
Domain_object_stats _dhcp_stats { };
unsigned long _dropped_fragm_ipv4 { 0 };
void _read_forward_rules(Genode::Cstring const &protocol,
Domain_tree &domains,
@ -195,6 +196,8 @@ class Net::Domain : public Domain_base,
void report(Genode::Xml_generator &xml);
void add_dropped_fragm_ipv4(unsigned long dropped_fragm_ipv4);
/*********
** log **

View File

@ -354,6 +354,7 @@ void Interface::_detach_from_domain_raw()
_domain = Pointer<Domain>();
_policy.interface_unready();
domain.add_dropped_fragm_ipv4(_dropped_fragm_ipv4);
domain.tcp_stats().dissolve_interface(_tcp_stats);
domain.udp_stats().dissolve_interface(_udp_stats);
domain.icmp_stats().dissolve_interface(_icmp_stats);
@ -371,6 +372,7 @@ void Interface::_update_domain_object(Domain &new_domain) {
_domain = Pointer<Domain>();
_policy.interface_unready();
old_domain.add_dropped_fragm_ipv4(_dropped_fragm_ipv4);
old_domain.tcp_stats().dissolve_interface(_tcp_stats);
old_domain.udp_stats().dissolve_interface(_udp_stats);
old_domain.icmp_stats().dissolve_interface(_icmp_stats);
@ -1120,6 +1122,7 @@ void Interface::_handle_ip(Ethernet_frame &eth,
if (ip.more_fragments() ||
ip.fragment_offset() != 0) {
_dropped_fragm_ipv4++;
throw Drop_packet("fragmented IPv4 not supported");
}
/* try handling subnet-local IP packets */
@ -2191,6 +2194,12 @@ void Interface::report(Genode::Xml_generator &xml)
try { xml.node("arp-waiters", [&] () { _arp_stats.report(xml); }); empty = false; } catch (Report::Empty) { }
try { xml.node("dhcp-allocations", [&] () { _dhcp_stats.report(xml); }); empty = false; } catch (Report::Empty) { }
}
if (_config().report().dropped_fragm_ipv4() && _dropped_fragm_ipv4) {
xml.node("dropped-fragm-ipv4", [&] () {
xml.attribute("value", _dropped_fragm_ipv4);
});
empty = false;
}
if (empty) { throw Report::Empty(); }
});
}

View File

@ -163,6 +163,7 @@ class Net::Interface : private Interface_list::Element
Interface_link_stats _icmp_stats { };
Interface_object_stats _arp_stats { };
Interface_object_stats _dhcp_stats { };
unsigned long _dropped_fragm_ipv4 { 0 };
void _new_link(L3_protocol const protocol,
Link_side_id const &local_id,

View File

@ -33,6 +33,7 @@ Net::Report::Report(bool const &verbose,
_config_triggers { node.attribute_value("config_triggers", false) },
_bytes { node.attribute_value("bytes", true) },
_stats { node.attribute_value("stats", true) },
_dropped_fragm_ipv4 { node.attribute_value("dropped_fragm_ipv4", false) },
_link_state { node.attribute_value("link_state", false) },
_link_state_triggers { node.attribute_value("link_state_triggers", false) },
_quota { node.attribute_value("quota", true) },

View File

@ -48,6 +48,7 @@ class Net::Report
bool const _config_triggers;
bool const _bytes;
bool const _stats;
bool const _dropped_fragm_ipv4;
bool const _link_state;
bool const _link_state_triggers;
bool const _quota;
@ -85,6 +86,7 @@ class Net::Report
bool config() const { return _config; }
bool bytes() const { return _bytes; }
bool stats() const { return _stats; }
bool dropped_fragm_ipv4() const { return _dropped_fragm_ipv4; }
bool link_state() const { return _link_state; }
bool link_state_triggers() const { return _link_state_triggers; }
};