diff --git a/repos/os/src/server/nic_router/component.cc b/repos/os/src/server/nic_router/component.cc index 7504a17783..438eaffcbd 100644 --- a/repos/os/src/server/nic_router/component.cc +++ b/repos/os/src/server/nic_router/component.cc @@ -42,28 +42,26 @@ Session_component_base(Allocator &guarded_alloc_backing, size_t const guarded_alloc_amount, Ram_session &buf_ram, size_t const tx_buf_size, - size_t const rx_buf_size, - Configuration const &config, - Session_label const &label) + size_t const rx_buf_size) : _guarded_alloc(&guarded_alloc_backing, guarded_alloc_amount), _range_alloc(&_guarded_alloc), _tx_buf(buf_ram, tx_buf_size), - _rx_buf(buf_ram, rx_buf_size), _intf_policy(label, config) + _rx_buf(buf_ram, rx_buf_size) { } -/********************************************** - ** Session_component_base::Interface_policy ** - **********************************************/ +/***************************************** + ** Session_component::Interface_policy ** + *****************************************/ -Net::Session_component_base:: +Net::Session_component:: Interface_policy::Interface_policy(Genode::Session_label const &label, Configuration const &config) : _label(label), _config(config) { } Domain_name -Net::Session_component_base::Interface_policy::determine_domain_name() const +Net::Session_component::Interface_policy::determine_domain_name() const { Domain_name domain_name; try { @@ -94,28 +92,19 @@ Net::Session_component::Session_component(Allocator &alloc, Interface_list &interfaces, Configuration &config) : - Session_component_base(alloc, amount, buf_ram, tx_buf_size, rx_buf_size, - config, label), - Session_rpc_object(region_map, _tx_buf, _rx_buf, &_range_alloc, - ep.rpc_ep()), - Interface(ep, timer, router_mac, _guarded_alloc, mac, config, interfaces, - _intf_policy) + Session_component_base { alloc, amount, buf_ram, tx_buf_size, + rx_buf_size }, + Session_rpc_object { region_map, _tx_buf, _rx_buf, &_range_alloc, + ep.rpc_ep() }, + _interface_policy { label, config }, + _interface { ep, timer, router_mac, _guarded_alloc, mac, + config, interfaces, *_tx.sink(), *_rx.source(), + _link_state, _interface_policy } { - _tx.sigh_ready_to_ack(_sink_ack); - _tx.sigh_packet_avail(_sink_submit); - _rx.sigh_ack_avail(_source_ack); - _rx.sigh_ready_to_submit(_source_submit); -} - - -bool Net::Session_component::_link_state() -{ - try { - domain(); - return true; - } - catch (Pointer::Invalid) { } - return false; + _tx.sigh_ready_to_ack (_interface.sink_ack()); + _tx.sigh_packet_avail (_interface.sink_submit()); + _rx.sigh_ack_avail (_interface.source_ack()); + _rx.sigh_ready_to_submit(_interface.source_submit()); } @@ -164,14 +153,11 @@ Session_component *Net::Root::_create_session(char const *args) throw Insufficient_ram_quota(); } Session_label const label(label_from_args(args)); - Session_component &component = *new (md_alloc()) + return new (md_alloc()) Session_component(*md_alloc(), _timer, ram_quota - session_size, _buf_ram, tx_buf_size, rx_buf_size, _region_map, _mac_alloc.alloc(), _ep, _router_mac, label, _interfaces, _config()); - - component.init(); - return &component; } catch (Mac_allocator::Alloc_failed) { error("failed to allocate MAC address"); diff --git a/repos/os/src/server/nic_router/component.h b/repos/os/src/server/nic_router/component.h index 803edfde90..eccbb83e28 100644 --- a/repos/os/src/server/nic_router/component.h +++ b/repos/os/src/server/nic_router/component.h @@ -53,6 +53,26 @@ class Net::Session_component_base { protected: + Genode::Allocator_guard _guarded_alloc; + Nic::Packet_allocator _range_alloc; + Communication_buffer _tx_buf; + Communication_buffer _rx_buf; + + public: + + Session_component_base(Genode::Allocator &guarded_alloc_backing, + Genode::size_t const guarded_alloc_amount, + Genode::Ram_session &buf_ram, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size); +}; + + +class Net::Session_component : private Session_component_base, + public ::Nic::Session_rpc_object +{ + private: + struct Interface_policy : Net::Interface_policy { private: @@ -74,37 +94,9 @@ class Net::Session_component_base void handle_config(Configuration const &config) override { _config = config; } }; - Genode::Allocator_guard _guarded_alloc; - Nic::Packet_allocator _range_alloc; - Communication_buffer _tx_buf; - Communication_buffer _rx_buf; - Interface_policy _intf_policy; - - public: - - Session_component_base(Genode::Allocator &guarded_alloc_backing, - Genode::size_t const guarded_alloc_amount, - Genode::Ram_session &buf_ram, - Genode::size_t const tx_buf_size, - Genode::size_t const rx_buf_size, - Configuration const &config, - Genode::Session_label const &label); -}; - - -class Net::Session_component : private Session_component_base, - public ::Nic::Session_rpc_object, - public Interface -{ - private: - - /******************** - ** Net::Interface ** - ********************/ - - Packet_stream_sink &_sink() override { return *_tx.sink(); } - Packet_stream_source &_source() override { return *_rx.source(); } - bool _link_state() override; + bool _link_state { true }; + Interface_policy _interface_policy; + Interface _interface; public: @@ -127,9 +119,10 @@ class Net::Session_component : private Session_component_base, ** Nic::Session ** ******************/ - Mac_address mac_address() override { return _mac; } - bool link_state() override { return _link_state(); } - void link_state_sigh(Genode::Signal_context_capability sigh) override { Interface::link_state_sigh(sigh); } + Mac_address mac_address() override { return _interface.mac(); } + bool link_state() override { return _interface.link_state(); } + void link_state_sigh(Genode::Signal_context_capability sigh) override { + _interface.session_link_state_sigh(sigh); } }; diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index aa57275093..b6415b84f7 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -236,7 +236,7 @@ Interface::_transport_rules(Domain &local_domain, L3_protocol const prot) const void Interface::_attach_to_domain_raw(Domain &domain) { _domain = domain; - Signal_transmitter(_link_state_sigh).submit(); + Signal_transmitter(_session_link_state_sigh).submit(); _interfaces.remove(this); domain.attach_interface(*this); } @@ -248,7 +248,7 @@ void Interface::_detach_from_domain_raw() domain.detach_interface(*this); _interfaces.insert(this); _domain = Pointer(); - Signal_transmitter(_link_state_sigh).submit(); + Signal_transmitter(_session_link_state_sigh).submit(); } @@ -283,9 +283,9 @@ void Interface::attach_to_ip_config(Domain &domain, } -void Interface::link_state_sigh(Signal_context_capability sigh) +void Interface::session_link_state_sigh(Signal_context_capability sigh) { - _link_state_sigh = sigh; + _session_link_state_sigh = sigh; } @@ -315,14 +315,14 @@ void Interface::detach_from_ip_config() void Interface::detach_from_remote_ip_config() { /* only the DNS server address of the local DHCP server can be remote */ - Signal_transmitter(_link_state_sigh).submit(); + Signal_transmitter(_session_link_state_sigh).submit(); } void Interface::attach_to_remote_ip_config() { /* only the DNS server address of the local DHCP server can be remote */ - Signal_transmitter(_link_state_sigh).submit(); + Signal_transmitter(_session_link_state_sigh).submit(); } @@ -725,6 +725,12 @@ void Interface::_send_icmp_dst_unreachable(Ipv4_address_prefix const &local_intf } +bool Interface::link_state() const +{ + return _domain.valid() && _session_link_state; +} + + void Interface::_handle_icmp_query(Ethernet_frame ð, Size_guard &size_guard, Ipv4_packet &ip, @@ -1168,10 +1174,10 @@ void Interface::_handle_arp(Ethernet_frame ð, void Interface::_ready_to_submit() { - while (_sink().packet_avail()) { - Packet_descriptor const pkt = _sink().get_packet(); + while (_sink.packet_avail()) { + Packet_descriptor const pkt = _sink.get_packet(); 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) { continue; } _ack_packet(pkt); } @@ -1181,7 +1187,7 @@ void Interface::_ready_to_submit() void Interface::_continue_handle_eth(Packet_descriptor const &pkt) { 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"); } _ack_packet(pkt); } @@ -1189,8 +1195,8 @@ void Interface::_continue_handle_eth(Packet_descriptor const &pkt) void Interface::_ready_to_ack() { - while (_source().ack_avail()) { - _source().release_packet(_source().get_acked_packet()); } + while (_source.ack_avail()) { + _source.release_packet(_source.get_acked_packet()); } } @@ -1293,8 +1299,8 @@ void Interface::_send_alloc_pkt(Packet_descriptor &pkt, void * &pkt_base, size_t pkt_size) { - pkt = _source().alloc_packet(pkt_size); - pkt_base = _source().packet_content(pkt); + pkt = _source.alloc_packet(pkt_size); + pkt_base = _source.packet_content(pkt); } @@ -1312,7 +1318,7 @@ void Interface::_send_submit_pkt(Packet_descriptor &pkt, } catch (Size_guard::Exceeded) { log("[", local_domain, "] snd ?"); } } - _source().submit_packet(pkt); + _source.submit_packet(pkt); } @@ -1323,22 +1329,27 @@ Interface::Interface(Genode::Entrypoint &ep, Mac_address const mac, Configuration &config, Interface_list &interfaces, + Packet_stream_sink &sink, + Packet_stream_source &source, + bool &session_link_state, Interface_policy &policy) : - _sink_ack(ep, *this, &Interface::_ack_avail), - _sink_submit(ep, *this, &Interface::_ready_to_submit), - _source_ack(ep, *this, &Interface::_ready_to_ack), - _source_submit(ep, *this, &Interface::_packet_avail), - _router_mac(router_mac), _mac(mac), _config(config), - _policy(policy), _timer(timer), _alloc(alloc), - _interfaces(interfaces) + _sink { sink }, + _source { source }, + _session_link_state { session_link_state }, + _sink_ack { ep, *this, &Interface::_ack_avail }, + _sink_submit { ep, *this, &Interface::_ready_to_submit }, + _source_ack { ep, *this, &Interface::_ready_to_ack }, + _source_submit { ep, *this, &Interface::_packet_avail }, + _router_mac { router_mac }, + _mac { mac }, + _config { config }, + _policy { policy }, + _timer { timer }, + _alloc { alloc }, + _interfaces { interfaces } { _interfaces.insert(this); -} - - -void Interface::init() -{ try { _attach_to_domain(_policy.determine_domain_name()); } catch (Domain_tree::No_match) { } } @@ -1650,11 +1661,11 @@ void Interface::handle_config_3() void Interface::_ack_packet(Packet_descriptor const &pkt) { - if (!_sink().ready_to_ack()) { + if (!_sink.ready_to_ack()) { error("ack state FULL"); return; } - _sink().acknowledge_packet(pkt); + _sink.acknowledge_packet(pkt); } diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index c51f23f688..ae19c943dd 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -62,19 +62,11 @@ class Net::Interface : private Interface_list::Element friend class List; friend class Genode::List; - protected: - - using Signal_handler = Genode::Signal_handler; - - Signal_handler _sink_ack; - Signal_handler _sink_submit; - Signal_handler _source_ack; - Signal_handler _source_submit; - Mac_address const _router_mac; - Mac_address const _mac; - private: + using Signal_handler = Genode::Signal_handler; + using Signal_context_capability = Genode::Signal_context_capability; + enum { IPV4_TIME_TO_LIVE = 64 }; struct Dismiss_link : Genode::Exception { }; @@ -86,24 +78,33 @@ class Net::Interface : private Interface_list::Element Domain &new_domain; }; - Reference _config; - Interface_policy &_policy; - Timer::Connection &_timer; - Genode::Allocator &_alloc; - Pointer _domain { }; - Arp_waiter_list _own_arp_waiters { }; - Link_list _tcp_links { }; - Link_list _udp_links { }; - Link_list _icmp_links { }; - Link_list _dissolved_tcp_links { }; - Link_list _dissolved_udp_links { }; - Link_list _dissolved_icmp_links { }; - Dhcp_allocation_tree _dhcp_allocations { }; - Dhcp_allocation_list _released_dhcp_allocations { }; - Dhcp_client _dhcp_client { _alloc, _timer, *this }; - Interface_list &_interfaces; - Genode::Signal_context_capability _link_state_sigh { }; - Pointer _update_domain { }; + Packet_stream_sink &_sink; + Packet_stream_source &_source; + bool &_session_link_state; + Signal_context_capability _session_link_state_sigh { }; + Signal_handler _sink_ack; + Signal_handler _sink_submit; + Signal_handler _source_ack; + Signal_handler _source_submit; + Mac_address const _router_mac; + Mac_address const _mac; + Reference _config; + Interface_policy &_policy; + Timer::Connection &_timer; + Genode::Allocator &_alloc; + Pointer _domain { }; + Arp_waiter_list _own_arp_waiters { }; + Link_list _tcp_links { }; + Link_list _udp_links { }; + Link_list _icmp_links { }; + Link_list _dissolved_tcp_links { }; + Link_list _dissolved_udp_links { }; + Link_list _dissolved_icmp_links { }; + Dhcp_allocation_tree _dhcp_allocations { }; + Dhcp_allocation_list _released_dhcp_allocations { }; + Dhcp_client _dhcp_client { _alloc, _timer, *this }; + Interface_list &_interfaces; + Pointer _update_domain { }; void _new_link(L3_protocol const protocol, Link_side_id const &local_id, @@ -281,16 +282,6 @@ class Net::Interface : private Interface_list::Element Ipv4_packet const &req_ip, Icmp_packet::Code const code); - /******************* - ** Pure virtuals ** - *******************/ - - virtual Packet_stream_sink &_sink() = 0; - - virtual Packet_stream_source &_source() = 0; - - virtual bool _link_state() = 0; - /*********************************** ** Packet-stream signal handlers ** @@ -332,6 +323,9 @@ class Net::Interface : private Interface_list::Element Mac_address const mac, Configuration &config, Interface_list &interfaces, + Packet_stream_sink &sink, + Packet_stream_source &source, + bool &session_link_state, Interface_policy &policy); virtual ~Interface(); @@ -341,7 +335,7 @@ class Net::Interface : private Interface_list::Element template void send(Genode::size_t pkt_size, FUNC && write_to_pkt) { - if (!_link_state()) { + if (!link_state()) { _failed_to_send_packet_link(); return; } @@ -383,20 +377,25 @@ class Net::Interface : private Interface_list::Element void attach_to_remote_ip_config(); - void link_state_sigh(Genode::Signal_context_capability sigh); - - void init(); - void attach_to_domain_finish(); + bool link_state() const; + /*************** ** Accessors ** ***************/ - Domain &domain() { return _domain(); } - Mac_address router_mac() const { return _router_mac; } - Arp_waiter_list &own_arp_waiters() { return _own_arp_waiters; } + Domain &domain() { return _domain(); } + Mac_address const &router_mac() const { return _router_mac; } + Mac_address const &mac() const { return _mac; } + Arp_waiter_list &own_arp_waiters() { return _own_arp_waiters; } + Signal_handler &sink_ack() { return _sink_ack; } + Signal_handler &sink_submit() { return _sink_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); }; #endif /* _INTERFACE_H_ */ diff --git a/repos/os/src/server/nic_router/main.cc b/repos/os/src/server/nic_router/main.cc index 2677c24679..fa7774242b 100644 --- a/repos/os/src/server/nic_router/main.cc +++ b/repos/os/src/server/nic_router/main.cc @@ -103,7 +103,6 @@ void Net::Main::_init_uplink(Configuration &config, Uplink &uplink = *new (_heap) Uplink(_env, _timer, _heap, _interfaces, config, label); _uplink = Pointer(uplink); - uplink.init(); } diff --git a/repos/os/src/server/nic_router/pointer.h b/repos/os/src/server/nic_router/pointer.h index 3d3c406df3..400db572ec 100644 --- a/repos/os/src/server/nic_router/pointer.h +++ b/repos/os/src/server/nic_router/pointer.h @@ -46,6 +46,8 @@ class Net::Pointer return *_obj; } + + bool valid() const { return _obj != nullptr; } }; diff --git a/repos/os/src/server/nic_router/uplink.cc b/repos/os/src/server/nic_router/uplink.cc index 1b5f293bf8..b3def4d879 100644 --- a/repos/os/src/server/nic_router/uplink.cc +++ b/repos/os/src/server/nic_router/uplink.cc @@ -30,25 +30,29 @@ Net::Uplink::Uplink(Env &env, Configuration &config, Session_label const &label) : - Nic::Packet_allocator(&alloc), - Nic::Connection(env, this, BUF_SIZE, BUF_SIZE, label.string()), - Net::Interface(env.ep(), timer, mac_address(), alloc, Mac_address(), - config, interfaces, _intf_policy), - _label(label), - _link_state_handler(env.ep(), *this, &Uplink::_handle_link_state) + Nic::Packet_allocator { &alloc }, + Nic::Connection { env, this, BUF_SIZE, BUF_SIZE, label.string() }, + _label { label }, + _link_state_handler { env.ep(), *this, &Uplink::_handle_link_state }, + _interface { env.ep(), timer, mac_address(), alloc, + Mac_address(), config, interfaces, *rx(), *tx(), + _link_state, _intf_policy } { - rx_channel()->sigh_ready_to_ack(_sink_ack); - rx_channel()->sigh_packet_avail(_sink_submit); - tx_channel()->sigh_ack_avail(_source_ack); - tx_channel()->sigh_ready_to_submit(_source_submit); + /* install packet stream signal handlers */ + rx_channel()->sigh_ready_to_ack (_interface.sink_ack()); + rx_channel()->sigh_packet_avail (_interface.sink_submit()); + tx_channel()->sigh_ack_avail (_interface.source_ack()); + tx_channel()->sigh_ready_to_submit(_interface.source_submit()); + + /* initialize link state handling */ Nic::Connection::link_state_sigh(_link_state_handler); - _link_state_ = link_state(); + _link_state = link_state(); } void Net::Uplink::_handle_link_state() { - _link_state_ = link_state(); - try { domain().discard_ip_config(); } + _link_state = link_state(); + try { _interface.domain().discard_ip_config(); } catch (Domain::Ip_config_static) { } } diff --git a/repos/os/src/server/nic_router/uplink.h b/repos/os/src/server/nic_router/uplink.h index f39b101184..7fed7e33b0 100644 --- a/repos/os/src/server/nic_router/uplink.h +++ b/repos/os/src/server/nic_router/uplink.h @@ -52,8 +52,7 @@ class Net::Uplink_base class Net::Uplink : public Uplink_base, public Nic::Packet_allocator, - public Nic::Connection, - public Interface + public Nic::Connection { private: @@ -63,22 +62,14 @@ class Net::Uplink : public Uplink_base, }; Genode::Session_label const &_label; - bool _link_state_ { false }; + bool _link_state { false }; Genode::Signal_handler _link_state_handler; + Net::Interface _interface; Ipv4_address_prefix _read_interface(); void _handle_link_state(); - - /******************** - ** Net::Interface ** - ********************/ - - Packet_stream_sink &_sink() override { return *rx(); } - Packet_stream_source &_source() override { return *tx(); } - bool _link_state() override { return _link_state_; } - public: Uplink(Genode::Env &env, @@ -93,7 +84,7 @@ class Net::Uplink : public Uplink_base, ** Accessors ** ***************/ - Mac_address const &router_mac() const { return _router_mac; } + Mac_address const &router_mac() const { return _interface.router_mac(); } Genode::Session_label const &label() const { return _label; } };