diff --git a/repos/dde_linux/run/nic_router_uplinks.run b/repos/dde_linux/run/nic_router_uplinks.run index 5ef4bd97d5..95c7f5c071 100644 --- a/repos/dde_linux/run/nic_router_uplinks.run +++ b/repos/dde_linux/run/nic_router_uplinks.run @@ -317,7 +317,10 @@ append config { - + + + + diff --git a/repos/gems/recipes/src/sculpt_manager/used_apis b/repos/gems/recipes/src/sculpt_manager/used_apis index 685de8b9d4..c7b53ffe6d 100644 --- a/repos/gems/recipes/src/sculpt_manager/used_apis +++ b/repos/gems/recipes/src/sculpt_manager/used_apis @@ -3,6 +3,7 @@ os report_session file_system_session nic_session +uplink_session timer_session block_session usb_session diff --git a/repos/gems/src/app/sculpt_manager/runtime/nic_router.cc b/repos/gems/src/app/sculpt_manager/runtime/nic_router.cc index 3677b1e9c4..cec8f54fed 100644 --- a/repos/gems/src/app/sculpt_manager/runtime/nic_router.cc +++ b/repos/gems/src/app/sculpt_manager/runtime/nic_router.cc @@ -11,6 +11,10 @@ * under the terms of the GNU Affero General Public License version 3. */ +/* Genode includes */ +#include + +/* local includes */ #include @@ -22,7 +26,14 @@ void Sculpt::gen_nic_router_start_content(Xml_generator &xml, gen_common_start_content(xml, "nic_router", Cap_quota{300}, Ram_quota{10*1024*1024}); - gen_provides(xml); + xml.node("provides", [&] () { + xml.node("service", [&] () { + xml.attribute("name", Nic::Session::service_name()); + }); + xml.node("service", [&] () { + xml.attribute("name", Uplink::Session::service_name()); + }); + }); xml.node("route", [&] () { diff --git a/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime b/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime index b73c4e5e8d..baca0f5ba8 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime +++ b/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime @@ -39,7 +39,10 @@ - + + + + diff --git a/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime b/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime index 42b76f9178..324fcda299 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime +++ b/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime @@ -40,7 +40,10 @@ - + + + + diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime index 9ff91065f3..f362befcf6 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime +++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime @@ -40,7 +40,10 @@ - + + + + diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime index 204df8f627..de72666540 100644 --- a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime +++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime @@ -41,7 +41,10 @@ - + + + + diff --git a/repos/libports/run/nic_router.run b/repos/libports/run/nic_router.run index 1c64259c4c..11a83d2962 100644 --- a/repos/libports/run/nic_router.run +++ b/repos/libports/run/nic_router.run @@ -188,7 +188,10 @@ proc test_7_config { } { - + + + + @@ -286,7 +289,10 @@ append config { - + + + + - + + + + diff --git a/repos/os/recipes/src/nic_router/used_apis b/repos/os/recipes/src/nic_router/used_apis index 64e9a07739..1988ee0b01 100644 --- a/repos/os/recipes/src/nic_router/used_apis +++ b/repos/os/recipes/src/nic_router/used_apis @@ -1,5 +1,6 @@ base os nic_session +uplink_session timer_session report_session diff --git a/repos/os/run/nic_dump.run b/repos/os/run/nic_dump.run index 25199aeb03..5b15cbfba4 100644 --- a/repos/os/run/nic_dump.run +++ b/repos/os/run/nic_dump.run @@ -81,7 +81,10 @@ append config { - + + + + - + + + + diff --git a/repos/os/run/nic_router_dhcp.inc b/repos/os/run/nic_router_dhcp.inc index e24786dbac..7d62956a12 100644 --- a/repos/os/run/nic_router_dhcp.inc +++ b/repos/os/run/nic_router_dhcp.inc @@ -142,7 +142,10 @@ append config { - + + + + @@ -154,7 +157,10 @@ append config { - } + + + + } append_if [expr ![nic_router_2_managed]] config { diff --git a/repos/os/run/nic_router_disable_arp.run b/repos/os/run/nic_router_disable_arp.run index e71365752e..b6df26d6a1 100644 --- a/repos/os/run/nic_router_disable_arp.run +++ b/repos/os/run/nic_router_disable_arp.run @@ -51,7 +51,10 @@ append config { - + + + + diff --git a/repos/os/run/nic_router_flood.run b/repos/os/run/nic_router_flood.run index 21d921802c..0cfb8f459b 100644 --- a/repos/os/run/nic_router_flood.run +++ b/repos/os/run/nic_router_flood.run @@ -142,7 +142,10 @@ install_config { - + + + + diff --git a/repos/os/run/nic_stress.inc b/repos/os/run/nic_stress.inc index 5ab1c0eda5..50833753bc 100644 --- a/repos/os/run/nic_stress.inc +++ b/repos/os/run/nic_stress.inc @@ -83,7 +83,10 @@ append_if [string equal $type "nic_router"] config { - + + + + @@ -97,7 +100,10 @@ append_if [string equal $type "nic_bridge"] config { - + + + + diff --git a/repos/os/run/ping_nic_router.run b/repos/os/run/ping_nic_router.run index f231909473..d8eb2ecdb5 100644 --- a/repos/os/run/ping_nic_router.run +++ b/repos/os/run/ping_nic_router.run @@ -61,7 +61,10 @@ append config { - + + + + - + + + + diff --git a/repos/os/src/server/nic_router/communication_buffer.cc b/repos/os/src/server/nic_router/communication_buffer.cc new file mode 100644 index 0000000000..ac231ed9ab --- /dev/null +++ b/repos/os/src/server/nic_router/communication_buffer.cc @@ -0,0 +1,26 @@ +/* + * \brief Buffer for network communication + * \author Martin Stein + * \date 2020-11-30 + */ + +/* + * Copyright (C) 2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +using namespace Net; +using namespace Genode; + + +Communication_buffer::Communication_buffer(Ram_allocator &ram_alloc, + size_t const size) +: + _ram_alloc { ram_alloc }, + _ram_ds { ram_alloc.alloc(size) } +{ } diff --git a/repos/os/src/server/nic_router/communication_buffer.h b/repos/os/src/server/nic_router/communication_buffer.h new file mode 100644 index 0000000000..91be70a1ff --- /dev/null +++ b/repos/os/src/server/nic_router/communication_buffer.h @@ -0,0 +1,46 @@ +/* + * \brief Buffer for network communication + * \author Martin Stein + * \date 2020-11-30 + */ + +/* + * Copyright (C) 2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _COMMUNICATION_BUFFER_H_ +#define _COMMUNICATION_BUFFER_H_ + +/* Genode includes */ +#include +#include + +namespace Net { class Communication_buffer; } + + +class Net::Communication_buffer +{ + private: + + Genode::Ram_allocator &_ram_alloc; + Genode::Ram_dataspace_capability _ram_ds; + + public: + + Communication_buffer(Genode::Ram_allocator &ram_alloc, + Genode::size_t const size); + + ~Communication_buffer() { _ram_alloc.free(_ram_ds); } + + + /*************** + ** Accessors ** + ***************/ + + Genode::Dataspace_capability ds() const { return _ram_ds; } +}; + +#endif /* _COMMUNICATION_BUFFER_H_ */ diff --git a/repos/os/src/server/nic_router/component.h b/repos/os/src/server/nic_router/component.h deleted file mode 100644 index 812dfca53c..0000000000 --- a/repos/os/src/server/nic_router/component.h +++ /dev/null @@ -1,397 +0,0 @@ -/* - * \brief Downlink interface in form of a NIC session component - * \author Martin Stein - * \date 2016-08-23 - */ - -/* - * Copyright (C) 2016-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _COMPONENT_H_ -#define _COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include -#include - -/* local includes */ -#include -#include -#include -#include - -namespace Genode { class Session_env; } - -namespace Net { - - class Communication_buffer; - class Session_component_base; - class Session_component; - class Root; -} - - -class Genode::Session_env : public Ram_allocator, - public Region_map -{ - private: - - Env &_env; - Net::Quota &_shared_quota; - Ram_quota_guard _ram_guard; - Cap_quota_guard _cap_guard; - - template - void _consume(size_t own_ram, - size_t max_shared_ram, - size_t own_cap, - size_t max_shared_cap, - FUNC && functor) - { - size_t const max_ram_consumpt { own_ram + max_shared_ram }; - size_t const max_cap_consumpt { own_cap + max_shared_cap }; - size_t ram_consumpt { _env.pd().used_ram().value }; - size_t cap_consumpt { _env.pd().used_caps().value }; - { - Ram_quota_guard::Reservation ram_reserv { _ram_guard, Ram_quota { max_ram_consumpt } }; - Cap_quota_guard::Reservation cap_reserv { _cap_guard, Cap_quota { max_cap_consumpt } }; - - functor(); - - ram_reserv.acknowledge(); - cap_reserv.acknowledge(); - } - ram_consumpt = _env.pd().used_ram().value - ram_consumpt; - cap_consumpt = _env.pd().used_caps().value - cap_consumpt; - - if (ram_consumpt > max_ram_consumpt) { - error("Session_env: more RAM quota consumed than expected"); } - if (cap_consumpt > max_cap_consumpt) { - error("Session_env: more CAP quota consumed than expected"); } - if (ram_consumpt < own_ram) { - error("Session_env: less RAM quota consumed than expected"); } - if (cap_consumpt < own_cap) { - error("Session_env: less CAP quota consumed than expected"); } - - _shared_quota.ram += ram_consumpt - own_ram; - _shared_quota.cap += cap_consumpt - own_cap; - - _ram_guard.replenish( Ram_quota { max_shared_ram } ); - _cap_guard.replenish( Cap_quota { max_shared_cap } ); - } - - template - void _replenish(size_t accounted_ram, - size_t accounted_cap, - FUNC && functor) - { - size_t ram_replenish { _env.pd().used_ram().value }; - size_t cap_replenish { _env.pd().used_caps().value }; - functor(); - ram_replenish = ram_replenish - _env.pd().used_ram().value; - cap_replenish = cap_replenish - _env.pd().used_caps().value; - - if (ram_replenish < accounted_ram) { - error("Session_env: less RAM quota replenished than expected"); } - if (cap_replenish < accounted_cap) { - error("Session_env: less CAP quota replenished than expected"); } - - _shared_quota.ram -= ram_replenish - accounted_ram; - _shared_quota.cap -= cap_replenish - accounted_cap; - - _ram_guard.replenish( Ram_quota { accounted_ram } ); - _cap_guard.replenish( Cap_quota { accounted_cap } ); - - } - - public: - - Session_env(Env &env, - Net::Quota &shared_quota, - Ram_quota const &ram_quota, - Cap_quota const &cap_quota) - : - _env { env }, - _shared_quota { shared_quota }, - _ram_guard { ram_quota }, - _cap_guard { cap_quota } - { } - - Entrypoint &ep() { return _env.ep(); } - - - /******************* - ** Ram_allocator ** - *******************/ - - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override - { - enum { MAX_SHARED_CAP = 1 }; - enum { MAX_SHARED_RAM = 4096 }; - enum { DS_SIZE_GRANULARITY_LOG2 = 12 }; - - size_t const ds_size = align_addr(size, DS_SIZE_GRANULARITY_LOG2); - Ram_dataspace_capability ds; - _consume(ds_size, MAX_SHARED_RAM, 1, MAX_SHARED_CAP, [&] () { - ds = _env.pd().alloc(ds_size, cached); - }); - return ds; - } - - - void free(Ram_dataspace_capability ds) override - { - _replenish(_env.pd().dataspace_size(ds), 1, [&] () { - _env.pd().free(ds); - }); - } - - size_t dataspace_size(Ram_dataspace_capability ds) const override { return _env.pd().dataspace_size(ds); } - - - /**************** - ** Region_map ** - ****************/ - - Local_addr attach(Dataspace_capability ds, - size_t size = 0, - off_t offset = 0, - bool use_local_addr = false, - Local_addr local_addr = (void *)0, - bool executable = false, - bool writeable = true) override - { - enum { MAX_SHARED_CAP = 2 }; - enum { MAX_SHARED_RAM = 4 * 4096 }; - - void *ptr; - _consume(0, MAX_SHARED_RAM, 0, MAX_SHARED_CAP, [&] () { - ptr = _env.rm().attach(ds, size, offset, use_local_addr, - local_addr, executable, writeable); - }); - return ptr; - }; - - void report(Genode::Xml_generator &xml) const - { - xml.node("ram-quota", [&] () { - xml.attribute("used", _ram_guard.used().value); - xml.attribute("limit", _ram_guard.limit().value); - xml.attribute("avail", _ram_guard.avail().value); - }); - xml.node("cap-quota", [&] () { - xml.attribute("used", _cap_guard.used().value); - xml.attribute("limit", _cap_guard.limit().value); - xml.attribute("avail", _cap_guard.avail().value); - }); - } - - void detach(Local_addr local_addr) override - { - _replenish(0, 0, [&] () { _env.rm().detach(local_addr); }); - } - - void fault_handler(Signal_context_capability handler) override { _env.rm().fault_handler(handler); } - State state() override { return _env.rm().state(); } - Dataspace_capability dataspace() override { return _env.rm().dataspace(); } - - - /*************** - ** Accessors ** - ***************/ - - Ram_quota_guard const &ram_guard() const { return _ram_guard; }; - Cap_quota_guard const &cap_guard() const { return _cap_guard; }; -}; - - -class Net::Communication_buffer -{ - private: - - Genode::Ram_allocator &_ram_alloc; - Genode::Ram_dataspace_capability _ram_ds; - - public: - - Communication_buffer(Genode::Ram_allocator &ram_alloc, - Genode::size_t const size); - - ~Communication_buffer() { _ram_alloc.free(_ram_ds); } - - - /*************** - ** Accessors ** - ***************/ - - Genode::Dataspace_capability ds() const { return _ram_ds; } -}; - - -class Net::Session_component_base -{ - protected: - - Genode::Session_env &_session_env; - Genode::Heap _alloc; - Nic::Packet_allocator _packet_alloc; - Communication_buffer _tx_buf; - Communication_buffer _rx_buf; - - public: - - Session_component_base(Genode::Session_env &session_env, - 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: - - class Interface_policy : public Net::Interface_policy - { - private: - - using Signal_context_capability = - Genode::Signal_context_capability; - - /* - * The transient link state is a combination of session and - * interface link state. The first word in the value name - * denotes the link state of the session. If the session - * link state has already been read by the client and - * can therefore be altered directly, it is marked as - * 'ACKNOWLEDGED'. Otherwise, the denoted session state - * has to stay fixed until the client has read it. In this - * case, the session link state in the value name may be - * followed by the pending link state edges. Consequently, - * the last 'UP' or 'DOWN' in each value name denotes the - * router-internal interface link-state. - */ - enum Transient_link_state - { - DOWN_ACKNOWLEDGED, - DOWN, - DOWN_UP, - DOWN_UP_DOWN, - UP_ACKNOWLEDGED, - UP, - UP_DOWN, - UP_DOWN_UP - }; - - Genode::Session_label const _label; - Const_reference _config; - Genode::Session_env const &_session_env; - Transient_link_state _transient_link_state { DOWN_ACKNOWLEDGED }; - Signal_context_capability _session_link_state_sigh { }; - - void _session_link_state_transition(Transient_link_state tls); - - public: - - Interface_policy(Genode::Session_label const &label, - Genode::Session_env const &session_env, - Configuration const &config); - - bool read_and_ack_session_link_state(); - - void session_link_state_sigh(Genode::Signal_context_capability sigh); - - - /*************************** - ** Net::Interface_policy ** - ***************************/ - - Domain_name determine_domain_name() const override; - void handle_config(Configuration const &config) override { _config = config; } - Genode::Session_label const &label() const override { return _label; } - void report(Genode::Xml_generator &xml) const override { _session_env.report(xml); }; - void interface_unready() override; - void interface_ready() override; - bool interface_link_state() const override; - }; - - Interface_policy _interface_policy; - Interface _interface; - Genode::Ram_dataspace_capability const _ram_ds; - - public: - - Session_component(Genode::Session_env &session_env, - Genode::size_t const tx_buf_size, - Genode::size_t const rx_buf_size, - Timer::Connection &timer, - Mac_address const mac, - Mac_address const &router_mac, - Genode::Session_label const &label, - Interface_list &interfaces, - Configuration &config, - Genode::Ram_dataspace_capability const ram_ds); - - - /****************** - ** Nic::Session ** - ******************/ - - Mac_address mac_address() override { return _interface.mac(); } - bool link_state() override; - void link_state_sigh(Genode::Signal_context_capability sigh) override; - - - /*************** - ** Accessors ** - ***************/ - - Interface_policy const &interface_policy() const { return _interface_policy; } - Genode::Ram_dataspace_capability ram_ds() const { return _ram_ds; }; - Genode::Session_env const &session_env() const { return _session_env; }; -}; - - -class Net::Root : public Genode::Root_component -{ - private: - - enum { MAC_ALLOC_BASE = 0x02 }; - - Genode::Env &_env; - Timer::Connection &_timer; - Mac_allocator _mac_alloc; - Mac_address const _router_mac; - Reference _config; - Quota &_shared_quota; - Interface_list &_interfaces; - - void _invalid_downlink(char const *reason); - - - /******************** - ** Root_component ** - ********************/ - - Session_component *_create_session(char const *args) override; - void _destroy_session(Session_component *session) override; - - public: - - Root(Genode::Env &env, - Timer::Connection &timer, - Genode::Allocator &alloc, - Configuration &config, - Quota &shared_quota, - Interface_list &interfaces); - - void handle_config(Configuration &config) { _config = Reference(config); } -}; - -#endif /* _COMPONENT_H_ */ diff --git a/repos/os/src/server/nic_router/main.cc b/repos/os/src/server/nic_router/main.cc index 86993d8e01..2a6fcef2f2 100644 --- a/repos/os/src/server/nic_router/main.cc +++ b/repos/os/src/server/nic_router/main.cc @@ -18,7 +18,8 @@ #include /* local includes */ -#include +#include +#include #include #include @@ -33,14 +34,15 @@ class Net::Main private: Genode::Env &_env; - Quota _shared_quota { }; - Interface_list _interfaces { }; - Timer::Connection _timer { _env }; - Genode::Heap _heap { &_env.ram(), &_env.rm() }; - Genode::Attached_rom_dataspace _config_rom { _env, "config" }; - Reference _config { *new (_heap) Configuration { _config_rom.xml(), _heap } }; - Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; - Root _root { _env, _timer, _heap, _config(), _shared_quota, _interfaces }; + Quota _shared_quota { }; + Interface_list _interfaces { }; + Timer::Connection _timer { _env }; + Genode::Heap _heap { &_env.ram(), &_env.rm() }; + Genode::Attached_rom_dataspace _config_rom { _env, "config" }; + Reference _config { *new (_heap) Configuration { _config_rom.xml(), _heap } }; + Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; + Nic_session_root _nic_session_root { _env, _timer, _heap, _config(), _shared_quota, _interfaces }; + Uplink_session_root _uplink_session_root { _env, _timer, _heap, _config(), _shared_quota, _interfaces }; void _handle_config(); @@ -67,7 +69,8 @@ Net::Main::Main(Env &env) : _env(env) { _config_rom.sigh(_config_handler); _handle_config(); - env.parent().announce(env.ep().manage(_root)); + env.parent().announce(env.ep().manage(_nic_session_root)); + env.parent().announce(env.ep().manage(_uplink_session_root)); } @@ -81,7 +84,8 @@ void Net::Main::_handle_config() Configuration(_env, _config_rom.xml(), _heap, _timer, old_config, _shared_quota, _interfaces); - _root.handle_config(new_config); + _nic_session_root.handle_config(new_config); + _uplink_session_root.handle_config(new_config); _for_each_interface([&] (Interface &intf) { intf.handle_config_1(new_config); }); _for_each_interface([&] (Interface &intf) { intf.handle_config_2(); }); _config = Reference(new_config); diff --git a/repos/os/src/server/nic_router/component.cc b/repos/os/src/server/nic_router/nic_session_root.cc similarity index 67% rename from repos/os/src/server/nic_router/component.cc rename to repos/os/src/server/nic_router/nic_session_root.cc index f7c91dbd5f..2acb38549e 100644 --- a/repos/os/src/server/nic_router/component.cc +++ b/repos/os/src/server/nic_router/nic_session_root.cc @@ -1,5 +1,5 @@ /* - * \brief Downlink interface in form of a NIC session component + * \brief NIC session server role of the NIC router * \author Martin Stein * \date 2016-08-23 */ @@ -15,33 +15,21 @@ #include /* local includes */ -#include +#include #include using namespace Net; using namespace Genode; -/************************** - ** Communication_buffer ** - **************************/ +/******************************** + ** Nic_session_component_base ** + ********************************/ -Communication_buffer::Communication_buffer(Ram_allocator &ram_alloc, - size_t const size) -: - _ram_alloc { ram_alloc }, - _ram_ds { ram_alloc.alloc(size) } -{ } - - -/**************************** - ** Session_component_base ** - ****************************/ - -Session_component_base:: -Session_component_base(Session_env &session_env, - size_t const tx_buf_size, - size_t const rx_buf_size) +Nic_session_component_base:: +Nic_session_component_base(Session_env &session_env, + size_t const tx_buf_size, + size_t const rx_buf_size) : _session_env { session_env }, _alloc { _session_env, _session_env }, @@ -51,11 +39,11 @@ Session_component_base(Session_env &session_env, { } -/***************************************** - ** Session_component::Interface_policy ** - *****************************************/ +/********************************************* + ** Nic_session_component::Interface_policy ** + *********************************************/ -Net::Session_component:: +Net::Nic_session_component:: Interface_policy::Interface_policy(Genode::Session_label const &label, Session_env const &session_env, Configuration const &config) @@ -69,7 +57,7 @@ Interface_policy::Interface_policy(Genode::Session_label const &label, Domain_name -Net::Session_component::Interface_policy::determine_domain_name() const +Net::Nic_session_component::Interface_policy::determine_domain_name() const { Domain_name domain_name; try { @@ -90,7 +78,7 @@ Net::Session_component::Interface_policy::determine_domain_name() const } -void Net::Session_component:: +void Net::Nic_session_component:: Interface_policy::_session_link_state_transition(Transient_link_state tls) { _transient_link_state = tls; @@ -98,7 +86,7 @@ Interface_policy::_session_link_state_transition(Transient_link_state tls) } -void Net::Session_component::Interface_policy::interface_unready() +void Net::Nic_session_component::Interface_policy::interface_unready() { switch (_transient_link_state) { case UP_ACKNOWLEDGED: @@ -132,7 +120,7 @@ void Net::Session_component::Interface_policy::interface_unready() } -void Net::Session_component::Interface_policy::interface_ready() +void Net::Nic_session_component::Interface_policy::interface_ready() { switch (_transient_link_state) { case DOWN_ACKNOWLEDGED: @@ -166,7 +154,7 @@ void Net::Session_component::Interface_policy::interface_ready() } bool -Net::Session_component::Interface_policy::interface_link_state() const +Net::Nic_session_component::Interface_policy::interface_link_state() const { switch (_transient_link_state) { case DOWN_ACKNOWLEDGED: return false; @@ -184,7 +172,7 @@ Net::Session_component::Interface_policy::interface_link_state() const bool -Net::Session_component::Interface_policy::read_and_ack_session_link_state() +Net::Nic_session_component::Interface_policy::read_and_ack_session_link_state() { switch (_transient_link_state) { case DOWN_ACKNOWLEDGED: @@ -230,36 +218,38 @@ Net::Session_component::Interface_policy::read_and_ack_session_link_state() } -void Net::Session_component::Interface_policy:: +void Net::Nic_session_component::Interface_policy:: session_link_state_sigh(Signal_context_capability sigh) { _session_link_state_sigh = sigh; } -/*********************** - ** Session_component ** - ***********************/ +/*************************** + ** Nic_session_component ** + ***************************/ -Net::Session_component::Session_component(Session_env &session_env, - size_t const tx_buf_size, - size_t const rx_buf_size, - Timer::Connection &timer, - Mac_address const mac, - Mac_address const &router_mac, - Session_label const &label, - Interface_list &interfaces, - Configuration &config, - Ram_dataspace_capability const ram_ds) +Net:: +Nic_session_component:: +Nic_session_component(Session_env &session_env, + size_t const tx_buf_size, + size_t const rx_buf_size, + Timer::Connection &timer, + Mac_address const mac, + Mac_address const &router_mac, + Session_label const &label, + Interface_list &interfaces, + Configuration &config, + Ram_dataspace_capability const ram_ds) : - Session_component_base { session_env, tx_buf_size,rx_buf_size }, - Session_rpc_object { _session_env, _tx_buf.ds(), _rx_buf.ds(), - &_packet_alloc, _session_env.ep().rpc_ep() }, - _interface_policy { label, _session_env, config }, - _interface { _session_env.ep(), timer, router_mac, _alloc, - mac, config, interfaces, *_tx.sink(), - *_rx.source(), _interface_policy }, - _ram_ds { ram_ds } + Nic_session_component_base { session_env, tx_buf_size,rx_buf_size }, + Session_rpc_object { _session_env, _tx_buf.ds(), _rx_buf.ds(), + &_packet_alloc, _session_env.ep().rpc_ep() }, + _interface_policy { label, _session_env, config }, + _interface { _session_env.ep(), timer, router_mac, _alloc, + mac, config, interfaces, *_tx.sink(), + *_rx.source(), _interface_policy }, + _ram_ds { ram_ds } { _interface.attach_to_domain(); @@ -270,42 +260,42 @@ Net::Session_component::Session_component(Session_env &sessio } -bool Net::Session_component::link_state() +bool Net::Nic_session_component::link_state() { return _interface_policy.read_and_ack_session_link_state(); } void Net:: -Session_component::link_state_sigh(Signal_context_capability sigh) +Nic_session_component::link_state_sigh(Signal_context_capability sigh) { _interface_policy.session_link_state_sigh(sigh); } -/********** - ** Root ** - **********/ +/********************** + ** Nic_session_root ** + **********************/ -Net::Root::Root(Env &env, - Timer::Connection &timer, - Allocator &alloc, - Configuration &config, - Quota &shared_quota, - Interface_list &interfaces) +Net::Nic_session_root::Nic_session_root(Env &env, + Timer::Connection &timer, + Allocator &alloc, + Configuration &config, + Quota &shared_quota, + Interface_list &interfaces) : - Root_component { &env.ep().rpc_ep(), &alloc }, - _env { env }, - _timer { timer }, - _mac_alloc { MAC_ALLOC_BASE }, - _router_mac { _mac_alloc.alloc() }, - _config { config }, - _shared_quota { shared_quota }, - _interfaces { interfaces } + Root_component { &env.ep().rpc_ep(), &alloc }, + _env { env }, + _timer { timer }, + _mac_alloc { MAC_ALLOC_BASE }, + _router_mac { _mac_alloc.alloc() }, + _config { config }, + _shared_quota { shared_quota }, + _interfaces { interfaces } { } -Session_component *Net::Root::_create_session(char const *args) +Nic_session_component *Net::Nic_session_root::_create_session(char const *args) { try { /* create session environment temporarily on the stack */ @@ -316,7 +306,7 @@ Session_component *Net::Root::_create_session(char const *args) /* alloc/attach RAM block and move session env to base of the block */ Ram_dataspace_capability ram_ds { session_env_stack.alloc(sizeof(Session_env) + - sizeof(Session_component), CACHED) }; + sizeof(Nic_session_component), CACHED) }; try { void * const ram_ptr { session_env_stack.attach(ram_ds) }; Session_env &session_env { @@ -327,14 +317,13 @@ Session_component *Net::Root::_create_session(char const *args) Session_label const label { label_from_args(args) }; Mac_address const mac { _mac_alloc.alloc() }; try { - Session_component *x = construct_at( + return construct_at( (void*)((addr_t)ram_ptr + sizeof(Session_env)), session_env, Arg_string::find_arg(args, "tx_buf_size").ulong_value(0), Arg_string::find_arg(args, "rx_buf_size").ulong_value(0), _timer, mac, _router_mac, label, _interfaces, _config(), ram_ds); - return x; } catch (Out_of_ram) { _mac_alloc.free(mac); @@ -392,7 +381,7 @@ Session_component *Net::Root::_create_session(char const *args) } } -void Net::Root::_destroy_session(Session_component *session) +void Net::Nic_session_root::_destroy_session(Nic_session_component *session) { Mac_address const mac = session->mac_address(); @@ -400,7 +389,7 @@ void Net::Root::_destroy_session(Session_component *session) Ram_dataspace_capability ram_ds { session->ram_ds() }; Session_env const &session_env { session->session_env() }; Session_label const session_label { session->interface_policy().label() }; - session->~Session_component(); + session->~Nic_session_component(); /* copy session env to stack and detach/free all session data */ Session_env session_env_stack { session_env }; @@ -420,7 +409,7 @@ void Net::Root::_destroy_session(Session_component *session) } -void Net::Root::_invalid_downlink(char const *reason) +void Net::Nic_session_root::_invalid_downlink(char const *reason) { if (_config().verbose()) { log("[?] invalid downlink (", reason, ")"); } diff --git a/repos/os/src/server/nic_router/nic_session_root.h b/repos/os/src/server/nic_router/nic_session_root.h new file mode 100644 index 0000000000..54116a1775 --- /dev/null +++ b/repos/os/src/server/nic_router/nic_session_root.h @@ -0,0 +1,201 @@ +/* + * \brief NIC session server role of the NIC router + * \author Martin Stein + * \date 2016-08-23 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _NIC_SESSION_ROOT_H_ +#define _NIC_SESSION_ROOT_H_ + +/* Genode includes */ +#include +#include +#include +#include + +/* local includes */ +#include +#include +#include +#include +#include +#include + +namespace Net { + + class Nic_session_component_base; + class Nic_session_component; + class Nic_session_root; +} + + +class Net::Nic_session_component_base +{ + protected: + + Genode::Session_env &_session_env; + Genode::Heap _alloc; + Nic::Packet_allocator _packet_alloc; + Communication_buffer _tx_buf; + Communication_buffer _rx_buf; + + public: + + Nic_session_component_base(Genode::Session_env &session_env, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size); +}; + + +class Net::Nic_session_component : private Nic_session_component_base, + public ::Nic::Session_rpc_object +{ + private: + + class Interface_policy : public Net::Interface_policy + { + private: + + using Signal_context_capability = + Genode::Signal_context_capability; + + /* + * The transient link state is a combination of session and + * interface link state. The first word in the value name + * denotes the link state of the session. If the session + * link state has already been read by the client and + * can therefore be altered directly, it is marked as + * 'ACKNOWLEDGED'. Otherwise, the denoted session state + * has to stay fixed until the client has read it. In this + * case, the session link state in the value name may be + * followed by the pending link state edges. Consequently, + * the last 'UP' or 'DOWN' in each value name denotes the + * router-internal interface link-state. + */ + enum Transient_link_state + { + DOWN_ACKNOWLEDGED, + DOWN, + DOWN_UP, + DOWN_UP_DOWN, + UP_ACKNOWLEDGED, + UP, + UP_DOWN, + UP_DOWN_UP + }; + + Genode::Session_label const _label; + Const_reference _config; + Genode::Session_env const &_session_env; + Transient_link_state _transient_link_state { DOWN_ACKNOWLEDGED }; + Signal_context_capability _session_link_state_sigh { }; + + void _session_link_state_transition(Transient_link_state tls); + + public: + + Interface_policy(Genode::Session_label const &label, + Genode::Session_env const &session_env, + Configuration const &config); + + bool read_and_ack_session_link_state(); + + void session_link_state_sigh(Genode::Signal_context_capability sigh); + + + /*************************** + ** Net::Interface_policy ** + ***************************/ + + Domain_name determine_domain_name() const override; + void handle_config(Configuration const &config) override { _config = config; } + Genode::Session_label const &label() const override { return _label; } + void report(Genode::Xml_generator &xml) const override { _session_env.report(xml); }; + void interface_unready() override; + void interface_ready() override; + bool interface_link_state() const override; + }; + + Interface_policy _interface_policy; + Interface _interface; + Genode::Ram_dataspace_capability const _ram_ds; + + public: + + Nic_session_component(Genode::Session_env &session_env, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size, + Timer::Connection &timer, + Mac_address const mac, + Mac_address const &router_mac, + Genode::Session_label const &label, + Interface_list &interfaces, + Configuration &config, + Genode::Ram_dataspace_capability const ram_ds); + + + /****************** + ** Nic::Session ** + ******************/ + + Mac_address mac_address() override { return _interface.mac(); } + bool link_state() override; + void link_state_sigh(Genode::Signal_context_capability sigh) override; + + + /*************** + ** Accessors ** + ***************/ + + Interface_policy const &interface_policy() const { return _interface_policy; } + Genode::Ram_dataspace_capability ram_ds() const { return _ram_ds; }; + Genode::Session_env const &session_env() const { return _session_env; }; +}; + + +class Net::Nic_session_root +: + public Genode::Root_component +{ + private: + + enum { MAC_ALLOC_BASE = 0x02 }; + + Genode::Env &_env; + Timer::Connection &_timer; + Mac_allocator _mac_alloc; + Mac_address const _router_mac; + Reference _config; + Quota &_shared_quota; + Interface_list &_interfaces; + + void _invalid_downlink(char const *reason); + + + /******************** + ** Root_component ** + ********************/ + + Nic_session_component *_create_session(char const *args) override; + void _destroy_session(Nic_session_component *session) override; + + public: + + Nic_session_root(Genode::Env &env, + Timer::Connection &timer, + Genode::Allocator &alloc, + Configuration &config, + Quota &shared_quota, + Interface_list &interfaces); + + void handle_config(Configuration &config) { _config = Reference(config); } +}; + +#endif /* _NIC_SESSION_ROOT_H_ */ diff --git a/repos/os/src/server/nic_router/session_env.h b/repos/os/src/server/nic_router/session_env.h new file mode 100644 index 0000000000..f399494b60 --- /dev/null +++ b/repos/os/src/server/nic_router/session_env.h @@ -0,0 +1,196 @@ +/* + * \brief Guarded Genode environment for session components + * \author Martin Stein + * \date 2020-11-30 + */ + +/* + * Copyright (C) 2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _SESSION_ENV_H_ +#define _SESSION_ENV_H_ + +/* Genode includes */ +#include + +namespace Genode { class Session_env; } + + +class Genode::Session_env : public Ram_allocator, + public Region_map +{ + private: + + Env &_env; + Net::Quota &_shared_quota; + Ram_quota_guard _ram_guard; + Cap_quota_guard _cap_guard; + + template + void _consume(size_t own_ram, + size_t max_shared_ram, + size_t own_cap, + size_t max_shared_cap, + FUNC && functor) + { + size_t const max_ram_consumpt { own_ram + max_shared_ram }; + size_t const max_cap_consumpt { own_cap + max_shared_cap }; + size_t ram_consumpt { _env.pd().used_ram().value }; + size_t cap_consumpt { _env.pd().used_caps().value }; + { + Ram_quota_guard::Reservation ram_reserv { _ram_guard, Ram_quota { max_ram_consumpt } }; + Cap_quota_guard::Reservation cap_reserv { _cap_guard, Cap_quota { max_cap_consumpt } }; + + functor(); + + ram_reserv.acknowledge(); + cap_reserv.acknowledge(); + } + ram_consumpt = _env.pd().used_ram().value - ram_consumpt; + cap_consumpt = _env.pd().used_caps().value - cap_consumpt; + + if (ram_consumpt > max_ram_consumpt) { + error("Session_env: more RAM quota consumed than expected"); } + if (cap_consumpt > max_cap_consumpt) { + error("Session_env: more CAP quota consumed than expected"); } + if (ram_consumpt < own_ram) { + error("Session_env: less RAM quota consumed than expected"); } + if (cap_consumpt < own_cap) { + error("Session_env: less CAP quota consumed than expected"); } + + _shared_quota.ram += ram_consumpt - own_ram; + _shared_quota.cap += cap_consumpt - own_cap; + + _ram_guard.replenish( Ram_quota { max_shared_ram } ); + _cap_guard.replenish( Cap_quota { max_shared_cap } ); + } + + template + void _replenish(size_t accounted_ram, + size_t accounted_cap, + FUNC && functor) + { + size_t ram_replenish { _env.pd().used_ram().value }; + size_t cap_replenish { _env.pd().used_caps().value }; + functor(); + ram_replenish = ram_replenish - _env.pd().used_ram().value; + cap_replenish = cap_replenish - _env.pd().used_caps().value; + + if (ram_replenish < accounted_ram) { + error("Session_env: less RAM quota replenished than expected"); } + if (cap_replenish < accounted_cap) { + error("Session_env: less CAP quota replenished than expected"); } + + _shared_quota.ram -= ram_replenish - accounted_ram; + _shared_quota.cap -= cap_replenish - accounted_cap; + + _ram_guard.replenish( Ram_quota { accounted_ram } ); + _cap_guard.replenish( Cap_quota { accounted_cap } ); + + } + + public: + + Session_env(Env &env, + Net::Quota &shared_quota, + Ram_quota const &ram_quota, + Cap_quota const &cap_quota) + : + _env { env }, + _shared_quota { shared_quota }, + _ram_guard { ram_quota }, + _cap_guard { cap_quota } + { } + + Entrypoint &ep() { return _env.ep(); } + + + /******************* + ** Ram_allocator ** + *******************/ + + Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override + { + enum { MAX_SHARED_CAP = 1 }; + enum { MAX_SHARED_RAM = 4096 }; + enum { DS_SIZE_GRANULARITY_LOG2 = 12 }; + + size_t const ds_size = align_addr(size, DS_SIZE_GRANULARITY_LOG2); + Ram_dataspace_capability ds; + _consume(ds_size, MAX_SHARED_RAM, 1, MAX_SHARED_CAP, [&] () { + ds = _env.pd().alloc(ds_size, cached); + }); + return ds; + } + + + void free(Ram_dataspace_capability ds) override + { + _replenish(_env.pd().dataspace_size(ds), 1, [&] () { + _env.pd().free(ds); + }); + } + + size_t dataspace_size(Ram_dataspace_capability ds) const override { return _env.pd().dataspace_size(ds); } + + + /**************** + ** Region_map ** + ****************/ + + Local_addr attach(Dataspace_capability ds, + size_t size = 0, + off_t offset = 0, + bool use_local_addr = false, + Local_addr local_addr = (void *)0, + bool executable = false, + bool writeable = true) override + { + enum { MAX_SHARED_CAP = 2 }; + enum { MAX_SHARED_RAM = 4 * 4096 }; + + void *ptr; + _consume(0, MAX_SHARED_RAM, 0, MAX_SHARED_CAP, [&] () { + ptr = _env.rm().attach(ds, size, offset, use_local_addr, + local_addr, executable, writeable); + }); + return ptr; + }; + + void report(Genode::Xml_generator &xml) const + { + xml.node("ram-quota", [&] () { + xml.attribute("used", _ram_guard.used().value); + xml.attribute("limit", _ram_guard.limit().value); + xml.attribute("avail", _ram_guard.avail().value); + }); + xml.node("cap-quota", [&] () { + xml.attribute("used", _cap_guard.used().value); + xml.attribute("limit", _cap_guard.limit().value); + xml.attribute("avail", _cap_guard.avail().value); + }); + } + + void detach(Local_addr local_addr) override + { + _replenish(0, 0, [&] () { _env.rm().detach(local_addr); }); + } + + void fault_handler(Signal_context_capability handler) override { _env.rm().fault_handler(handler); } + State state() override { return _env.rm().state(); } + Dataspace_capability dataspace() override { return _env.rm().dataspace(); } + + + /*************** + ** Accessors ** + ***************/ + + Ram_quota_guard const &ram_guard() const { return _ram_guard; }; + Cap_quota_guard const &cap_guard() const { return _cap_guard; }; +}; + +#endif /* _SESSION_ENV_H_ */ diff --git a/repos/os/src/server/nic_router/target.mk b/repos/os/src/server/nic_router/target.mk index 011e8cba8b..66a6b20bfb 100644 --- a/repos/os/src/server/nic_router/target.mk +++ b/repos/os/src/server/nic_router/target.mk @@ -2,13 +2,34 @@ TARGET = nic_router LIBS += base net -SRC_CC += arp_waiter.cc ip_rule.cc ipv4_address_prefix.cc -SRC_CC += component.cc port_allocator.cc forward_rule.cc -SRC_CC += nat_rule.cc main.cc ipv4_config.cc -SRC_CC += uplink.cc interface.cc arp_cache.cc configuration.cc -SRC_CC += domain.cc l3_protocol.cc direct_rule.cc link.cc -SRC_CC += transport_rule.cc permit_rule.cc dns_server.cc -SRC_CC += dhcp_client.cc dhcp_server.cc report.cc xml_node.cc +SRC_CC += \ + arp_waiter.cc \ + ip_rule.cc \ + ipv4_address_prefix.cc \ + nic_session_root.cc \ + port_allocator.cc \ + forward_rule.cc \ + nat_rule.cc \ + main.cc \ + ipv4_config.cc \ + uplink.cc \ + interface.cc \ + arp_cache.cc \ + configuration.cc \ + domain.cc \ + l3_protocol.cc \ + direct_rule.cc \ + link.cc \ + transport_rule.cc \ + permit_rule.cc \ + dns_server.cc \ + dhcp_client.cc \ + dhcp_server.cc \ + report.cc \ + xml_node.cc \ + uplink_session_root.cc \ + communication_buffer.cc \ + INC_DIR += $(PRG_DIR) diff --git a/repos/os/src/server/nic_router/uplink_session_root.cc b/repos/os/src/server/nic_router/uplink_session_root.cc new file mode 100644 index 0000000000..50f16028ec --- /dev/null +++ b/repos/os/src/server/nic_router/uplink_session_root.cc @@ -0,0 +1,256 @@ +/* + * \brief Downlink interface in form of an Uplink session component + * \author Martin Stein + * \date 2016-08-23 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode includes */ +#include + +/* local includes */ +#include +#include + +using namespace Net; +using namespace Genode; + + +/*********************************** + ** Uplink_session_component_base ** + ***********************************/ + +Uplink_session_component_base:: +Uplink_session_component_base(Session_env &session_env, + size_t const tx_buf_size, + size_t const rx_buf_size) +: + _session_env { session_env }, + _alloc { _session_env, _session_env }, + _packet_alloc { &_alloc }, + _tx_buf { _session_env, tx_buf_size }, + _rx_buf { _session_env, rx_buf_size } +{ } + + +/************************************************ + ** Uplink_session_component::Interface_policy ** + ************************************************/ + +Net::Uplink_session_component:: +Interface_policy::Interface_policy(Genode::Session_label const &label, + Session_env const &session_env, + Configuration const &config) +: + _label { label }, + _config { config }, + _session_env { session_env } +{ } + + +Domain_name +Net::Uplink_session_component::Interface_policy::determine_domain_name() const +{ + Domain_name domain_name; + try { + Session_policy policy(_label, _config().node()); + domain_name = policy.attribute_value("domain", Domain_name()); + } + catch (Session_policy::No_policy_defined) { + 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; +} + + +/****************************** + ** Uplink_session_component ** + ******************************/ + +Net::Uplink_session_component::Uplink_session_component(Session_env &session_env, + size_t const tx_buf_size, + size_t const rx_buf_size, + Timer::Connection &timer, + Mac_address const mac, + Session_label const &label, + Interface_list &interfaces, + Configuration &config, + Ram_dataspace_capability const ram_ds) +: + Uplink_session_component_base { session_env, tx_buf_size,rx_buf_size }, + Session_rpc_object { _session_env, _tx_buf.ds(), _rx_buf.ds(), + &_packet_alloc, _session_env.ep().rpc_ep() }, + _interface_policy { label, _session_env, config }, + _interface { _session_env.ep(), timer, mac, _alloc, + Mac_address(), config, interfaces, *_tx.sink(), + *_rx.source(), _interface_policy }, + _ram_ds { ram_ds } +{ + _interface.attach_to_domain(); + + _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()); +} + + +/************************* + ** Uplink_session_root ** + *************************/ + +Net::Uplink_session_root::Uplink_session_root(Env &env, + Timer::Connection &timer, + Allocator &alloc, + Configuration &config, + Quota &shared_quota, + Interface_list &interfaces) +: + Root_component { &env.ep().rpc_ep(), &alloc }, + _env { env }, + _timer { timer }, + _config { config }, + _shared_quota { shared_quota }, + _interfaces { interfaces } +{ } + + +Uplink_session_component * +Net::Uplink_session_root::_create_session(char const *args) +{ + try { + /* create session environment temporarily on the stack */ + Session_env session_env_stack { _env, _shared_quota, + Ram_quota { Arg_string::find_arg(args, "ram_quota").ulong_value(0) }, + Cap_quota { Arg_string::find_arg(args, "cap_quota").ulong_value(0) } }; + + /* alloc/attach RAM block and move session env to base of the block */ + Ram_dataspace_capability ram_ds { + session_env_stack.alloc(sizeof(Session_env) + + sizeof(Uplink_session_component), CACHED) }; + try { + void * const ram_ptr { session_env_stack.attach(ram_ds) }; + Session_env &session_env { + *construct_at(ram_ptr, session_env_stack) }; + + Session_label const label { label_from_args(args) }; + + enum { MAC_STR_LENGTH = 19 }; + char mac_str [MAC_STR_LENGTH]; + Arg mac_arg { Arg_string::find_arg(args, "mac_address") }; + + if (!mac_arg.valid()) { + Session_env session_env_stack { session_env }; + session_env_stack.detach(ram_ptr); + session_env_stack.free(ram_ds); + _invalid_downlink("failed to find 'mac_address' arg"); + throw Service_denied(); + } + mac_arg.string(mac_str, MAC_STR_LENGTH, ""); + Mac_address mac { }; + ascii_to(mac_str, mac); + if (mac == Mac_address { }) { + Session_env session_env_stack { session_env }; + session_env_stack.detach(ram_ptr); + session_env_stack.free(ram_ds); + _invalid_downlink("malformed 'mac_address' arg"); + throw Service_denied(); + } + /* create new session object behind session env in the RAM block */ + try { + return construct_at( + (void*)((addr_t)ram_ptr + sizeof(Session_env)), + session_env, + Arg_string::find_arg(args, "tx_buf_size").ulong_value(0), + Arg_string::find_arg(args, "rx_buf_size").ulong_value(0), + _timer, mac, label, _interfaces, _config(), ram_ds); + } + catch (Out_of_ram) { + Session_env session_env_stack { session_env }; + session_env_stack.detach(ram_ptr); + session_env_stack.free(ram_ds); + _invalid_downlink("Uplink session RAM quota"); + throw Insufficient_ram_quota(); + } + catch (Out_of_caps) { + Session_env session_env_stack { session_env }; + session_env_stack.detach(ram_ptr); + session_env_stack.free(ram_ds); + _invalid_downlink("Uplink session CAP quota"); + throw Insufficient_cap_quota(); + } + } + catch (Region_map::Invalid_dataspace) { + session_env_stack.free(ram_ds); + _invalid_downlink("Failed to attach RAM"); + throw Service_denied(); + } + catch (Region_map::Region_conflict) { + session_env_stack.free(ram_ds); + _invalid_downlink("Failed to attach RAM"); + throw Service_denied(); + } + catch (Out_of_ram) { + session_env_stack.free(ram_ds); + _invalid_downlink("Uplink session RAM quota"); + throw Insufficient_ram_quota(); + } + catch (Out_of_caps) { + session_env_stack.free(ram_ds); + _invalid_downlink("Uplink session CAP quota"); + throw Insufficient_cap_quota(); + } + } + catch (Out_of_ram) { + _invalid_downlink("Uplink session RAM quota"); + throw Insufficient_ram_quota(); + } + catch (Out_of_caps) { + _invalid_downlink("Uplink session CAP quota"); + throw Insufficient_cap_quota(); + } +} + +void +Net::Uplink_session_root::_destroy_session(Uplink_session_component *session) +{ + /* read out initial dataspace and session env and destruct session */ + Ram_dataspace_capability ram_ds { session->ram_ds() }; + Session_env const &session_env { session->session_env() }; + Session_label const session_label { session->interface_policy().label() }; + session->~Uplink_session_component(); + + /* copy session env to stack and detach/free all session data */ + Session_env session_env_stack { session_env }; + session_env_stack.detach(session); + session_env_stack.detach(&session_env); + session_env_stack.free(ram_ds); + + /* check for leaked quota */ + if (session_env_stack.ram_guard().used().value) { + error("Uplink session component \"", session_label, "\" leaks RAM quota of ", + session_env_stack.ram_guard().used().value, " byte(s)"); }; + if (session_env_stack.cap_guard().used().value) { + error("Uplink session component \"", session_label, "\" leaks CAP quota of ", + session_env_stack.cap_guard().used().value, " cap(s)"); }; +} + + +void Net::Uplink_session_root::_invalid_downlink(char const *reason) +{ + if (_config().verbose()) { + log("[?] invalid downlink (", reason, ")"); } +} diff --git a/repos/os/src/server/nic_router/uplink_session_root.h b/repos/os/src/server/nic_router/uplink_session_root.h new file mode 100644 index 0000000000..d85c67f1de --- /dev/null +++ b/repos/os/src/server/nic_router/uplink_session_root.h @@ -0,0 +1,153 @@ +/* + * \brief Downlink interface in form of an Uplink session component + * \author Martin Stein + * \date 2016-08-23 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _UPLINK_SESSION_ROOT_H_ +#define _UPLINK_SESSION_ROOT_H_ + +/* Genode includes */ +#include +#include +#include +#include + +/* local includes */ +#include +#include +#include +#include +#include +#include + +namespace Net { + + class Uplink_session_component_base; + class Uplink_session_component; + class Uplink_session_root; +} + + +class Net::Uplink_session_component_base +{ + protected: + + Genode::Session_env &_session_env; + Genode::Heap _alloc; + Nic::Packet_allocator _packet_alloc; + Communication_buffer _tx_buf; + Communication_buffer _rx_buf; + + public: + + Uplink_session_component_base(Genode::Session_env &session_env, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size); +}; + + +class Net::Uplink_session_component : private Uplink_session_component_base, + public ::Uplink::Session_rpc_object +{ + private: + + class Interface_policy : public Net::Interface_policy + { + private: + + Genode::Session_label const _label; + Const_reference _config; + Genode::Session_env const &_session_env; + + public: + + Interface_policy(Genode::Session_label const &label, + Genode::Session_env const &session_env, + Configuration const &config); + + + /*************************** + ** Net::Interface_policy ** + ***************************/ + + Domain_name determine_domain_name() const override; + void handle_config(Configuration const &config) override { _config = config; } + Genode::Session_label const &label() const override { return _label; } + void report(Genode::Xml_generator &xml) const override { _session_env.report(xml); }; + void interface_unready() override { } + void interface_ready() override { } + bool interface_link_state() const override { return true; } + }; + + Interface_policy _interface_policy; + Interface _interface; + Genode::Ram_dataspace_capability const _ram_ds; + + public: + + Uplink_session_component(Genode::Session_env &session_env, + Genode::size_t const tx_buf_size, + Genode::size_t const rx_buf_size, + Timer::Connection &timer, + Mac_address const mac, + Genode::Session_label const &label, + Interface_list &interfaces, + Configuration &config, + Genode::Ram_dataspace_capability const ram_ds); + + + /*************** + ** Accessors ** + ***************/ + + Interface_policy const &interface_policy() const { return _interface_policy; } + Genode::Ram_dataspace_capability ram_ds() const { return _ram_ds; }; + Genode::Session_env const &session_env() const { return _session_env; }; +}; + + +class Net::Uplink_session_root +: + public Genode::Root_component +{ + private: + + enum { MAC_ALLOC_BASE = 0x02 }; + + Genode::Env &_env; + Timer::Connection &_timer; + Reference _config; + Quota &_shared_quota; + Interface_list &_interfaces; + + void _invalid_downlink(char const *reason); + + + /******************** + ** Root_component ** + ********************/ + + Uplink_session_component *_create_session(char const *args) override; + void _destroy_session(Uplink_session_component *session) override; + + public: + + Uplink_session_root(Genode::Env &env, + Timer::Connection &timer, + Genode::Allocator &alloc, + Configuration &config, + Quota &shared_quota, + Interface_list &interfaces); + + void handle_config(Configuration &config) { _config = Reference(config); } +}; + +#endif /* _UPLINK_SESSION_ROOT_H_ */ diff --git a/repos/ports/run/netperf.inc b/repos/ports/run/netperf.inc index be873c3460..da04b75ff8 100644 --- a/repos/ports/run/netperf.inc +++ b/repos/ports/run/netperf.inc @@ -221,7 +221,10 @@ append config { append_if $use_nic_router config { - + + + +