2016-08-25 17:48:53 +02:00
|
|
|
/*
|
|
|
|
* \brief Downlink interface in form of a NIC session component
|
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2016-08-23
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-01-13 19:38:23 +01:00
|
|
|
* Copyright (C) 2016-2017 Genode Labs GmbH
|
2016-08-25 17:48:53 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2016-08-25 17:48:53 +02:00
|
|
|
*/
|
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
/* Genode includes */
|
|
|
|
#include <os/session_policy.h>
|
|
|
|
|
2016-08-25 17:48:53 +02:00
|
|
|
/* local includes */
|
|
|
|
#include <component.h>
|
2016-09-12 12:55:12 +02:00
|
|
|
#include <configuration.h>
|
2016-08-25 17:48:53 +02:00
|
|
|
|
|
|
|
using namespace Net;
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
/**************************
|
|
|
|
** Communication_buffer **
|
|
|
|
**************************/
|
2016-08-25 17:48:53 +02:00
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
Communication_buffer::Communication_buffer(Ram_session &ram,
|
|
|
|
Genode::size_t const size)
|
|
|
|
:
|
|
|
|
Ram_dataspace_capability(ram.alloc(size)), _ram(ram)
|
|
|
|
{ }
|
2016-08-25 17:48:53 +02:00
|
|
|
|
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
/****************************
|
|
|
|
** Session_component_base **
|
|
|
|
****************************/
|
2016-08-25 17:48:53 +02:00
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
Session_component_base::
|
|
|
|
Session_component_base(Allocator &guarded_alloc_backing,
|
|
|
|
size_t const guarded_alloc_amount,
|
|
|
|
Ram_session &buf_ram,
|
|
|
|
size_t const tx_buf_size,
|
|
|
|
size_t const rx_buf_size)
|
2016-08-25 17:48:53 +02:00
|
|
|
:
|
2016-09-12 12:55:12 +02:00
|
|
|
_guarded_alloc(&guarded_alloc_backing, guarded_alloc_amount),
|
|
|
|
_range_alloc(&_guarded_alloc), _tx_buf(buf_ram, tx_buf_size),
|
|
|
|
_rx_buf(buf_ram, rx_buf_size)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
/***********************
|
|
|
|
** Session_component **
|
|
|
|
***********************/
|
|
|
|
|
|
|
|
Net::Session_component::Session_component(Allocator &alloc,
|
|
|
|
Genode::Timer &timer,
|
|
|
|
size_t const amount,
|
|
|
|
Ram_session &buf_ram,
|
|
|
|
size_t const tx_buf_size,
|
|
|
|
size_t const rx_buf_size,
|
2017-01-13 19:38:23 +01:00
|
|
|
Region_map ®ion_map,
|
2016-09-12 12:55:12 +02:00
|
|
|
Mac_address const mac,
|
|
|
|
Entrypoint &ep,
|
|
|
|
Mac_address const &router_mac,
|
|
|
|
Domain &domain)
|
|
|
|
:
|
|
|
|
Session_component_base(alloc, amount, buf_ram, tx_buf_size, rx_buf_size),
|
2017-01-13 19:38:23 +01:00
|
|
|
Session_rpc_object(region_map, _tx_buf, _rx_buf, &_range_alloc, ep.rpc_ep()),
|
2016-09-12 12:55:12 +02:00
|
|
|
Interface(ep, timer, router_mac, _guarded_alloc, mac, domain)
|
2016-08-25 17:48:53 +02:00
|
|
|
{
|
|
|
|
_tx.sigh_ready_to_ack(_sink_ack);
|
|
|
|
_tx.sigh_packet_avail(_sink_submit);
|
|
|
|
_rx.sigh_ack_avail(_source_ack);
|
|
|
|
_rx.sigh_ready_to_submit(_source_submit);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
bool Session_component::link_state()
|
|
|
|
{
|
|
|
|
warning("Session_component::link_state not implemented");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Session_component::link_state_sigh(Signal_context_capability sigh)
|
|
|
|
{
|
|
|
|
warning("Session_component::link_state_sigh not implemented");
|
|
|
|
}
|
|
|
|
|
2016-08-25 17:48:53 +02:00
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
/**********
|
|
|
|
** Root **
|
|
|
|
**********/
|
2016-08-25 17:48:53 +02:00
|
|
|
|
2016-09-12 12:55:12 +02:00
|
|
|
Net::Root::Root(Entrypoint &ep,
|
|
|
|
Genode::Timer &timer,
|
|
|
|
Allocator &alloc,
|
|
|
|
Mac_address const &router_mac,
|
|
|
|
Configuration &config,
|
2017-01-13 19:38:23 +01:00
|
|
|
Ram_session &buf_ram,
|
|
|
|
Region_map ®ion_map)
|
2016-08-25 17:48:53 +02:00
|
|
|
:
|
2016-09-12 12:55:12 +02:00
|
|
|
Root_component<Session_component>(&ep.rpc_ep(), &alloc), _timer(timer),
|
2017-01-13 19:38:23 +01:00
|
|
|
_ep(ep), _router_mac(router_mac), _config(config), _buf_ram(buf_ram),
|
|
|
|
_region_map(region_map)
|
2016-08-25 17:48:53 +02:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
Session_component *Net::Root::_create_session(char const *args)
|
|
|
|
{
|
|
|
|
try {
|
2016-09-12 12:55:12 +02:00
|
|
|
Session_label const label = label_from_args(args);
|
|
|
|
Session_policy policy(label, _config.node());
|
2016-12-22 01:02:50 +01:00
|
|
|
Domain_name domain_name(policy.attribute_value("domain", Domain_name()));
|
2016-09-12 12:55:12 +02:00
|
|
|
|
|
|
|
Domain &domain = _config.domains().find_by_name(domain_name);
|
|
|
|
|
|
|
|
size_t const ram_quota =
|
|
|
|
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
|
|
|
|
|
|
|
size_t const tx_buf_size =
|
|
|
|
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
|
|
|
|
|
|
|
size_t const rx_buf_size =
|
|
|
|
Arg_string::find_arg(args, "rx_buf_size").ulong_value(0);
|
|
|
|
|
|
|
|
size_t const session_size =
|
|
|
|
max((size_t)4096, sizeof(Session_component));
|
|
|
|
|
|
|
|
if (ram_quota < session_size) {
|
|
|
|
throw Root::Quota_exceeded(); }
|
|
|
|
|
|
|
|
if (tx_buf_size > ram_quota - session_size ||
|
|
|
|
rx_buf_size > ram_quota - session_size ||
|
|
|
|
tx_buf_size + rx_buf_size > ram_quota - session_size)
|
|
|
|
{
|
|
|
|
error("insufficient 'ram_quota' for session creation");
|
|
|
|
throw Root::Quota_exceeded();
|
|
|
|
}
|
|
|
|
return new (md_alloc())
|
|
|
|
Session_component(*md_alloc(), _timer, ram_quota - session_size,
|
2017-01-13 19:38:23 +01:00
|
|
|
_buf_ram, tx_buf_size, rx_buf_size, _region_map,
|
2016-09-12 12:55:12 +02:00
|
|
|
_mac_alloc.alloc(), _ep, _router_mac,
|
|
|
|
domain);
|
2016-08-25 17:48:53 +02:00
|
|
|
}
|
2016-09-12 12:55:12 +02:00
|
|
|
catch (Session_policy::No_policy_defined) {
|
|
|
|
error("no matching policy");
|
2016-08-25 17:48:53 +02:00
|
|
|
}
|
2016-09-12 12:55:12 +02:00
|
|
|
catch (Domain_tree::No_match) {
|
|
|
|
error("no matching domain");
|
2016-08-25 17:48:53 +02:00
|
|
|
}
|
|
|
|
catch (Mac_allocator::Alloc_failed) {
|
|
|
|
error("failed to allocate MAC address");
|
|
|
|
}
|
2016-09-12 12:55:12 +02:00
|
|
|
catch (Xml_node::Nonexistent_attribute) {
|
|
|
|
error("missing domain attribute in policy");
|
|
|
|
}
|
|
|
|
catch (Pointer<Interface>::Valid) {
|
|
|
|
error("one session per domain only");
|
|
|
|
}
|
|
|
|
throw Root::Unavailable();
|
2016-08-25 17:48:53 +02:00
|
|
|
}
|