nic_router: non-critical logs only when verbose

* Do not log events that are not critical (deadly) to the NIC router if not
  configured to be verbose,
* Print almost all log lines with a prefix of the domain name they are
  related to,
* And, do not use Genode::error and Genode::warning as they make it hard to
  read the log with the domain name prefixes.

Fixes #2840
This commit is contained in:
Martin Stein 2018-06-13 13:28:22 +02:00 committed by Norman Feske
parent 49a3a0e0d0
commit 90fcba79c6
16 changed files with 235 additions and 153 deletions

View File

@ -68,8 +68,16 @@ Net::Session_component::Interface_policy::determine_domain_name() const
Session_policy policy(_label, _config().node()); Session_policy policy(_label, _config().node());
domain_name = policy.attribute_value("domain", Domain_name()); domain_name = policy.attribute_value("domain", Domain_name());
} }
catch (Session_policy::No_policy_defined) { if (_config().verbose()) { log("No matching policy"); } } catch (Session_policy::No_policy_defined) {
catch (Xml_node::Nonexistent_attribute) { if (_config().verbose()) { log("No domain attribute in policy"); } } if (_config().verbose()) {
log("[?] no policy for downlink label \"", _label, "\""); }
}
catch (Xml_node::Nonexistent_attribute) {
if (_config().verbose()) {
log("[?] no domain attribute in policy for downlink label \"",
_label, "\"");
}
}
return domain_name; return domain_name;
} }
@ -145,13 +153,14 @@ Session_component *Net::Root::_create_session(char const *args)
max((size_t)4096, sizeof(Session_component)); max((size_t)4096, sizeof(Session_component));
if (ram_quota < session_size) { if (ram_quota < session_size) {
throw Insufficient_ram_quota(); } _invalid_downlink("NIC session RAM quota");
throw Insufficient_ram_quota();
}
if (tx_buf_size > ram_quota - session_size || if (tx_buf_size > ram_quota - session_size ||
rx_buf_size > ram_quota - session_size || rx_buf_size > ram_quota - session_size ||
tx_buf_size + rx_buf_size > ram_quota - session_size) tx_buf_size + rx_buf_size > ram_quota - session_size)
{ {
error("insufficient 'ram_quota' for session creation"); _invalid_downlink("NIC session RAM quota for buffers)");
throw Insufficient_ram_quota(); throw Insufficient_ram_quota();
} }
Session_label const label(label_from_args(args)); Session_label const label(label_from_args(args));
@ -162,7 +171,14 @@ Session_component *Net::Root::_create_session(char const *args)
_interfaces, _config()); _interfaces, _config());
} }
catch (Mac_allocator::Alloc_failed) { catch (Mac_allocator::Alloc_failed) {
error("failed to allocate MAC address"); _invalid_downlink("failed to allocate MAC address"); }
}
throw Service_denied(); throw Service_denied();
} }
void Net::Root::_invalid_downlink(char const *reason)
{
if (_config().verbose()) {
log("[?] invalid downlink (", reason, ")"); }
}

View File

@ -141,6 +141,8 @@ class Net::Root : public Genode::Root_component<Session_component>
Genode::Region_map &_region_map; Genode::Region_map &_region_map;
Interface_list &_interfaces; Interface_list &_interfaces;
void _invalid_downlink(char const *reason);
/******************** /********************
** Root_component ** ** Root_component **

View File

@ -87,7 +87,7 @@ Configuration::Configuration(Env &env,
_invalid_domain(exception.object, "name not unique"); _invalid_domain(exception.object, "name not unique");
} }
} }
catch (Domain::Invalid) { log("[?] invalid domain"); } catch (Domain::Invalid) { }
}); });
/* do parts of domain initialization that may lookup other domains */ /* do parts of domain initialization that may lookup other domains */
while (true) { while (true) {
@ -138,7 +138,7 @@ Configuration::Configuration(Env &env,
} }
/* create report generator */ /* create report generator */
_report = *new (_alloc) _report = *new (_alloc)
Report(report_node, timer, _domains, _reporter()); Report(_verbose, report_node, timer, _domains, _reporter());
} }
catch (Genode::Xml_node::Nonexistent_sub_node) { } catch (Genode::Xml_node::Nonexistent_sub_node) { }

View File

@ -21,9 +21,9 @@ enum { PKT_SIZE = 1024 };
using namespace Genode; using namespace Genode;
using namespace Net; using namespace Net;
using Message_type = Dhcp_packet::Message_type; using Message_type = Dhcp_packet::Message_type;
using Drop_packet_inform = Net::Interface::Drop_packet_inform; using Drop_packet = Net::Interface::Drop_packet;
using Dhcp_options = Dhcp_packet::Options_aggregator<Size_guard>; using Dhcp_options = Dhcp_packet::Options_aggregator<Size_guard>;
/*************** /***************
@ -93,7 +93,14 @@ Microseconds Dhcp_client::_rerequest_timeout(unsigned lease_time_div_log2)
if (timeout_sec > MAX_TIMEOUT_SEC) { if (timeout_sec > MAX_TIMEOUT_SEC) {
timeout_sec = MAX_TIMEOUT_SEC; timeout_sec = MAX_TIMEOUT_SEC;
warning("Had to prune the state timeout of DHCP client"); if (_interface.config().verbose()) {
try {
log("[", _interface.domain(), "] prune re-request timeout of "
"DHCP client");
}
catch (Pointer<Domain>::Invalid) {
log("[?] prune re-request timeout of DHCP client"); }
}
} }
return Microseconds(timeout_sec * 1000UL * 1000UL); return Microseconds(timeout_sec * 1000UL * 1000UL);
} }
@ -115,26 +122,27 @@ void Dhcp_client::handle_ip(Ethernet_frame &eth,
{ {
if (eth.dst() != _interface.router_mac() && if (eth.dst() != _interface.router_mac() &&
eth.dst() != Mac_address(0xff)) eth.dst() != Mac_address(0xff))
{ throw Drop_packet_inform("DHCP client expects Ethernet targeting the router"); } {
throw Drop_packet("DHCP client expects Ethernet targeting the router"); }
Ipv4_packet &ip = eth.data<Ipv4_packet>(size_guard); Ipv4_packet &ip = eth.data<Ipv4_packet>(size_guard);
if (ip.protocol() != Ipv4_packet::Protocol::UDP) { if (ip.protocol() != Ipv4_packet::Protocol::UDP) {
throw Drop_packet_inform("DHCP client expects UDP packet"); } throw Drop_packet("DHCP client expects UDP packet"); }
Udp_packet &udp = ip.data<Udp_packet>(size_guard); Udp_packet &udp = ip.data<Udp_packet>(size_guard);
if (!Dhcp_packet::is_dhcp(&udp)) { if (!Dhcp_packet::is_dhcp(&udp)) {
throw Drop_packet_inform("DHCP client expects DHCP packet"); } throw Drop_packet("DHCP client expects DHCP packet"); }
Dhcp_packet &dhcp = udp.data<Dhcp_packet>(size_guard); Dhcp_packet &dhcp = udp.data<Dhcp_packet>(size_guard);
if (dhcp.op() != Dhcp_packet::REPLY) { if (dhcp.op() != Dhcp_packet::REPLY) {
throw Drop_packet_inform("DHCP client expects DHCP reply"); } throw Drop_packet("DHCP client expects DHCP reply"); }
if (dhcp.client_mac() != _interface.router_mac()) { if (dhcp.client_mac() != _interface.router_mac()) {
throw Drop_packet_inform("DHCP client expects DHCP targeting the router"); } throw Drop_packet("DHCP client expects DHCP targeting the router"); }
try { _handle_dhcp_reply(dhcp); } try { _handle_dhcp_reply(dhcp); }
catch (Dhcp_packet::Option_not_found) { catch (Dhcp_packet::Option_not_found) {
throw Drop_packet_inform("DHCP client misses DHCP option"); } throw Drop_packet("DHCP client misses DHCP option"); }
} }
@ -147,7 +155,7 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp)
case State::SELECT: case State::SELECT:
if (msg_type != Message_type::OFFER) { if (msg_type != Message_type::OFFER) {
throw Drop_packet_inform("DHCP client expects an offer"); throw Drop_packet("DHCP client expects an offer");
} }
_set_state(State::REQUEST, _config().dhcp_request_timeout()); _set_state(State::REQUEST, _config().dhcp_request_timeout());
_send(Message_type::REQUEST, Ipv4_address(), _send(Message_type::REQUEST, Ipv4_address(),
@ -158,7 +166,7 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp)
case State::REQUEST: case State::REQUEST:
{ {
if (msg_type != Message_type::ACK) { if (msg_type != Message_type::ACK) {
throw Drop_packet_inform("DHCP client expects an acknowledgement"); throw Drop_packet("DHCP client expects an acknowledgement");
} }
_lease_time_sec = dhcp.option<Dhcp_packet::Ip_lease_time>().value(); _lease_time_sec = dhcp.option<Dhcp_packet::Ip_lease_time>().value();
_set_state(State::BOUND, _rerequest_timeout(1)); _set_state(State::BOUND, _rerequest_timeout(1));
@ -175,13 +183,13 @@ void Dhcp_client::_handle_dhcp_reply(Dhcp_packet &dhcp)
case State::REBIND: case State::REBIND:
if (msg_type != Message_type::ACK) { if (msg_type != Message_type::ACK) {
throw Drop_packet_inform("DHCP client expects an acknowledgement"); throw Drop_packet("DHCP client expects an acknowledgement");
} }
_set_state(State::BOUND, _rerequest_timeout(1)); _set_state(State::BOUND, _rerequest_timeout(1));
_lease_time_sec = dhcp.option<Dhcp_packet::Ip_lease_time>().value(); _lease_time_sec = dhcp.option<Dhcp_packet::Ip_lease_time>().value();
break; break;
default: throw Drop_packet_inform("DHCP client doesn't expect a packet"); default: throw Drop_packet("DHCP client doesn't expect a packet");
} }
} }

View File

@ -15,6 +15,7 @@
#include <dhcp_server.h> #include <dhcp_server.h>
#include <interface.h> #include <interface.h>
#include <domain.h> #include <domain.h>
#include <configuration.h>
using namespace Net; using namespace Net;
using namespace Genode; using namespace Genode;
@ -24,8 +25,18 @@ using namespace Genode;
** Dhcp_server ** ** Dhcp_server **
*****************/ *****************/
void Dhcp_server::_invalid(Domain &domain,
char const *reason)
{
if (domain.config().verbose()) {
log("[", domain, "] invalid DHCP server (", reason, ")"); }
throw Domain::Invalid();
}
Dhcp_server::Dhcp_server(Xml_node const node, Dhcp_server::Dhcp_server(Xml_node const node,
Domain const &domain, Domain &domain,
Allocator &alloc, Allocator &alloc,
Ipv4_address_prefix const &interface, Ipv4_address_prefix const &interface,
Domain_tree &domains) Domain_tree &domains)
@ -40,17 +51,13 @@ Dhcp_server::Dhcp_server(Xml_node const node,
_ip_alloc(alloc, _ip_count) _ip_alloc(alloc, _ip_count)
{ {
if (!interface.prefix_matches(_ip_first)) { if (!interface.prefix_matches(_ip_first)) {
log("[", domain, "] first IP of DHCP server does not match domain subnet"); _invalid(domain, "first IP does not match domain subnet"); }
throw Domain::Invalid();
}
if (!interface.prefix_matches(_ip_last)) { if (!interface.prefix_matches(_ip_last)) {
log("[", domain, "] last IP of DHCP server does not match domain subnet"); _invalid(domain, "last IP does not match domain subnet"); }
throw Domain::Invalid();
}
if (interface.address.is_in_range(_ip_first, _ip_last)) { if (interface.address.is_in_range(_ip_first, _ip_last)) {
log("[", domain, "] IP range of DHCP server contains IP address of domain"); _invalid(domain, "IP range contains IP address of domain"); }
throw Domain::Invalid();
}
} }

View File

@ -28,6 +28,7 @@
namespace Net { namespace Net {
class Configuration;
class Dhcp_server; class Dhcp_server;
class Dhcp_allocation; class Dhcp_allocation;
class Dhcp_allocation; class Dhcp_allocation;
@ -54,6 +55,9 @@ class Net::Dhcp_server : private Genode::Noncopyable
Genode::uint32_t const _ip_count; Genode::uint32_t const _ip_count;
Genode::Bit_allocator_dynamic _ip_alloc; Genode::Bit_allocator_dynamic _ip_alloc;
void _invalid(Domain &domain,
char const *reason);
Genode::Microseconds _init_ip_lease_time(Genode::Xml_node const node); Genode::Microseconds _init_ip_lease_time(Genode::Xml_node const node);
Pointer<Domain> _init_dns_server_from(Genode::Xml_node const node, Pointer<Domain> _init_dns_server_from(Genode::Xml_node const node,
@ -67,7 +71,7 @@ class Net::Dhcp_server : private Genode::Noncopyable
struct Invalid : Genode::Exception { }; struct Invalid : Genode::Exception { };
Dhcp_server(Genode::Xml_node const node, Dhcp_server(Genode::Xml_node const node,
Domain const &domain, Domain &domain,
Genode::Allocator &alloc, Genode::Allocator &alloc,
Ipv4_address_prefix const &interface, Ipv4_address_prefix const &interface,
Domain_tree &domains); Domain_tree &domains);

View File

@ -40,6 +40,26 @@ Domain_base::Domain_base(Xml_node const node)
** Domain ** ** Domain **
************/ ************/
void Domain::_log_ip_config() const
{
Ipv4_config const &ip_config = *_ip_config;
if (_config.verbose()) {
if (!ip_config.valid &&
(ip_config.interface_valid ||
ip_config.gateway_valid ||
ip_config.dns_server_valid))
{
log("[", *this, "] malformed ", _ip_config_dynamic ? "dynamic" :
"static", "IP config: ", ip_config);
}
}
if (_config.verbose_domain_state()) {
log("[", *this, "] ", _ip_config_dynamic ? "dynamic" : "static",
" IP config: ", ip_config);
}
}
void Domain::ip_config(Ipv4_config const &new_ip_config) void Domain::ip_config(Ipv4_config const &new_ip_config)
{ {
if (!_ip_config_dynamic) { if (!_ip_config_dynamic) {
@ -63,10 +83,7 @@ void Domain::ip_config(Ipv4_config const &new_ip_config)
} }
/* overwrite old with new IP config */ /* overwrite old with new IP config */
_ip_config.construct(new_ip_config); _ip_config.construct(new_ip_config);
_log_ip_config();
/* log the event */
if (_config.verbose_domain_state()) {
log("[", *this, "] IP config: ", ip_config()); }
/* attach all dependent interfaces to new IP config if it is valid */ /* attach all dependent interfaces to new IP config if it is valid */
if (ip_config().valid) { if (ip_config().valid) {
@ -167,7 +184,10 @@ void Domain::_read_transport_rules(Cstring const &protocol,
void Domain::print(Output &output) const void Domain::print(Output &output) const
{ {
Genode::print(output, _name); if (_name == Domain_name()) {
Genode::print(output, "?");
} else {
Genode::print(output, _name); }
} }
@ -182,13 +202,13 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
_config.verbose_packets()), _config.verbose_packets()),
_label(_node.attribute_value("label", String<160>()).string()) _label(_node.attribute_value("label", String<160>()).string())
{ {
_log_ip_config();
if (_name == Domain_name()) { if (_name == Domain_name()) {
log("[?] Missing name attribute in domain node"); _invalid("missing name attribute"); }
throw Invalid();
}
if (_config.verbose_domain_state()) { if (_config.verbose_domain_state()) {
log("[", *this, "] NIC sessions: ", _interface_cnt); log("[", *this, "] NIC sessions: ", _interface_cnt); }
}
} }

View File

@ -109,6 +109,8 @@ class Net::Domain : public Domain_base,
void _invalid(char const *reason) const; void _invalid(char const *reason) const;
void _log_ip_config() const;
void __FIXME__dissolve_foreign_arp_waiters(); void __FIXME__dissolve_foreign_arp_waiters();
public: public:

View File

@ -28,8 +28,6 @@ using Genode::Deallocator;
using Genode::size_t; using Genode::size_t;
using Genode::uint32_t; using Genode::uint32_t;
using Genode::log; using Genode::log;
using Genode::error;
using Genode::warning;
using Genode::Exception; using Genode::Exception;
using Genode::construct_at; using Genode::construct_at;
using Genode::Quota_guard; using Genode::Quota_guard;
@ -364,7 +362,7 @@ Interface::_new_link(L3_protocol const protocol,
remote, _timer, _config(), protocol }; remote, _timer, _config(), protocol };
} }
catch (Quota_guard<Ram_quota>::Limit_exceeded) { catch (Quota_guard<Ram_quota>::Limit_exceeded) {
throw Drop_packet_inform( throw Drop_packet(
"RAM quota exhausted during allocation of TCP link"); "RAM quota exhausted during allocation of TCP link");
} }
break; break;
@ -375,7 +373,7 @@ Interface::_new_link(L3_protocol const protocol,
remote, _timer, _config(), protocol }; remote, _timer, _config(), protocol };
} }
catch (Quota_guard<Ram_quota>::Limit_exceeded) { catch (Quota_guard<Ram_quota>::Limit_exceeded) {
throw Drop_packet_inform( throw Drop_packet(
"RAM quota exhausted during allocation of UDP link"); "RAM quota exhausted during allocation of UDP link");
} }
break; break;
@ -386,7 +384,7 @@ Interface::_new_link(L3_protocol const protocol,
remote, _timer, _config(), protocol }; remote, _timer, _config(), protocol };
} }
catch (Quota_guard<Ram_quota>::Limit_exceeded) { catch (Quota_guard<Ram_quota>::Limit_exceeded) {
throw Drop_packet_inform( throw Drop_packet(
"RAM quota exhausted during allocation of ICMP link"); "RAM quota exhausted during allocation of ICMP link");
} }
break; break;
@ -428,7 +426,7 @@ void Interface::_adapt_eth(Ethernet_frame &eth,
{ {
Ipv4_config const &remote_ip_cfg = remote_domain.ip_config(); Ipv4_config const &remote_ip_cfg = remote_domain.ip_config();
if (!remote_ip_cfg.valid) { if (!remote_ip_cfg.valid) {
throw Drop_packet_inform("target domain has yet no IP config"); throw Drop_packet("target domain has yet no IP config");
} }
Ipv4_address const &hop_ip = remote_domain.next_hop(dst_ip); Ipv4_address const &hop_ip = remote_domain.next_hop(dst_ip);
try { eth.dst(remote_domain.arp_cache().find_by_ip(hop_ip).mac()); } try { eth.dst(remote_domain.arp_cache().find_by_ip(hop_ip).mac()); }
@ -439,7 +437,7 @@ void Interface::_adapt_eth(Ethernet_frame &eth,
}); });
try { new (_alloc) Arp_waiter { *this, remote_domain, hop_ip, pkt }; } try { new (_alloc) Arp_waiter { *this, remote_domain, hop_ip, pkt }; }
catch (Quota_guard<Ram_quota>::Limit_exceeded) { catch (Quota_guard<Ram_quota>::Limit_exceeded) {
throw Drop_packet_inform( throw Drop_packet(
"RAM quota exhausted during allocation of ARP waiter"); "RAM quota exhausted during allocation of ARP waiter");
} }
throw Packet_postponed(); throw Packet_postponed();
@ -461,7 +459,7 @@ void Interface::_nat_link_and_pass(Ethernet_frame &eth,
try { try {
Nat_rule &nat = remote_domain.nat_rules().find_by_domain(local_domain); Nat_rule &nat = remote_domain.nat_rules().find_by_domain(local_domain);
if(_config().verbose()) { if(_config().verbose()) {
log("Using NAT rule: ", nat); } log("[", local_domain, "] using NAT rule: ", nat); }
_src_port(prot, prot_base, nat.port_alloc(prot).alloc()); _src_port(prot, prot_base, nat.port_alloc(prot).alloc());
ip.src(remote_domain.ip_config().interface.address); ip.src(remote_domain.ip_config().interface.address);
@ -552,9 +550,8 @@ void Interface::_release_dhcp_allocation(Dhcp_allocation &allocation,
Domain &local_domain) Domain &local_domain)
{ {
if (_config().verbose()) { if (_config().verbose()) {
log("Release DHCP allocation: ", allocation, log("[", local_domain, "] release DHCP allocation: ", allocation); }
" at ", local_domain);
}
_dhcp_allocations.remove(allocation); _dhcp_allocations.remove(allocation);
} }
@ -571,9 +568,8 @@ void Interface::_new_dhcp_allocation(Ethernet_frame &eth,
_dhcp_allocations.insert(allocation); _dhcp_allocations.insert(allocation);
if (_config().verbose()) { if (_config().verbose()) {
log("Offer DHCP allocation: ", allocation, log("[", local_domain, "] offer DHCP allocation: ", allocation); }
" at ", local_domain);
}
_send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(), _send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(),
allocation.ip(), allocation.ip(),
Dhcp_packet::Message_type::OFFER, Dhcp_packet::Message_type::OFFER,
@ -581,7 +577,7 @@ void Interface::_new_dhcp_allocation(Ethernet_frame &eth,
local_domain.ip_config().interface); local_domain.ip_config().interface);
} }
catch (Quota_guard<Ram_quota>::Limit_exceeded) { catch (Quota_guard<Ram_quota>::Limit_exceeded) {
throw Drop_packet_inform( throw Drop_packet(
"RAM quota exhausted during allocation of DHCP allocation"); "RAM quota exhausted during allocation of DHCP allocation");
} }
} }
@ -644,8 +640,8 @@ void Interface::_handle_dhcp_request(Ethernet_frame &eth,
allocation.set_bound(); allocation.set_bound();
allocation.lifetime(dhcp_srv.ip_lease_time()); allocation.lifetime(dhcp_srv.ip_lease_time());
if (_config().verbose()) { if (_config().verbose()) {
log("Bind DHCP allocation: ", allocation, log("[", local_domain, "] bind DHCP allocation: ",
" at ", local_domain); allocation);
} }
_send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(), _send_dhcp_reply(dhcp_srv, eth.src(), dhcp.client_mac(),
allocation.ip(), allocation.ip(),
@ -675,10 +671,10 @@ void Interface::_handle_dhcp_request(Ethernet_frame &eth,
_destroy_dhcp_allocation(allocation, local_domain); _destroy_dhcp_allocation(allocation, local_domain);
return; return;
case Dhcp_packet::Message_type::NAK: throw Drop_packet_warn("DHCP NAK from client"); case Dhcp_packet::Message_type::NAK: throw Drop_packet("DHCP NAK from client");
case Dhcp_packet::Message_type::OFFER: throw Drop_packet_warn("DHCP OFFER from client"); case Dhcp_packet::Message_type::OFFER: throw Drop_packet("DHCP OFFER from client");
case Dhcp_packet::Message_type::ACK: throw Drop_packet_warn("DHCP ACK from client"); case Dhcp_packet::Message_type::ACK: throw Drop_packet("DHCP ACK from client");
default: throw Drop_packet_warn("DHCP request with broken message type"); default: throw Drop_packet("DHCP request with broken message type");
} }
} }
catch (Dhcp_allocation_tree::No_match) { catch (Dhcp_allocation_tree::No_match) {
@ -689,21 +685,18 @@ void Interface::_handle_dhcp_request(Ethernet_frame &eth,
_new_dhcp_allocation(eth, dhcp, dhcp_srv, local_domain); _new_dhcp_allocation(eth, dhcp, dhcp_srv, local_domain);
return; return;
case Dhcp_packet::Message_type::REQUEST: throw Drop_packet_warn("DHCP REQUEST from client without offered/acked IP"); case Dhcp_packet::Message_type::REQUEST: throw Drop_packet("DHCP REQUEST from client without offered/acked IP");
case Dhcp_packet::Message_type::DECLINE: throw Drop_packet_warn("DHCP DECLINE from client without offered/acked IP"); case Dhcp_packet::Message_type::DECLINE: throw Drop_packet("DHCP DECLINE from client without offered/acked IP");
case Dhcp_packet::Message_type::RELEASE: throw Drop_packet_warn("DHCP RELEASE from client without offered/acked IP"); case Dhcp_packet::Message_type::RELEASE: throw Drop_packet("DHCP RELEASE from client without offered/acked IP");
case Dhcp_packet::Message_type::NAK: throw Drop_packet_warn("DHCP NAK from client"); case Dhcp_packet::Message_type::NAK: throw Drop_packet("DHCP NAK from client");
case Dhcp_packet::Message_type::OFFER: throw Drop_packet_warn("DHCP OFFER from client"); case Dhcp_packet::Message_type::OFFER: throw Drop_packet("DHCP OFFER from client");
case Dhcp_packet::Message_type::ACK: throw Drop_packet_warn("DHCP ACK from client"); case Dhcp_packet::Message_type::ACK: throw Drop_packet("DHCP ACK from client");
default: throw Drop_packet_warn("DHCP request with broken message type"); default: throw Drop_packet("DHCP request with broken message type");
} }
} }
} }
catch (Dhcp_packet::Option_not_found exception) { catch (Dhcp_packet::Option_not_found exception) {
throw Drop_packet("DHCP request misses required option"); }
throw Drop_packet_warn("DHCP request misses required option ",
(unsigned long)exception.code);
}
} }
@ -814,8 +807,9 @@ void Interface::_handle_icmp_query(Ethernet_frame &eth,
Link_side &remote_side = client ? link.server() : link.client(); Link_side &remote_side = client ? link.server() : link.client();
Domain &remote_domain = remote_side.domain(); Domain &remote_domain = remote_side.domain();
if (_config().verbose()) { if (_config().verbose()) {
log("Using ", l3_protocol_name(prot), " link: ", link); } log("[", local_domain, "] using ", l3_protocol_name(prot),
" link: ", link);
}
_adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain);
ip.src(remote_side.dst_ip()); ip.src(remote_side.dst_ip());
ip.dst(remote_side.src_ip()); ip.dst(remote_side.src_ip());
@ -836,7 +830,7 @@ void Interface::_handle_icmp_query(Ethernet_frame &eth,
local_domain.icmp_rules().longest_prefix_match(ip.dst()); local_domain.icmp_rules().longest_prefix_match(ip.dst());
if(_config().verbose()) { if(_config().verbose()) {
log("Using ICMP rule: ", rule); } log("[", local_domain, "] using ICMP rule: ", rule); }
Domain &remote_domain = rule.domain(); Domain &remote_domain = rule.domain();
_adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain);
@ -862,7 +856,7 @@ void Interface::_handle_icmp_error(Ethernet_frame &eth,
/* drop packet if embedded IP checksum invalid */ /* drop packet if embedded IP checksum invalid */
Ipv4_packet &embed_ip = icmp.data<Ipv4_packet>(size_guard); Ipv4_packet &embed_ip = icmp.data<Ipv4_packet>(size_guard);
if (embed_ip.checksum_error()) { if (embed_ip.checksum_error()) {
throw Drop_packet_inform("bad checksum in IP packet embedded in ICMP error"); throw Drop_packet("bad checksum in IP packet embedded in ICMP error");
} }
/* get link identity of the embeddeded transport packet */ /* get link identity of the embeddeded transport packet */
L3_protocol const embed_prot = embed_ip.protocol(); L3_protocol const embed_prot = embed_ip.protocol();
@ -879,8 +873,9 @@ void Interface::_handle_icmp_error(Ethernet_frame &eth,
/* print out that the link is used */ /* print out that the link is used */
if (_config().verbose()) { if (_config().verbose()) {
log("Using ", l3_protocol_name(embed_prot), " link: ", link); } log("[", local_domain, "] using ", l3_protocol_name(embed_prot),
" link: ", link);
}
/* adapt source and destination of Ethernet frame and IP packet */ /* adapt source and destination of Ethernet frame and IP packet */
_adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain);
if (remote_side.dst_ip() == remote_domain.ip_config().interface.address) { if (remote_side.dst_ip() == remote_domain.ip_config().interface.address) {
@ -909,7 +904,7 @@ void Interface::_handle_icmp_error(Ethernet_frame &eth,
} }
/* drop packet if there is no matching link */ /* drop packet if there is no matching link */
catch (Link_side_tree::No_match) { catch (Link_side_tree::No_match) {
throw Drop_packet_inform("no link that matches packet embedded in ICMP error"); } throw Drop_packet("no link that matches packet embedded in ICMP error"); }
} }
@ -925,14 +920,14 @@ void Interface::_handle_icmp(Ethernet_frame &eth,
/* drop packet if ICMP checksum is invalid */ /* drop packet if ICMP checksum is invalid */
Icmp_packet &icmp = *reinterpret_cast<Icmp_packet *>(prot_base); Icmp_packet &icmp = *reinterpret_cast<Icmp_packet *>(prot_base);
if (icmp.checksum_error(size_guard.unconsumed())) { if (icmp.checksum_error(size_guard.unconsumed())) {
throw Drop_packet_inform("bad ICMP checksum"); throw Drop_packet("bad ICMP checksum");
} }
/* select ICMP message type */ /* select ICMP message type */
switch (icmp.type()) { switch (icmp.type()) {
case Icmp_packet::Type::ECHO_REPLY: case Icmp_packet::Type::ECHO_REPLY:
case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, pkt, prot, prot_base, prot_size, local_domain); break; case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, pkt, prot, prot_base, prot_size, local_domain); break;
case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, pkt, local_domain, icmp, prot_size); break; case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, pkt, local_domain, icmp, prot_size); break;
default: Drop_packet_inform("unknown ICMP message type"); } default: Drop_packet("unknown ICMP message type"); }
} }
@ -999,8 +994,9 @@ void Interface::_handle_ip(Ethernet_frame &eth,
Link_side &remote_side = client ? link.server() : link.client(); Link_side &remote_side = client ? link.server() : link.client();
Domain &remote_domain = remote_side.domain(); Domain &remote_domain = remote_side.domain();
if (_config().verbose()) { if (_config().verbose()) {
log("Using ", l3_protocol_name(prot), " link: ", link); } log("[", local_domain, "] using ", l3_protocol_name(prot),
" link: ", link);
}
_adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain);
ip.src(remote_side.dst_ip()); ip.src(remote_side.dst_ip());
ip.dst(remote_side.src_ip()); ip.dst(remote_side.src_ip());
@ -1022,8 +1018,9 @@ void Interface::_handle_ip(Ethernet_frame &eth,
_forward_rules(local_domain, prot).find_by_port(local_id.dst_port); _forward_rules(local_domain, prot).find_by_port(local_id.dst_port);
if(_config().verbose()) { if(_config().verbose()) {
log("Using forward rule: ", l3_protocol_name(prot), " ", rule); } log("[", local_domain, "] using forward rule: ",
l3_protocol_name(prot), " ", rule);
}
Domain &remote_domain = rule.domain(); Domain &remote_domain = rule.domain();
_adapt_eth(eth, rule.to(), pkt, remote_domain); _adapt_eth(eth, rule.to(), pkt, remote_domain);
ip.dst(rule.to()); ip.dst(rule.to());
@ -1042,9 +1039,9 @@ void Interface::_handle_ip(Ethernet_frame &eth,
transport_rule.permit_rule(local_id.dst_port); transport_rule.permit_rule(local_id.dst_port);
if(_config().verbose()) { if(_config().verbose()) {
log("Using ", l3_protocol_name(prot), " rule: ", transport_rule, log("[", local_domain, "] using ", l3_protocol_name(prot),
" ", permit_rule); } " rule: ", transport_rule, " ", permit_rule);
}
Domain &remote_domain = permit_rule.domain(); Domain &remote_domain = permit_rule.domain();
_adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain);
_nat_link_and_pass(eth, size_guard, ip, prot, prot_base, prot_size, _nat_link_and_pass(eth, size_guard, ip, prot, prot_base, prot_size,
@ -1062,7 +1059,7 @@ void Interface::_handle_ip(Ethernet_frame &eth,
local_domain.ip_rules().longest_prefix_match(ip.dst()); local_domain.ip_rules().longest_prefix_match(ip.dst());
if(_config().verbose()) { if(_config().verbose()) {
log("Using IP rule: ", rule); } log("[", local_domain, "] using IP rule: ", rule); }
Domain &remote_domain = rule.domain(); Domain &remote_domain = rule.domain();
_adapt_eth(eth, ip.dst(), pkt, remote_domain); _adapt_eth(eth, ip.dst(), pkt, remote_domain);
@ -1078,7 +1075,7 @@ void Interface::_handle_ip(Ethernet_frame &eth,
_send_icmp_dst_unreachable(local_intf, eth, ip, _send_icmp_dst_unreachable(local_intf, eth, ip,
Icmp_packet::Code::DST_NET_UNREACHABLE); Icmp_packet::Code::DST_NET_UNREACHABLE);
if (_config().verbose()) { if (_config().verbose()) {
log("Unroutable packet"); } log("[", local_domain, "] unroutable packet"); }
} }
@ -1125,7 +1122,7 @@ void Interface::_handle_arp_reply(Ethernet_frame &eth,
/* check wether a matching ARP cache entry already exists */ /* check wether a matching ARP cache entry already exists */
local_domain.arp_cache().find_by_ip(arp.src_ip()); local_domain.arp_cache().find_by_ip(arp.src_ip());
if (_config().verbose()) { if (_config().verbose()) {
log("ARP entry already exists"); } log("[", local_domain, "] ARP entry already exists"); }
} }
catch (Arp_cache::No_match) { catch (Arp_cache::No_match) {
@ -1189,7 +1186,7 @@ void Interface::_handle_arp_request(Ethernet_frame &eth,
if (arp.src_ip() == arp.dst_ip()) { if (arp.src_ip() == arp.dst_ip()) {
/* gratuitous ARP requests are not really necessary */ /* gratuitous ARP requests are not really necessary */
throw Drop_packet_inform("gratuitous ARP request"); throw Drop_packet("gratuitous ARP request");
} else if (arp.dst_ip() == local_intf.address) { } else if (arp.dst_ip() == local_intf.address) {
@ -1208,7 +1205,7 @@ void Interface::_handle_arp_request(Ethernet_frame &eth,
if (local_ip_cfg.gateway_valid) { if (local_ip_cfg.gateway_valid) {
/* leave request up to the gateway of the domain */ /* leave request up to the gateway of the domain */
throw Drop_packet_inform("leave ARP request up to gateway"); throw Drop_packet("leave ARP request up to gateway");
} else { } else {
@ -1226,12 +1223,12 @@ void Interface::_handle_arp(Ethernet_frame &eth,
/* ignore ARP regarding protocols other than IPv4 via ethernet */ /* ignore ARP regarding protocols other than IPv4 via ethernet */
Arp_packet &arp = eth.data<Arp_packet>(size_guard); Arp_packet &arp = eth.data<Arp_packet>(size_guard);
if (!arp.ethernet_ipv4()) { if (!arp.ethernet_ipv4()) {
error("ARP for unknown protocol"); } throw Drop_packet("ARP for unknown protocol"); }
switch (arp.opcode()) { switch (arp.opcode()) {
case Arp_packet::REPLY: _handle_arp_reply(eth, size_guard, arp, local_domain); break; case Arp_packet::REPLY: _handle_arp_reply(eth, size_guard, arp, local_domain); break;
case Arp_packet::REQUEST: _handle_arp_request(eth, size_guard, arp, local_domain); break; case Arp_packet::REQUEST: _handle_arp_request(eth, size_guard, arp, local_domain); break;
default: error("unknown ARP operation"); } default: throw Drop_packet("unknown ARP operation"); }
} }
@ -1251,7 +1248,10 @@ void Interface::_continue_handle_eth(Packet_descriptor const &pkt)
{ {
Size_guard size_guard(pkt.size()); Size_guard size_guard(pkt.size());
try { _handle_eth(_sink.packet_content(pkt), size_guard, pkt); } try { _handle_eth(_sink.packet_content(pkt), size_guard, pkt); }
catch (Packet_postponed) { error("failed twice to handle packet"); } catch (Packet_postponed) {
if (_config().verbose()) {
log("[", _domain(), "] drop packet (handling postponed twice)"); }
}
_ack_packet(pkt); _ack_packet(pkt);
} }
@ -1314,23 +1314,44 @@ void Interface::_handle_eth(void *const eth_base,
default: throw Bad_network_protocol(); } default: throw Bad_network_protocol(); }
} }
} }
catch (Drop_packet_warn exception) { warning("[", local_domain, "] drop packet: ", exception.msg); } catch (Dhcp_server::Alloc_ip_failed) {
catch (Dhcp_server::Alloc_ip_failed) { error ("[", local_domain, "] failed to allocate IP for DHCP client"); } if (_config().verbose()) {
catch (Port_allocator_guard::Out_of_indices) { error ("[", local_domain, "] no available NAT ports"); } log("[", local_domain, "] failed to allocate IP for DHCP "
catch (Domain::No_next_hop) { error ("[", local_domain, "] cannot find next hop"); } "client");
catch (Alloc_dhcp_msg_buffer_failed) { error ("[", local_domain, "] failed to allocate buffer for DHCP reply"); } }
}
catch (Port_allocator_guard::Out_of_indices) {
if (_config().verbose()) {
log("[", local_domain, "] no available NAT ports"); }
}
catch (Domain::No_next_hop) {
if (_config().verbose()) {
log("[", local_domain, "] cannot find next hop"); }
}
catch (Alloc_dhcp_msg_buffer_failed) {
if (_config().verbose()) {
log("[", local_domain, "] failed to allocate buffer for "
"DHCP reply");
}
}
catch (Bad_network_protocol) { catch (Bad_network_protocol) {
if (_config().verbose()) { if (_config().verbose()) {
log("[", local_domain, "] unknown network layer protocol"); } log("[", local_domain, "] unknown network layer "
"protocol");
}
} }
catch (Drop_packet_inform exception) { catch (Drop_packet exception) {
if (_config().verbose()) { if (_config().verbose()) {
log("[", local_domain, "] drop packet: ", exception.msg); } log("[", local_domain, "] drop packet (",
exception.reason, ")");
}
} }
} }
catch (Size_guard::Exceeded) { catch (Size_guard::Exceeded) {
if (_config().verbose()) { if (_config().verbose()) {
log("[", local_domain, "] drop packet: packet size-guard exceeded"); } log("[", local_domain, "] drop packet: packet size-guard "
"exceeded");
}
} }
} }
catch (Pointer<Domain>::Invalid) { catch (Pointer<Domain>::Invalid) {
@ -1720,7 +1741,10 @@ void Interface::handle_config_3()
void Interface::_ack_packet(Packet_descriptor const &pkt) void Interface::_ack_packet(Packet_descriptor const &pkt)
{ {
if (!_sink.ready_to_ack()) { if (!_sink.ready_to_ack()) {
error("ack state FULL"); if (_config().verbose()) {
log("[", _domain(), "] leak packet (sink not ready to "
"acknowledge)");
}
return; return;
} }
_sink.acknowledge_packet(pkt); _sink.acknowledge_packet(pkt);
@ -1729,7 +1753,11 @@ void Interface::_ack_packet(Packet_descriptor const &pkt)
void Interface::cancel_arp_waiting(Arp_waiter &waiter) void Interface::cancel_arp_waiting(Arp_waiter &waiter)
{ {
warning("waiting for ARP cancelled"); if (_config().verbose()) {
try { log("[", _domain(), "] drop packet (ARP got cancelled)"); }
catch (Pointer<Domain>::Invalid) {
log("[?] drop packet (ARP got cancelled)"); }
}
_ack_packet(waiter.packet()); _ack_packet(waiter.packet());
destroy(_alloc, &waiter); destroy(_alloc, &waiter);
} }

View File

@ -305,20 +305,11 @@ class Net::Interface : private Interface_list::Element
struct Packet_postponed : Genode::Exception { }; struct Packet_postponed : Genode::Exception { };
struct Alloc_dhcp_msg_buffer_failed : Genode::Exception { }; struct Alloc_dhcp_msg_buffer_failed : Genode::Exception { };
struct Drop_packet_inform : Genode::Exception struct Drop_packet : Genode::Exception
{ {
Genode::String<128> msg; char const *reason;
template <typename... ARGS> Drop_packet(char const *reason) : reason(reason) { }
Drop_packet_inform(ARGS... args) : msg({args...}) { }
};
struct Drop_packet_warn : Genode::Exception
{
Genode::String<128> msg;
template <typename... ARGS>
Drop_packet_warn(ARGS... args) : msg({args...}) { }
}; };
Interface(Genode::Entrypoint &ep, Interface(Genode::Entrypoint &ep,
@ -395,14 +386,15 @@ class Net::Interface : private Interface_list::Element
** Accessors ** ** Accessors **
***************/ ***************/
Domain &domain() { return _domain(); } Configuration const &config() const { return _config(); }
Mac_address const &router_mac() const { return _router_mac; } Domain &domain() { return _domain(); }
Mac_address const &mac() const { return _mac; } Mac_address const &router_mac() const { return _router_mac; }
Arp_waiter_list &own_arp_waiters() { return _own_arp_waiters; } Mac_address const &mac() const { return _mac; }
Signal_handler &sink_ack() { return _sink_ack; } Arp_waiter_list &own_arp_waiters() { return _own_arp_waiters; }
Signal_handler &sink_submit() { return _sink_submit; } Signal_handler &sink_ack() { return _sink_ack; }
Signal_handler &source_ack() { return _source_ack; } Signal_handler &sink_submit() { return _sink_submit; }
Signal_handler &source_submit() { return _source_submit; } Signal_handler &source_ack() { return _source_ack; }
Signal_handler &source_submit() { return _source_submit; }
void session_link_state_sigh(Genode::Signal_context_capability sigh); void session_link_state_sigh(Genode::Signal_context_capability sigh);
}; };

View File

@ -25,17 +25,14 @@ Ipv4_config::Ipv4_config(Ipv4_address_prefix interface,
Ipv4_address dns_server) Ipv4_address dns_server)
: :
interface(interface), gateway(gateway), dns_server(dns_server) interface(interface), gateway(gateway), dns_server(dns_server)
{ { }
if (!valid && (interface_valid || gateway_valid)) {
error("Bad IP configuration ", *this); }
}
void Ipv4_config::print(Output &output) const void Ipv4_config::print(Output &output) const
{ {
if (valid) { if (valid) {
Genode::print(output, "interface ", interface, ", gateway ", gateway, Genode::print(output, "interface ", interface, ", gateway ", gateway,
", DNS server ", dns_server, " p2p ", point_to_point); } ", DNS server ", dns_server, " P2P ", point_to_point); }
else { else {
Genode::print(output, "none"); } Genode::print(output, "none"); }
} }

View File

@ -21,18 +21,19 @@ namespace Net { class Ipv4_config; }
struct Net::Ipv4_config struct Net::Ipv4_config
{ {
Ipv4_address_prefix const interface { }; Ipv4_address_prefix const interface { };
bool const interface_valid { interface.valid() }; bool const interface_valid { interface.valid() };
Ipv4_address const gateway { }; Ipv4_address const gateway { };
bool const gateway_valid { gateway.valid() }; bool const gateway_valid { gateway.valid() };
bool const point_to_point { gateway_valid && bool const point_to_point { gateway_valid &&
interface_valid && interface_valid &&
interface.prefix == 32 }; interface.prefix == 32 };
Ipv4_address const dns_server { }; Ipv4_address const dns_server { };
bool const valid { point_to_point || bool const dns_server_valid { dns_server.valid() };
(interface_valid && bool const valid { point_to_point ||
(!gateway_valid || (interface_valid &&
interface.prefix_matches(gateway))) }; (!gateway_valid ||
interface.prefix_matches(gateway))) };
Ipv4_config(Ipv4_address_prefix interface, Ipv4_config(Ipv4_address_prefix interface,
Ipv4_address gateway, Ipv4_address gateway,

View File

@ -56,7 +56,7 @@ Link_side::Link_side(Domain &domain,
_domain(domain), _id(id), _link(link) _domain(domain), _id(id), _link(link)
{ {
if (link.config().verbose()) { if (link.config().verbose()) {
log("[", domain, "] New ", l3_protocol_name(link.protocol()), log("[", domain, "] new ", l3_protocol_name(link.protocol()),
" link ", is_client() ? "client" : "server", ": ", *this); " link ", is_client() ? "client" : "server", ": ", *this);
} }
} }

View File

@ -20,11 +20,13 @@ using namespace Net;
using namespace Genode; using namespace Genode;
Net::Report::Report(Xml_node const node, Net::Report::Report(bool const &verbose,
Xml_node const node,
Timer::Connection &timer, Timer::Connection &timer,
Domain_tree &domains, Domain_tree &domains,
Reporter &reporter) Reporter &reporter)
: :
_verbose(verbose),
_config(node.attribute_value("config", true)), _config(node.attribute_value("config", true)),
_config_triggers(node.attribute_value("config_triggers", false)), _config_triggers(node.attribute_value("config_triggers", false)),
_bytes(node.attribute_value("bytes", true)), _bytes(node.attribute_value("bytes", true)),
@ -46,7 +48,8 @@ void Net::Report::_report()
}); });
}); });
} catch (Xml_generator::Buffer_exceeded) { } catch (Xml_generator::Buffer_exceeded) {
Genode::warning("Failed to generate report"); if (_verbose) {
log("Failed to generate report"); }
} }
} }

View File

@ -35,6 +35,7 @@ class Net::Report
{ {
private: private:
bool const &_verbose;
bool const _config; bool const _config;
bool const _config_triggers; bool const _config_triggers;
bool const _bytes; bool const _bytes;
@ -48,7 +49,8 @@ class Net::Report
public: public:
Report(Genode::Xml_node const node, Report(bool const &verbose,
Genode::Xml_node const node,
Timer::Connection &timer, Timer::Connection &timer,
Domain_tree &domains, Domain_tree &domains,
Genode::Reporter &reporter); Genode::Reporter &reporter);

View File

@ -101,7 +101,7 @@ Net::Uplink::~Uplink()
void Net::Uplink::print(Output &output) const void Net::Uplink::print(Output &output) const
{ {
if (label() == Session_label()) { if (label() == Session_label()) {
Genode::print(output, "<unlabeled>"); } Genode::print(output, "?"); }
else { else {
Genode::print(output, label()); } Genode::print(output, label()); }
} }