mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-21 03:55:04 +00:00
nic_router: act as "Uplink" server
Let the NIC router provide an Uplink service besides the Nic service that it already provided. Requests for an Uplink session towards the NIC router are assigned to Domains using the same <policy> configuration tags that are used in order to assign Nic session requests. The MAC addresses of Uplink session components are _NOT_ considered during the allocation of MAC addresses for NIC session components at the same Domain. The task of avoiding MAC address clashes between Uplink session components and Nic session components is therefore left to the integrator. Apart from that, Uplink session components are treated by the NIC router like any other interface. Ref #3961
This commit is contained in:
parent
cf72d1aac3
commit
1d2649b49a
@ -317,7 +317,10 @@ append config {
|
||||
<start name="router" caps="200" priority="-2">
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="Nic" label="nic">
|
||||
<child name="nic_drv"/>
|
||||
|
@ -3,6 +3,7 @@ os
|
||||
report_session
|
||||
file_system_session
|
||||
nic_session
|
||||
uplink_session
|
||||
timer_session
|
||||
block_session
|
||||
usb_session
|
||||
|
@ -11,6 +11,10 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <uplink_session/uplink_session.h>
|
||||
|
||||
/* local includes */
|
||||
#include <runtime.h>
|
||||
|
||||
|
||||
@ -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<Nic::Session>(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", [&] () {
|
||||
|
||||
|
@ -39,7 +39,10 @@
|
||||
|
||||
<start name="nic_router">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
<domain name="default" interface="10.0.1.1/24"/>
|
||||
<default-policy domain="default"/>
|
||||
|
@ -40,7 +40,10 @@
|
||||
|
||||
<start name="nic_router">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
<domain name="default" interface="10.0.1.1/24"/>
|
||||
<default-policy domain="default"/>
|
||||
|
@ -40,7 +40,10 @@
|
||||
|
||||
<start name="nic_router">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
<domain name="default" interface="10.0.1.1/24"/>
|
||||
<default-policy domain="default"/>
|
||||
|
@ -41,7 +41,10 @@
|
||||
|
||||
<start name="nic_router">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
<domain name="default" interface="10.0.1.1/24"/>
|
||||
<default-policy domain="default"/>
|
||||
|
@ -188,7 +188,10 @@ proc test_7_config { } {
|
||||
<start name="t7_d1_nic_router" caps="200" priority="-1">
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
|
||||
<policy label_prefix="t7_d1" domain="downlink" />
|
||||
@ -286,7 +289,10 @@ append config {
|
||||
|
||||
<start name="nic_router" caps="400" priority="-1">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose="no"
|
||||
verbose_packets="no"
|
||||
verbose_domain_state="yes"
|
||||
|
@ -378,7 +378,10 @@ append config {
|
||||
|
||||
<start name="nic_router" caps="200" priority="-1">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <child name="dynamic_rom" label="nic_router.config"/> </service>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
|
@ -1,5 +1,6 @@
|
||||
base
|
||||
os
|
||||
nic_session
|
||||
uplink_session
|
||||
timer_session
|
||||
report_session
|
||||
|
@ -81,7 +81,10 @@ append config {
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose="no"
|
||||
verbose_packets="no"
|
||||
dhcp_discover_timeout_sec="1"
|
||||
@ -117,7 +120,10 @@ append config {
|
||||
<start name="ping_2_nic_router" caps="200">
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose="no"
|
||||
verbose_packets="no"
|
||||
icmp_idle_timeout_sec="10">
|
||||
|
@ -142,7 +142,10 @@ append config {
|
||||
<start name="nic_router_1">
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child name="dynamic_rom" label="nic_router_1.config"/>
|
||||
@ -154,7 +157,10 @@ append config {
|
||||
<start name="nic_router_2">
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>}
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>}
|
||||
|
||||
append_if [expr ![nic_router_2_managed]] config {
|
||||
|
||||
|
@ -51,7 +51,10 @@ append config {
|
||||
|
||||
<start name="nic_router">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
|
||||
<policy label_prefix="ping" domain="downlink"/>
|
||||
|
@ -142,7 +142,10 @@ install_config {
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <child name="dynamic_rom" label="nic_router.config"/> </service>
|
||||
<service name="Nic"> <child name="drivers"/> </service>
|
||||
|
@ -83,7 +83,10 @@ append_if [string equal $type "nic_router"] config {
|
||||
|
||||
<start name="nic_router" caps="1000">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_prefix="nic_stress_2" domain="default"/>
|
||||
<policy label_prefix="nic_stress_1" domain="default"/>
|
||||
@ -97,7 +100,10 @@ append_if [string equal $type "nic_bridge"] config {
|
||||
|
||||
<start name="nic_router" caps="1000">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config>
|
||||
<policy label_prefix="nic_bridge" domain="default"/>
|
||||
<domain name="default" interface="10.0.2.55/24"/>
|
||||
|
@ -61,7 +61,10 @@ append config {
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose="no"
|
||||
verbose_packets="no"
|
||||
dhcp_discover_timeout_sec="1"
|
||||
@ -100,7 +103,10 @@ append config {
|
||||
<start name="ping_2_nic_router" caps="200">
|
||||
<binary name="nic_router"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose="no"
|
||||
verbose_packets="no"
|
||||
icmp_idle_timeout_sec="10">
|
||||
|
26
repos/os/src/server/nic_router/communication_buffer.cc
Normal file
26
repos/os/src/server/nic_router/communication_buffer.cc
Normal file
@ -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 <communication_buffer.h>
|
||||
|
||||
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) }
|
||||
{ }
|
46
repos/os/src/server/nic_router/communication_buffer.h
Normal file
46
repos/os/src/server/nic_router/communication_buffer.h
Normal file
@ -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 <dataspace/capability.h>
|
||||
#include <base/ram_allocator.h>
|
||||
|
||||
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_ */
|
@ -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 <base/heap.h>
|
||||
#include <root/component.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/rpc_object.h>
|
||||
|
||||
/* local includes */
|
||||
#include <mac_allocator.h>
|
||||
#include <interface.h>
|
||||
#include <reference.h>
|
||||
#include <report.h>
|
||||
|
||||
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 <typename FUNC>
|
||||
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 <typename FUNC>
|
||||
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<Configuration> _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<Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
enum { MAC_ALLOC_BASE = 0x02 };
|
||||
|
||||
Genode::Env &_env;
|
||||
Timer::Connection &_timer;
|
||||
Mac_allocator _mac_alloc;
|
||||
Mac_address const _router_mac;
|
||||
Reference<Configuration> _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<Configuration>(config); }
|
||||
};
|
||||
|
||||
#endif /* _COMPONENT_H_ */
|
@ -18,7 +18,8 @@
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include <component.h>
|
||||
#include <nic_session_root.h>
|
||||
#include <uplink_session_root.h>
|
||||
#include <uplink.h>
|
||||
#include <configuration.h>
|
||||
|
||||
@ -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<Configuration> _config { *new (_heap) Configuration { _config_rom.xml(), _heap } };
|
||||
Signal_handler<Main> _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<Configuration> _config { *new (_heap) Configuration { _config_rom.xml(), _heap } };
|
||||
Signal_handler<Main> _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<Configuration>(new_config);
|
||||
|
@ -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 <os/session_policy.h>
|
||||
|
||||
/* local includes */
|
||||
#include <component.h>
|
||||
#include <nic_session_root.h>
|
||||
#include <configuration.h>
|
||||
|
||||
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<Session_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<Nic_session_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<Session_component>(
|
||||
return construct_at<Nic_session_component>(
|
||||
(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, ")"); }
|
201
repos/os/src/server/nic_router/nic_session_root.h
Normal file
201
repos/os/src/server/nic_router/nic_session_root.h
Normal file
@ -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 <base/heap.h>
|
||||
#include <root/component.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/rpc_object.h>
|
||||
|
||||
/* local includes */
|
||||
#include <mac_allocator.h>
|
||||
#include <interface.h>
|
||||
#include <reference.h>
|
||||
#include <report.h>
|
||||
#include <session_env.h>
|
||||
#include <communication_buffer.h>
|
||||
|
||||
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<Configuration> _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<Nic_session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
enum { MAC_ALLOC_BASE = 0x02 };
|
||||
|
||||
Genode::Env &_env;
|
||||
Timer::Connection &_timer;
|
||||
Mac_allocator _mac_alloc;
|
||||
Mac_address const _router_mac;
|
||||
Reference<Configuration> _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<Configuration>(config); }
|
||||
};
|
||||
|
||||
#endif /* _NIC_SESSION_ROOT_H_ */
|
196
repos/os/src/server/nic_router/session_env.h
Normal file
196
repos/os/src/server/nic_router/session_env.h
Normal file
@ -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 <base/ram_allocator.h>
|
||||
|
||||
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 <typename FUNC>
|
||||
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 <typename FUNC>
|
||||
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_ */
|
@ -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)
|
||||
|
||||
|
256
repos/os/src/server/nic_router/uplink_session_root.cc
Normal file
256
repos/os/src/server/nic_router/uplink_session_root.cc
Normal file
@ -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 <os/session_policy.h>
|
||||
|
||||
/* local includes */
|
||||
#include <uplink_session_root.h>
|
||||
#include <configuration.h>
|
||||
|
||||
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<Uplink_session_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<Session_env>(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<Uplink_session_component>(
|
||||
(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, ")"); }
|
||||
}
|
153
repos/os/src/server/nic_router/uplink_session_root.h
Normal file
153
repos/os/src/server/nic_router/uplink_session_root.h
Normal file
@ -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 <base/heap.h>
|
||||
#include <root/component.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <uplink_session/rpc_object.h>
|
||||
|
||||
/* local includes */
|
||||
#include <mac_allocator.h>
|
||||
#include <interface.h>
|
||||
#include <reference.h>
|
||||
#include <report.h>
|
||||
#include <session_env.h>
|
||||
#include <communication_buffer.h>
|
||||
|
||||
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<Configuration> _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<Uplink_session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
enum { MAC_ALLOC_BASE = 0x02 };
|
||||
|
||||
Genode::Env &_env;
|
||||
Timer::Connection &_timer;
|
||||
Reference<Configuration> _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<Configuration>(config); }
|
||||
};
|
||||
|
||||
#endif /* _UPLINK_SESSION_ROOT_H_ */
|
@ -221,7 +221,10 @@ append config { </wifi_config>
|
||||
append_if $use_nic_router config {
|
||||
<start name="nic_router" caps="120">
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose_domain_state="yes">
|
||||
|
||||
<policy label_prefix="netserver_genode" domain="server"/>
|
||||
|
Loading…
Reference in New Issue
Block a user