nic_bridge: verbose mode

The verbosity mode of the NIC bridge can be toggled with the verbose attribute
(default value shown):

! <config verbose="no" />

If enabled, the NIC bridge logs sent and received packets as well as the
lifetime of interfaces connected to the bridge.

Issue #2899
This commit is contained in:
Martin Stein 2018-06-29 16:00:25 +02:00 committed by Christian Helmuth
parent 32d41388e2
commit 45347749fe
11 changed files with 153 additions and 45 deletions

View File

@ -59,7 +59,7 @@ append config {
<start name="nic_bridge" caps="200">
<resource name="RAM" quantum="24M"/>
<provides><service name="Nic"/></provides>
<config>
<config verbose="yes">
<policy label_prefix="test-lwip_httpsrv_static" ip_addr="10.0.2.55"/>
</config>
<route>

View File

@ -23,6 +23,7 @@ running as Genode processes without real network connectivity.
The static IP can be configured per client of the NIC bridge using a '<policy>'
node of the configuration. For example, the following policy assigns a static
address to a client with the session label "lighttpd".
!<start name="nic_bridge">
! ...
! <config>
@ -34,6 +35,7 @@ Of course, the client needs to configure its TCP/IP stack to use the assigned
IP address. This can be done via configuration arguments examined by the
'lwip_nic_dhcp' libc plugin. For the given example, the configuration for the
lighttpd process would look as follows.
!<start name="lighttpd">
! <config>
! <interface ip_addr="10.0.2.55"
@ -41,3 +43,11 @@ lighttpd process would look as follows.
! gateway="10.0.2.1"/>
! </config>
!</start>
The verbosity mode of the NIC bridge can be toggled with the verbose attribute
(default value shown):
! <config verbose="no" />
If enabled, the NIC bridge logs sent and received packets as well as the
lifetime of interfaces connected to the bridge.

View File

@ -108,22 +108,24 @@ void Session_component::set_ipv4_address(Ipv4_address ip_addr)
}
Session_component::Session_component(Genode::Ram_session &ram,
Genode::Region_map &rm,
Genode::Entrypoint &ep,
Genode::size_t amount,
Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size,
Mac_address vmac,
Net::Nic &nic,
char *ip_addr)
Session_component::Session_component(Genode::Ram_session &ram,
Genode::Region_map &rm,
Genode::Entrypoint &ep,
Genode::size_t amount,
Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size,
Mac_address vmac,
Net::Nic &nic,
bool const &verbose,
Genode::Session_label const &label,
char *ip_addr)
: Stream_allocator(ram, rm, amount),
Stream_dataspaces(ram, tx_buf_size, rx_buf_size),
Session_rpc_object(rm,
Stream_dataspaces::tx_ds,
Stream_dataspaces::rx_ds,
Stream_allocator::range_allocator(), ep.rpc_ep()),
Packet_handler(ep, nic.vlan()),
Packet_handler(ep, nic.vlan(), label, verbose),
_mac_node(*this, vmac),
_ipv4_node(*this),
_nic(nic)
@ -157,11 +159,16 @@ Session_component::~Session_component() {
}
Net::Root::Root(Genode::Env &env, Net::Nic &nic, Genode::Allocator &md_alloc,
Genode::Xml_node config)
Net::Root::Root(Genode::Env &env,
Net::Nic &nic,
Genode::Allocator &md_alloc,
bool const &verbose,
Genode::Xml_node config)
:
Genode::Root_component<Session_component>(env.ep(), md_alloc),
_mac_alloc(Mac_address(config.attribute_value("mac", Mac_address(DEFAULT_MAC)))),
_env(env),
_nic(nic),
_config(config) { }
_config(config),
_verbose(verbose)
{ }

View File

@ -123,15 +123,17 @@ class Net::Session_component : private Net::Stream_allocator,
* \param rx_buf_size buffer size for rx channel
* \param vmac virtual mac address
*/
Session_component(Genode::Ram_session &ram,
Genode::Region_map &rm,
Genode::Entrypoint &ep,
Genode::size_t amount,
Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size,
Mac_address vmac,
Net::Nic &nic,
char *ip_addr = 0);
Session_component(Genode::Ram_session &ram,
Genode::Region_map &rm,
Genode::Entrypoint &ep,
Genode::size_t amount,
Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size,
Mac_address vmac,
Net::Nic &nic,
bool const &verbose,
Genode::Session_label const &label,
char *ip_addr = 0);
~Session_component();
@ -196,6 +198,7 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
Genode::Env &_env;
Net::Nic &_nic;
Genode::Xml_node _config;
bool const &_verbose;
protected:
@ -207,8 +210,9 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
char ip_addr[MAX_IP_ADDR_LENGTH];
memset(ip_addr, 0, MAX_IP_ADDR_LENGTH);
Session_label label;
try {
Session_label const label = label_from_args(args);
label = label_from_args(args);
Session_policy policy(label, _config);
policy.attribute("ip_addr").value(ip_addr, sizeof(ip_addr));
} catch (Xml_node::Nonexistent_attribute) {
@ -226,7 +230,8 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
return new (md_alloc())
Session_component(_env.ram(), _env.rm(), _env.ep(),
ram_quota, tx_buf_size, rx_buf_size,
_mac_alloc.alloc(), _nic, ip_addr);
_mac_alloc.alloc(), _nic, _verbose,
label, ip_addr);
}
catch (Mac_allocator::Alloc_failed) {
Genode::warning("Mac address allocation failed!");
@ -244,8 +249,11 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
public:
Root(Genode::Env &env, Net::Nic &nic, Genode::Allocator &md_alloc,
Genode::Xml_node config);
Root(Genode::Env &env,
Net::Nic &nic,
Genode::Allocator &md_alloc,
bool const &verbose,
Genode::Xml_node config);
};
#endif /* _COMPONENT_H_ */

View File

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Boolean">
<xs:restriction base="xs:string">
<xs:enumeration value="true" />
<xs:enumeration value="yes" />
<xs:enumeration value="on" />
<xs:enumeration value="false" />
<xs:enumeration value="no" />
<xs:enumeration value="off" />
</xs:restriction>
</xs:simpleType><!-- Boolean -->
<xs:simpleType name="Session_label">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="160"/>
</xs:restriction>
</xs:simpleType><!-- Session_label -->
<xs:simpleType name="Ipv4_address">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"/>
</xs:restriction>
</xs:simpleType><!-- Ipv4_address -->
<xs:simpleType name="Mac_address">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}"/>
</xs:restriction>
</xs:simpleType><!-- Mac_address -->
<xs:element name="config">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="policy">
<xs:complexType>
<xs:attribute name="label_prefix" type="Session_label" />
<xs:attribute name="label_suffix" type="Session_label" />
<xs:attribute name="label" type="Session_label" />
<xs:attribute name="ip_addr" type="Ipv4_address" />
</xs:complexType>
</xs:element><!-- policy -->
</xs:choice>
<xs:attribute name="verbose" type="Boolean" />
<xs:attribute name="mac" type="Mac_address" />
</xs:complexType>
</xs:element><!-- config -->
</xs:schema>

View File

@ -28,12 +28,16 @@
struct Main
{
Genode::Env &env;
Genode::Entrypoint &ep { env.ep() };
Genode::Heap heap { env.ram(), env.rm() };
Genode::Attached_rom_dataspace config { env, "config" };
Net::Vlan vlan { };
Net::Nic nic { env, heap, vlan };
Net::Root root { env, nic, heap, config.xml() };
Genode::Entrypoint &ep { env.ep() };
Genode::Heap heap { env.ram(), env.rm() };
Genode::Attached_rom_dataspace config { env, "config" };
Net::Vlan vlan { };
Genode::Session_label const nic_label { "uplink" };
bool const verbose { config.xml().attribute_value("verbose", false) };
Net::Nic nic { env, heap, vlan, verbose,
nic_label };
Net::Root root { env, nic, heap, verbose,
config.xml() };
Main(Genode::Env &e) : env(e)
{

View File

@ -122,8 +122,12 @@ bool Net::Nic::handle_ip(Ethernet_frame &eth,
}
Net::Nic::Nic(Genode::Env &env, Genode::Heap &heap, Net::Vlan &vlan)
: Packet_handler(env.ep(), vlan),
Net::Nic::Nic(Genode::Env &env,
Genode::Heap &heap,
Net::Vlan &vlan,
bool const &verbose,
Session_label const &label)
: Packet_handler(env.ep(), vlan, label, verbose),
_tx_block_alloc(&heap),
_nic(env, &_tx_block_alloc, BUF_SIZE, BUF_SIZE),
_mac(_nic.mac_address().addr)

View File

@ -37,7 +37,11 @@ class Net::Nic : public Net::Packet_handler
public:
Nic(Genode::Env&, Genode::Heap&, Vlan&);
Nic(Genode::Env&,
Genode::Heap&,
Vlan&,
bool const &verbose,
Genode::Session_label const &label);
::Nic::Connection *nic() { return &_nic; }
Mac_address mac() { return _mac; }

View File

@ -81,6 +81,8 @@ void Packet_handler::handle_ethernet(void* src, Genode::size_t size)
/* parse ethernet frame header */
Size_guard size_guard(size);
Ethernet_frame &eth = Ethernet_frame::cast_from(src, size_guard);
if (_verbose) {
Genode::log("[", _label, "] rcv ", eth); }
switch (eth.type()) {
case Ethernet_frame::Type::ARP:
if (!handle_arp(eth, size_guard)) return;
@ -101,6 +103,8 @@ void Packet_handler::handle_ethernet(void* src, Genode::size_t size)
void Packet_handler::send(Ethernet_frame *eth, Genode::size_t size)
{
if (_verbose) {
Genode::log("[", _label, "] snd ", *eth); }
try {
/* copy and submit packet */
Packet_descriptor packet = source()->alloc_packet(size);
@ -113,11 +117,19 @@ void Packet_handler::send(Ethernet_frame *eth, Genode::size_t size)
}
Packet_handler::Packet_handler(Genode::Entrypoint &ep, Vlan &vlan)
Packet_handler::Packet_handler(Genode::Entrypoint &ep,
Vlan &vlan,
Genode::Session_label const &label,
bool const &verbose)
: _vlan(vlan),
_label(label),
_verbose(verbose),
_sink_ack(ep, *this, &Packet_handler::_ack_avail),
_sink_submit(ep, *this, &Packet_handler::_ready_to_submit),
_source_ack(ep, *this, &Packet_handler::_ready_to_ack),
_source_submit(ep, *this, &Packet_handler::_packet_avail),
_client_link_state(ep, *this, &Packet_handler::_link_state)
{ }
{
if (_verbose) {
Genode::log("[", _label, "] interface initialized"); }
}

View File

@ -39,8 +39,10 @@ class Net::Packet_handler
{
private:
Packet_descriptor _packet { };
Net::Vlan &_vlan;
Packet_descriptor _packet { };
Net::Vlan &_vlan;
Genode::Session_label _label;
bool const &_verbose;
/**
* submit queue not empty anymore
@ -83,7 +85,10 @@ class Net::Packet_handler
public:
Packet_handler(Genode::Entrypoint&, Vlan&);
Packet_handler(Genode::Entrypoint&,
Vlan&,
Genode::Session_label const &label,
bool const &verbose);
virtual ~Packet_handler() { }

View File

@ -1,4 +1,5 @@
TARGET = nic_bridge
LIBS = base net
SRC_CC = component.cc main.cc nic.cc packet_handler.cc
INC_DIR += $(PRG_DIR)
TARGET = nic_bridge
LIBS = base net
SRC_CC = component.cc main.cc nic.cc packet_handler.cc
CONFIG_XSD = config.xsd
INC_DIR += $(PRG_DIR)