mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
nic_bridge: transition to the new base API
* use Component::* instead of Server::* * do not use old printf format anymore * do not use old Genode::env()->heap() anymore * avoid pointers where possible, and use references instead * throw away the thread-safe variants of list and AVL tree, nic_bridge became single-threaded in the past * introduce Ram_session_guard instead of Allocator_guard Issue #1987
This commit is contained in:
parent
d9f33f7577
commit
a145e6ad70
@ -66,6 +66,7 @@ append_if $use_nic_bridge config {
|
||||
<start name="nic_bridge">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config/>
|
||||
<route>
|
||||
<service name="Nic"> }
|
||||
append_if [expr $use_nic_bridge && ([have_spec omap4] || [have_spec arndale])] config {
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/exception.h>
|
||||
#include <base/output.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <util/endian.h>
|
||||
@ -43,7 +44,21 @@ class Net::Ethernet_frame
|
||||
ADDR_LEN = 6, /* MAC address length in bytes */
|
||||
};
|
||||
|
||||
typedef Network_address<ADDR_LEN> Mac_address;
|
||||
struct Mac_address : Network_address<ADDR_LEN>
|
||||
{
|
||||
using Network_address<ADDR_LEN>::Network_address;
|
||||
|
||||
void print(Genode::Output &output) const
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
for (unsigned i = 0; i < ADDR_LEN; i++) {
|
||||
Genode::print(output, Hex(addr[i], Hex::OMIT_PREFIX,
|
||||
Hex::PAD));
|
||||
if (i < ADDR_LEN-1) output.out_char(':');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const Mac_address BROADCAST; /* broadcast address */
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
/* Genode */
|
||||
#include <base/exception.h>
|
||||
#include <base/output.h>
|
||||
#include <util/string.h>
|
||||
|
||||
#include <util/endian.h>
|
||||
@ -53,7 +54,18 @@ class Net::Ipv4_packet
|
||||
ADDR_LEN = 4, /* Ip address length in bytes */
|
||||
};
|
||||
|
||||
typedef Network_address<ADDR_LEN> Ipv4_address;
|
||||
struct Ipv4_address : Network_address<ADDR_LEN>
|
||||
{
|
||||
using Network_address<ADDR_LEN>::Network_address;
|
||||
|
||||
void print(Genode::Output &output) const
|
||||
{
|
||||
for (unsigned i = 0; i < ADDR_LEN; i++) {
|
||||
Genode::print(output, (unsigned) addr[i]);
|
||||
if (i < ADDR_LEN-1) output.out_char('.');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const Ipv4_address CURRENT; /* current network */
|
||||
static const Ipv4_address BROADCAST; /* broadcast address */
|
||||
|
@ -25,49 +25,47 @@ namespace Net { template <unsigned> class Network_address; }
|
||||
* Generic form of a network address.
|
||||
*/
|
||||
template <unsigned LEN>
|
||||
class Net::Network_address
|
||||
struct Net::Network_address
|
||||
{
|
||||
public:
|
||||
|
||||
Genode::uint8_t addr[LEN];
|
||||
Genode::uint8_t addr[LEN];
|
||||
|
||||
|
||||
/******************
|
||||
** Constructors **
|
||||
******************/
|
||||
/******************
|
||||
** Constructors **
|
||||
******************/
|
||||
|
||||
Network_address(Genode::uint8_t value = 0) {
|
||||
Genode::memset(&addr, value, LEN); }
|
||||
Network_address(Genode::uint8_t value = 0) {
|
||||
Genode::memset(&addr, value, LEN); }
|
||||
|
||||
Network_address(void *src) {
|
||||
Genode::memcpy(&addr, src, LEN); }
|
||||
Network_address(void *src) {
|
||||
Genode::memcpy(&addr, src, LEN); }
|
||||
|
||||
|
||||
/*********************
|
||||
** Helper methods **
|
||||
*********************/
|
||||
/*********************
|
||||
** Helper methods **
|
||||
*********************/
|
||||
|
||||
void copy(void *dst) { Genode::memcpy(dst, addr, LEN); }
|
||||
void copy(void *dst) { Genode::memcpy(dst, addr, LEN); }
|
||||
|
||||
|
||||
/***************
|
||||
** Operators **
|
||||
***************/
|
||||
/***************
|
||||
** Operators **
|
||||
***************/
|
||||
|
||||
bool operator==(const Network_address &other) const {
|
||||
bool operator==(const Network_address &other) const {
|
||||
|
||||
/*
|
||||
* We compare from lowest address segment to highest
|
||||
* one, because in a local context, the higher segments
|
||||
* of two addresses normally don't distinguish.
|
||||
* (e.g. in an IPv4 local subnet)
|
||||
*/
|
||||
for (int i = LEN-1; i >= 0; --i) {
|
||||
if (addr[i] != other.addr[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
/*
|
||||
* We compare from lowest address segment to highest
|
||||
* one, because in a local context, the higher segments
|
||||
* of two addresses normally don't distinguish.
|
||||
* (e.g. in an IPv4 local subnet)
|
||||
*/
|
||||
for (int i = LEN-1; i >= 0; --i) {
|
||||
if (addr[i] != other.addr[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _NET__NETADDRESS_H_ */
|
||||
|
@ -33,71 +33,72 @@ namespace Net {
|
||||
* a list and/or avl-tree, whereby the network-address (MAC or IP)
|
||||
* acts as a key.
|
||||
*/
|
||||
template <unsigned LEN>
|
||||
class Address_node : public Genode::Avl_node<Address_node<LEN> >,
|
||||
public Genode::List<Address_node<LEN> >::Element
|
||||
{
|
||||
public:
|
||||
template <typename ADDRESS> class Address_node;
|
||||
|
||||
typedef Network_address<LEN> Address;
|
||||
|
||||
private:
|
||||
|
||||
Address _addr; /* MAC or IP address */
|
||||
Session_component *_component; /* client's component */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param addr Network address acting as sorting criteria.
|
||||
* \param component pointer to client's session component.
|
||||
*/
|
||||
Address_node(Address addr, Session_component *component)
|
||||
: _addr(addr), _component(component) { }
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Address addr() { return _addr; }
|
||||
Session_component *component() { return _component; }
|
||||
|
||||
|
||||
/************************
|
||||
** Avl node interface **
|
||||
************************/
|
||||
|
||||
bool higher(Address_node *c)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
return (memcmp(&c->_addr.addr, &_addr.addr,
|
||||
sizeof(_addr.addr)) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find by address
|
||||
*/
|
||||
Address_node *find_by_address(Address addr)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (addr == _addr)
|
||||
return this;
|
||||
|
||||
bool side = memcmp(&addr.addr, _addr.addr,
|
||||
sizeof(_addr.addr)) > 0;
|
||||
Address_node *c = Avl_node<Address_node>::child(side);
|
||||
return c ? c->find_by_address(addr) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef Address_node<Ipv4_packet::ADDR_LEN> Ipv4_address_node;
|
||||
typedef Address_node<Ethernet_frame::ADDR_LEN> Mac_address_node;
|
||||
using Ipv4_address_node = Address_node<Ipv4_packet::Ipv4_address>;
|
||||
using Mac_address_node = Address_node<Ethernet_frame::Mac_address>;
|
||||
}
|
||||
|
||||
|
||||
template <typename ADDRESS>
|
||||
class Net::Address_node : public Genode::Avl_node<Address_node<ADDRESS> >,
|
||||
public Genode::List<Address_node<ADDRESS> >::Element
|
||||
{
|
||||
private:
|
||||
|
||||
ADDRESS _addr; /* MAC or IP address */
|
||||
Session_component &_component; /* client's component */
|
||||
|
||||
public:
|
||||
|
||||
using Address = ADDRESS;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param component reference to client's session component.
|
||||
*/
|
||||
Address_node(Session_component &component,
|
||||
Address addr = Address())
|
||||
: _addr(addr), _component(component) { }
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
void addr(Address addr) { _addr = addr; }
|
||||
Address addr() { return _addr; }
|
||||
Session_component &component() { return _component; }
|
||||
|
||||
|
||||
/************************
|
||||
** Avl node interface **
|
||||
************************/
|
||||
|
||||
bool higher(Address_node *c)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
return (memcmp(&c->_addr.addr, &_addr.addr,
|
||||
sizeof(_addr.addr)) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find by address
|
||||
*/
|
||||
Address_node *find_by_address(Address addr)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (addr == _addr)
|
||||
return this;
|
||||
|
||||
bool side = memcmp(&addr.addr, _addr.addr,
|
||||
sizeof(_addr.addr)) > 0;
|
||||
Address_node *c = Avl_node<Address_node>::child(side);
|
||||
return c ? c->find_by_address(addr) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _ADDRESS_NODE_H_ */
|
||||
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* \brief Thread-safe Avl_tree implementation
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2010-08-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _AVL_SAFE_H_
|
||||
#define _AVL_SAFE_H_
|
||||
|
||||
/* Genode */
|
||||
#include <base/lock.h>
|
||||
#include <base/lock_guard.h>
|
||||
#include <util/avl_tree.h>
|
||||
|
||||
/**
|
||||
* Lock-guarded avl-tree implementation.
|
||||
*/
|
||||
template <typename NT>
|
||||
class Avl_tree_safe : public Genode::Avl_tree<NT>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Lock _lock;
|
||||
|
||||
public:
|
||||
|
||||
void insert(Genode::Avl_node<NT> *node)
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
Genode::Avl_tree<NT>::insert(node);
|
||||
}
|
||||
|
||||
void remove(Genode::Avl_node<NT> *node)
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
Genode::Avl_tree<NT>::remove(node);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _AVL_SAFE_H_ */
|
@ -20,9 +20,6 @@
|
||||
|
||||
using namespace Net;
|
||||
|
||||
static const int verbose = 1;
|
||||
|
||||
|
||||
bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
|
||||
{
|
||||
Arp_packet *arp =
|
||||
@ -41,7 +38,7 @@ bool Session_component::handle_arp(Ethernet_frame *eth, Genode::size_t size)
|
||||
if (arp->src_ip() == arp->dst_ip())
|
||||
return false;
|
||||
|
||||
Ipv4_address_node *node = vlan().ip_tree()->first();
|
||||
Ipv4_address_node *node = vlan().ip_tree.first();
|
||||
if (node)
|
||||
node = node->find_by_address(arp->dst_ip());
|
||||
if (!node) {
|
||||
@ -77,11 +74,11 @@ bool Session_component::handle_ip(Ethernet_frame *eth, Genode::size_t size)
|
||||
void Session_component::finalize_packet(Ethernet_frame *eth,
|
||||
Genode::size_t size)
|
||||
{
|
||||
Mac_address_node *node = vlan().mac_tree()->first();
|
||||
Mac_address_node *node = vlan().mac_tree.first();
|
||||
if (node)
|
||||
node = node->find_by_address(eth->dst());
|
||||
if (node)
|
||||
node->component()->send(eth, size);
|
||||
node->component().send(eth, size);
|
||||
else {
|
||||
/* set our MAC as sender */
|
||||
eth->src(_nic.mac());
|
||||
@ -90,12 +87,12 @@ void Session_component::finalize_packet(Ethernet_frame *eth,
|
||||
}
|
||||
|
||||
|
||||
void Session_component::_free_ipv4_node()
|
||||
void Session_component::_unset_ipv4_node()
|
||||
{
|
||||
if (_ipv4_node) {
|
||||
vlan().ip_tree()->remove(_ipv4_node);
|
||||
destroy(this->guarded_allocator(), _ipv4_node);
|
||||
}
|
||||
Ipv4_address_node * first = vlan().ip_tree.first();
|
||||
if (!first) return;
|
||||
if (first->find_by_address(_ipv4_node.addr()))
|
||||
vlan().ip_tree.remove(&_ipv4_node);
|
||||
}
|
||||
|
||||
|
||||
@ -104,48 +101,43 @@ bool Session_component::link_state() { return _nic.link_state(); }
|
||||
|
||||
void Session_component::set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr)
|
||||
{
|
||||
_free_ipv4_node();
|
||||
_ipv4_node = new (this->guarded_allocator())
|
||||
Ipv4_address_node(ip_addr, this);
|
||||
vlan().ip_tree()->insert(_ipv4_node);
|
||||
_unset_ipv4_node();
|
||||
_ipv4_node.addr(ip_addr);
|
||||
vlan().ip_tree.insert(&_ipv4_node);
|
||||
}
|
||||
|
||||
|
||||
Session_component::Session_component(Genode::Allocator *allocator,
|
||||
Session_component::Session_component(Genode::Ram_session &ram,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::size_t amount,
|
||||
Genode::size_t tx_buf_size,
|
||||
Genode::size_t rx_buf_size,
|
||||
Ethernet_frame::Mac_address vmac,
|
||||
Server::Entrypoint &ep,
|
||||
Net::Nic &nic,
|
||||
char *ip_addr)
|
||||
: Guarded_range_allocator(allocator, amount),
|
||||
Tx_rx_communication_buffers(tx_buf_size, rx_buf_size),
|
||||
Session_rpc_object(Tx_rx_communication_buffers::tx_ds(),
|
||||
Tx_rx_communication_buffers::rx_ds(),
|
||||
this->range_allocator(), ep.rpc_ep()),
|
||||
: Stream_allocator(ram, rm, amount),
|
||||
Stream_dataspaces(ram, tx_buf_size, rx_buf_size),
|
||||
Session_rpc_object(Stream_dataspaces::tx_ds,
|
||||
Stream_dataspaces::rx_ds,
|
||||
Stream_allocator::range_allocator(), ep.rpc_ep()),
|
||||
Packet_handler(ep, nic.vlan()),
|
||||
_mac_node(vmac, this),
|
||||
_ipv4_node(0),
|
||||
_mac_node(*this, vmac),
|
||||
_ipv4_node(*this),
|
||||
_nic(nic)
|
||||
{
|
||||
vlan().mac_tree()->insert(&_mac_node);
|
||||
vlan().mac_list()->insert(&_mac_node);
|
||||
vlan().mac_tree.insert(&_mac_node);
|
||||
vlan().mac_list.insert(&_mac_node);
|
||||
|
||||
/* static ip parsing */
|
||||
if (ip_addr != 0 && Genode::strlen(ip_addr)) {
|
||||
Ipv4_packet::Ipv4_address ip = Ipv4_packet::ip_from_string(ip_addr);
|
||||
|
||||
if (ip == Ipv4_packet::Ipv4_address()) {
|
||||
PWRN("Empty or error ip address. Skipped.");
|
||||
Genode::warning("Empty or error ip address. Skipped.");
|
||||
} else {
|
||||
set_ipv4_address(ip);
|
||||
|
||||
if (verbose)
|
||||
PLOG("vmac=%02x:%02x:%02x:%02x:%02x:%02x ip=%d.%d.%d.%d",
|
||||
vmac.addr[0], vmac.addr[1], vmac.addr[2],
|
||||
vmac.addr[3], vmac.addr[4], vmac.addr[5],
|
||||
ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3]);
|
||||
Genode::log("vmac = ", vmac, " ip = ", ip);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +149,7 @@ Session_component::Session_component(Genode::Allocator *allocator,
|
||||
|
||||
|
||||
Session_component::~Session_component() {
|
||||
vlan().mac_tree()->remove(&_mac_node);
|
||||
vlan().mac_list()->remove(&_mac_node);
|
||||
_free_ipv4_node();
|
||||
vlan().mac_tree.remove(&_mac_node);
|
||||
vlan().mac_list.remove(&_mac_node);
|
||||
_unset_ipv4_node();
|
||||
}
|
||||
|
@ -15,250 +15,225 @@
|
||||
#define _COMPONENT_H_
|
||||
|
||||
/* Genode */
|
||||
#include <base/lock.h>
|
||||
#include <root/component.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <base/log.h>
|
||||
#include <base/heap.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/rpc_object.h>
|
||||
#include <nic_session/connection.h>
|
||||
#include <net/ipv4.h>
|
||||
#include <base/allocator_guard.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <root/component.h>
|
||||
#include <util/arg_string.h>
|
||||
|
||||
#include <address_node.h>
|
||||
#include <mac.h>
|
||||
#include <nic.h>
|
||||
#include <packet_handler.h>
|
||||
#include <ram_session_guard.h>
|
||||
|
||||
namespace Net {
|
||||
|
||||
/**
|
||||
* Helper class.
|
||||
*
|
||||
*/
|
||||
class Guarded_range_allocator
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Allocator_guard _guarded_alloc;
|
||||
::Nic::Packet_allocator _range_alloc;
|
||||
|
||||
public:
|
||||
|
||||
Guarded_range_allocator(Genode::Allocator *backing_store,
|
||||
Genode::size_t amount)
|
||||
: _guarded_alloc(backing_store, amount),
|
||||
_range_alloc(&_guarded_alloc) {}
|
||||
|
||||
Genode::Allocator_guard *guarded_allocator() {
|
||||
return &_guarded_alloc; }
|
||||
|
||||
Genode::Range_allocator *range_allocator() {
|
||||
return static_cast<Genode::Range_allocator *>(&_range_alloc); }
|
||||
};
|
||||
class Stream_allocator;
|
||||
class Stream_dataspace;
|
||||
class Stream_dataspaces;
|
||||
class Session_component;
|
||||
class Root;
|
||||
}
|
||||
|
||||
|
||||
class Communication_buffer : Genode::Ram_dataspace_capability
|
||||
{
|
||||
public:
|
||||
/********************
|
||||
** Helper classes **
|
||||
********************/
|
||||
|
||||
Communication_buffer(Genode::size_t size)
|
||||
: Genode::Ram_dataspace_capability(Genode::env()->ram_session()->alloc(size))
|
||||
{ }
|
||||
class Net::Stream_allocator
|
||||
{
|
||||
protected:
|
||||
|
||||
~Communication_buffer() { Genode::env()->ram_session()->free(*this); }
|
||||
Genode::Ram_session_guard _ram;
|
||||
Genode::Heap _heap;
|
||||
::Nic::Packet_allocator _range_alloc;
|
||||
|
||||
Genode::Dataspace_capability dataspace() { return *this; }
|
||||
};
|
||||
public:
|
||||
|
||||
Stream_allocator(Genode::Ram_session &ram,
|
||||
Genode::Region_map &rm,
|
||||
Genode::size_t amount)
|
||||
: _ram(ram, amount),
|
||||
_heap(ram, rm),
|
||||
_range_alloc(&_heap) {}
|
||||
|
||||
Genode::Range_allocator *range_allocator() {
|
||||
return static_cast<Genode::Range_allocator *>(&_range_alloc); }
|
||||
};
|
||||
|
||||
|
||||
class Tx_rx_communication_buffers
|
||||
{
|
||||
private:
|
||||
struct Net::Stream_dataspace : Genode::Ram_dataspace_capability
|
||||
{
|
||||
Genode::Ram_session &ram;
|
||||
|
||||
Communication_buffer _tx_buf, _rx_buf;
|
||||
Stream_dataspace(Genode::Ram_session &ram, Genode::size_t size)
|
||||
: Genode::Ram_dataspace_capability(ram.alloc(size)), ram(ram) { }
|
||||
|
||||
public:
|
||||
|
||||
Tx_rx_communication_buffers(Genode::size_t tx_size,
|
||||
Genode::size_t rx_size)
|
||||
: _tx_buf(tx_size), _rx_buf(rx_size) { }
|
||||
|
||||
Genode::Dataspace_capability tx_ds() { return _tx_buf.dataspace(); }
|
||||
Genode::Dataspace_capability rx_ds() { return _rx_buf.dataspace(); }
|
||||
};
|
||||
~Stream_dataspace() { ram.free(*this); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Nic-session component class
|
||||
*
|
||||
* We must inherit here from Guarded_range_allocator, although aggregation
|
||||
* would be more convinient, because the range-allocator needs to be initialized
|
||||
* before base-class Session_rpc_object.
|
||||
*/
|
||||
class Session_component : public Guarded_range_allocator,
|
||||
private Tx_rx_communication_buffers,
|
||||
public ::Nic::Session_rpc_object,
|
||||
public Packet_handler
|
||||
{
|
||||
private:
|
||||
struct Net::Stream_dataspaces
|
||||
{
|
||||
Stream_dataspace tx_ds, rx_ds;
|
||||
|
||||
Mac_address_node _mac_node;
|
||||
Ipv4_address_node *_ipv4_node;
|
||||
Net::Nic &_nic;
|
||||
Genode::Signal_context_capability _link_state_sigh;
|
||||
|
||||
void _free_ipv4_node();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param allocator backing store for guarded allocator
|
||||
* \param amount amount of memory managed by guarded allocator
|
||||
* \param tx_buf_size buffer size for tx channel
|
||||
* \param rx_buf_size buffer size for rx channel
|
||||
* \param vmac virtual mac address
|
||||
* \param ep entry point used for packet stream
|
||||
*/
|
||||
Session_component(Genode::Allocator *allocator,
|
||||
Genode::size_t amount,
|
||||
Genode::size_t tx_buf_size,
|
||||
Genode::size_t rx_buf_size,
|
||||
Ethernet_frame::Mac_address vmac,
|
||||
Server::Entrypoint &ep,
|
||||
Net::Nic &nic,
|
||||
char *ip_addr = 0);
|
||||
|
||||
~Session_component();
|
||||
|
||||
::Nic::Mac_address mac_address()
|
||||
{
|
||||
::Nic::Mac_address m;
|
||||
Mac_address_node::Address mac = _mac_node.addr();
|
||||
Genode::memcpy(&m, mac.addr, sizeof(m.addr));
|
||||
return m;
|
||||
}
|
||||
|
||||
void link_state_changed()
|
||||
{
|
||||
if (_link_state_sigh.valid())
|
||||
Genode::Signal_transmitter(_link_state_sigh).submit();
|
||||
}
|
||||
|
||||
void set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr);
|
||||
|
||||
/****************************************
|
||||
** Nic::Driver notification interface **
|
||||
****************************************/
|
||||
|
||||
bool link_state();
|
||||
|
||||
void link_state_sigh(Genode::Signal_context_capability sigh) {
|
||||
_link_state_sigh = sigh; }
|
||||
|
||||
/******************************
|
||||
** Packet_handler interface **
|
||||
******************************/
|
||||
|
||||
Packet_stream_sink< ::Nic::Session::Policy> * sink() {
|
||||
return _tx.sink(); }
|
||||
|
||||
Packet_stream_source< ::Nic::Session::Policy> * source() {
|
||||
return _rx.source(); }
|
||||
|
||||
bool handle_arp(Ethernet_frame *eth, Genode::size_t size);
|
||||
bool handle_ip(Ethernet_frame *eth, Genode::size_t size);
|
||||
void finalize_packet(Ethernet_frame *eth, Genode::size_t size);
|
||||
};
|
||||
Stream_dataspaces(Genode::Ram_session &ram, Genode::size_t tx_size,
|
||||
Genode::size_t rx_size)
|
||||
: tx_ds(ram, tx_size), rx_ds(ram, rx_size) { }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Root component, handling new session requests.
|
||||
*/
|
||||
class Root : public Genode::Root_component<Session_component>
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Nic-session component class
|
||||
*
|
||||
* We must inherit here from Stream_allocator, although aggregation
|
||||
* would be more convinient, because the allocator needs to be initialized
|
||||
* before base-class Session_rpc_object.
|
||||
*/
|
||||
class Net::Session_component : public Net::Stream_allocator,
|
||||
private Net::Stream_dataspaces,
|
||||
public ::Nic::Session_rpc_object,
|
||||
public Net::Packet_handler
|
||||
{
|
||||
private:
|
||||
|
||||
enum { verbose = 1 };
|
||||
Mac_address_node _mac_node;
|
||||
Ipv4_address_node _ipv4_node;
|
||||
Net::Nic &_nic;
|
||||
Genode::Signal_context_capability _link_state_sigh;
|
||||
|
||||
Mac_allocator _mac_alloc;
|
||||
Server::Entrypoint &_ep;
|
||||
Net::Nic &_nic;
|
||||
void _unset_ipv4_node();
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param ram ram session
|
||||
* \param rm region map of this component
|
||||
* \param ep entry point this session component is handled by
|
||||
* \param amount amount of memory managed by guarded allocator
|
||||
* \param tx_buf_size buffer size for tx channel
|
||||
* \param rx_buf_size buffer size for rx channel
|
||||
* \param vmac virtual mac address
|
||||
*/
|
||||
Session_component(Genode::Ram_session &ram,
|
||||
Genode::Region_map &rm,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::size_t amount,
|
||||
Genode::size_t tx_buf_size,
|
||||
Genode::size_t rx_buf_size,
|
||||
Ethernet_frame::Mac_address vmac,
|
||||
Net::Nic &nic,
|
||||
char *ip_addr = 0);
|
||||
|
||||
~Session_component();
|
||||
|
||||
::Nic::Mac_address mac_address()
|
||||
{
|
||||
::Nic::Mac_address m;
|
||||
Mac_address_node::Address mac = _mac_node.addr();
|
||||
Genode::memcpy(&m, mac.addr, sizeof(m.addr));
|
||||
return m;
|
||||
}
|
||||
|
||||
void link_state_changed()
|
||||
{
|
||||
if (_link_state_sigh.valid())
|
||||
Genode::Signal_transmitter(_link_state_sigh).submit();
|
||||
}
|
||||
|
||||
void set_ipv4_address(Ipv4_packet::Ipv4_address ip_addr);
|
||||
|
||||
|
||||
/****************************************
|
||||
** Nic::Driver notification interface **
|
||||
****************************************/
|
||||
|
||||
bool link_state();
|
||||
|
||||
void link_state_sigh(Genode::Signal_context_capability sigh) {
|
||||
_link_state_sigh = sigh; }
|
||||
|
||||
|
||||
/******************************
|
||||
** Packet_handler interface **
|
||||
******************************/
|
||||
|
||||
Packet_stream_sink< ::Nic::Session::Policy> * sink() {
|
||||
return _tx.sink(); }
|
||||
|
||||
Packet_stream_source< ::Nic::Session::Policy> * source() {
|
||||
return _rx.source(); }
|
||||
|
||||
bool handle_arp(Ethernet_frame *eth, Genode::size_t size);
|
||||
bool handle_ip(Ethernet_frame *eth, Genode::size_t size);
|
||||
void finalize_packet(Ethernet_frame *eth, Genode::size_t size);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Root component, handling new session requests.
|
||||
*/
|
||||
class Net::Root : public Genode::Root_component<Net::Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Mac_allocator _mac_alloc;
|
||||
Genode::Env &_env;
|
||||
Net::Nic &_nic;
|
||||
Genode::Xml_node _config;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
enum { MAX_IP_ADDR_LENGTH = 16, };
|
||||
char ip_addr[MAX_IP_ADDR_LENGTH];
|
||||
memset(ip_addr, 0, MAX_IP_ADDR_LENGTH);
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
memset(ip_addr, 0, MAX_IP_ADDR_LENGTH);
|
||||
|
||||
try {
|
||||
Session_label label(args);
|
||||
Session_policy policy(label);
|
||||
policy.attribute("ip_addr").value(ip_addr, sizeof(ip_addr));
|
||||
|
||||
if (verbose) PLOG("policy: %s ip_addr = %s", label.string(), ip_addr);
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
if (verbose) PLOG("Missing \"ip_addr\" attribute in policy definition");
|
||||
} catch (Session_policy::No_policy_defined) {
|
||||
if (verbose) PLOG("Invalid session request, no matching policy");;
|
||||
}
|
||||
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size =
|
||||
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
size_t rx_buf_size =
|
||||
Arg_string::find_arg(args, "rx_buf_size").ulong_value(0);
|
||||
|
||||
/* delete ram quota by the memory needed for the session */
|
||||
size_t session_size = max((size_t)4096, sizeof(Session_component));
|
||||
if (ram_quota < session_size)
|
||||
throw Root::Quota_exceeded();
|
||||
|
||||
/*
|
||||
* Check if donated ram quota suffices for both
|
||||
* communication buffers. Also check both sizes separately
|
||||
* to handle a possible overflow of the sum of both sizes.
|
||||
*/
|
||||
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) {
|
||||
PERR("insufficient 'ram_quota', got %zd, need %zd",
|
||||
ram_quota, tx_buf_size + rx_buf_size + session_size);
|
||||
throw Root::Quota_exceeded();
|
||||
}
|
||||
|
||||
try {
|
||||
return new (md_alloc()) Session_component(env()->heap(),
|
||||
ram_quota - session_size,
|
||||
tx_buf_size,
|
||||
rx_buf_size,
|
||||
_mac_alloc.alloc(),
|
||||
_ep,
|
||||
_nic,
|
||||
ip_addr);
|
||||
} catch(Mac_allocator::Alloc_failed) {
|
||||
PWRN("Mac address allocation failed!");
|
||||
return (Session_component*) 0;
|
||||
}
|
||||
try {
|
||||
Session_label label(args);
|
||||
Session_policy policy(label, _config);
|
||||
policy.attribute("ip_addr").value(ip_addr, sizeof(ip_addr));
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
Genode::log("Missing \"ip_addr\" attribute in policy definition");
|
||||
} catch (Session_policy::No_policy_defined) {
|
||||
Genode::log("Invalid session request, no matching policy");;
|
||||
}
|
||||
|
||||
public:
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size =
|
||||
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
size_t rx_buf_size =
|
||||
Arg_string::find_arg(args, "rx_buf_size").ulong_value(0);
|
||||
|
||||
Root(Server::Entrypoint &ep,
|
||||
Net::Nic &nic,
|
||||
Genode::Allocator *md_alloc)
|
||||
: Genode::Root_component<Session_component>(&ep.rpc_ep(), md_alloc),
|
||||
_ep(ep), _nic(nic) { }
|
||||
};
|
||||
try {
|
||||
return new (md_alloc())
|
||||
Session_component(_env.ram(), _env.rm(), _env.ep(),
|
||||
ram_quota, tx_buf_size, rx_buf_size,
|
||||
_mac_alloc.alloc(), _nic, ip_addr);
|
||||
} catch(Mac_allocator::Alloc_failed) {
|
||||
Genode::warning("Mac address allocation failed!");
|
||||
throw Root::Unavailable();
|
||||
} catch(Ram_session::Quota_exceeded) {
|
||||
Genode::warning("insufficient 'ram_quota'");
|
||||
throw Root::Quota_exceeded();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace Net */
|
||||
public:
|
||||
|
||||
Root(Genode::Env &env, Net::Nic &nic, Genode::Allocator &md_alloc,
|
||||
Genode::Xml_node config)
|
||||
: Genode::Root_component<Session_component>(env.ep(), md_alloc),
|
||||
_env(env), _nic(nic), _config(config) { }
|
||||
};
|
||||
|
||||
#endif /* _COMPONENT_H_ */
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* \brief Thread-safe list implementation
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2010-08-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LIST_SAFE_H_
|
||||
#define _LIST_SAFE_H_
|
||||
|
||||
#include <base/lock_guard.h>
|
||||
#include <util/list.h>
|
||||
|
||||
/**
|
||||
* Lock-guarded avl-tree implementation.
|
||||
*/
|
||||
template <typename LE>
|
||||
class List_safe : public Genode::List<LE>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Lock _lock;
|
||||
|
||||
public:
|
||||
|
||||
void insert(LE *item)
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
Genode::List<LE>::insert(item);
|
||||
}
|
||||
|
||||
void remove(LE *item)
|
||||
{
|
||||
Genode::Lock::Guard lock_guard(_lock);
|
||||
Genode::List<LE>::remove(item);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _LIST_SAFE_H_ */
|
@ -12,13 +12,14 @@
|
||||
*/
|
||||
|
||||
/* Genode */
|
||||
#include <nic/xml_node.h> /* ugly template dependency forces us
|
||||
to include this before xml_node.h */
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <base/log.h>
|
||||
#include <nic_session/connection.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic/xml_node.h>
|
||||
#include <os/config.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <component.h>
|
||||
@ -26,54 +27,47 @@
|
||||
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
Net::Vlan vlan;
|
||||
Net::Nic nic = { ep, vlan };
|
||||
Net::Root root = { ep, nic, Genode::env()->heap() };
|
||||
Genode::Env &env;
|
||||
Genode::Entrypoint &ep { env.ep() };
|
||||
Genode::Heap heap { env.ram(), env.rm() };
|
||||
Genode::Attached_rom_dataspace config { env, "config" };
|
||||
Net::Vlan vlan;
|
||||
Net::Nic nic { ep, heap, vlan };
|
||||
Net::Root root { env, nic, heap, config.xml() };
|
||||
|
||||
void handle_config()
|
||||
{
|
||||
/* read MAC address prefix from config file */
|
||||
try {
|
||||
Nic::Mac_address mac;
|
||||
Genode::config()->xml_node().attribute("mac").value(&mac);
|
||||
config.xml().attribute("mac").value(&mac);
|
||||
Genode::memcpy(&Net::Mac_allocator::mac_addr_base, &mac,
|
||||
sizeof(Net::Mac_allocator::mac_addr_base));
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void read_mac()
|
||||
{
|
||||
Net::Ethernet_frame::Mac_address mac(nic.mac());
|
||||
Genode::printf("--- NIC bridge started "
|
||||
"(mac=%02x:%02x:%02x:%02x:%02x:%02x) ---\n",
|
||||
mac.addr[0], mac.addr[1], mac.addr[2],
|
||||
mac.addr[3], mac.addr[4], mac.addr[5]);
|
||||
}
|
||||
|
||||
Main(Server::Entrypoint &ep) : ep(ep)
|
||||
Main(Genode::Env &e) : env(e)
|
||||
{
|
||||
try {
|
||||
/* read configuration file */
|
||||
handle_config();
|
||||
read_mac();
|
||||
Genode::env()->parent()->announce(ep.manage(root));
|
||||
|
||||
/* show MAC address to use */
|
||||
Net::Ethernet_frame::Mac_address mac(nic.mac());
|
||||
Genode::log("--- NIC bridge started (mac=", mac, ") ---");
|
||||
|
||||
/* announce at parent */
|
||||
env.parent().announce(ep.manage(root));
|
||||
} catch (Genode::Parent::Service_denied) {
|
||||
PERR("Could not connect to uplink NIC");
|
||||
Genode::error("Could not connect to uplink NIC");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
Genode::size_t Component::stack_size() {
|
||||
return 2048*sizeof(Genode::addr_t); }
|
||||
|
||||
namespace Server {
|
||||
|
||||
char const *name() { return "nic_bridge_ep"; }
|
||||
|
||||
size_t stack_size() { return 2048*sizeof(Genode::addr_t); }
|
||||
|
||||
void construct(Entrypoint &ep) { static Main nic_bridge(ep); }
|
||||
}
|
||||
void Component::construct(Genode::Env &env) {
|
||||
static Main nic_bridge(env); }
|
||||
|
@ -32,7 +32,7 @@ bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) {
|
||||
return true;
|
||||
|
||||
/* look whether the IP address is one of our client's */
|
||||
Ipv4_address_node *node = vlan().ip_tree()->first();
|
||||
Ipv4_address_node *node = vlan().ip_tree.first();
|
||||
if (node)
|
||||
node = node->find_by_address(arp->dst_ip());
|
||||
if (node) {
|
||||
@ -55,9 +55,9 @@ bool Net::Nic::handle_arp(Ethernet_frame *eth, Genode::size_t size) {
|
||||
send(eth, size);
|
||||
} else {
|
||||
/* overwrite destination MAC */
|
||||
arp->dst_mac(node->component()->mac_address().addr);
|
||||
eth->dst(node->component()->mac_address().addr);
|
||||
node->component()->send(eth, size);
|
||||
arp->dst_mac(node->component().mac_address().addr);
|
||||
eth->dst(node->component().mac_address().addr);
|
||||
node->component().send(eth, size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -91,11 +91,11 @@ bool Net::Nic::handle_ip(Ethernet_frame *eth, Genode::size_t size) {
|
||||
Genode::uint8_t *msg_type = (Genode::uint8_t*) ext->value();
|
||||
if (*msg_type == Dhcp_packet::DHCP_ACK) {
|
||||
Mac_address_node *node =
|
||||
vlan().mac_tree()->first();
|
||||
vlan().mac_tree.first();
|
||||
if (node)
|
||||
node = node->find_by_address(dhcp->client_mac());
|
||||
if (node)
|
||||
node->component()->set_ipv4_address(dhcp->yiaddr());
|
||||
node->component().set_ipv4_address(dhcp->yiaddr());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,15 +104,15 @@ bool Net::Nic::handle_ip(Ethernet_frame *eth, Genode::size_t size) {
|
||||
|
||||
/* is it an unicast message to one of our clients ? */
|
||||
if (eth->dst() == mac()) {
|
||||
Ipv4_address_node *node = vlan().ip_tree()->first();
|
||||
Ipv4_address_node *node = vlan().ip_tree.first();
|
||||
if (node) {
|
||||
node = node->find_by_address(ip->dst());
|
||||
if (node) {
|
||||
/* overwrite destination MAC */
|
||||
eth->dst(node->component()->mac_address().addr);
|
||||
eth->dst(node->component().mac_address().addr);
|
||||
|
||||
/* deliver the packet to the client */
|
||||
node->component()->send(eth, size);
|
||||
node->component().send(eth, size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -121,9 +121,9 @@ bool Net::Nic::handle_ip(Ethernet_frame *eth, Genode::size_t size) {
|
||||
}
|
||||
|
||||
|
||||
Net::Nic::Nic(Server::Entrypoint &ep, Net::Vlan &vlan)
|
||||
Net::Nic::Nic(Genode::Entrypoint &ep, Genode::Heap &heap, Net::Vlan &vlan)
|
||||
: Packet_handler(ep, vlan),
|
||||
_tx_block_alloc(Genode::env()->heap()),
|
||||
_tx_block_alloc(&heap),
|
||||
_nic(&_tx_block_alloc, BUF_SIZE, BUF_SIZE),
|
||||
_mac(_nic.mac_address().addr)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ class Net::Nic : public Net::Packet_handler
|
||||
|
||||
public:
|
||||
|
||||
Nic(Server::Entrypoint&, Vlan&);
|
||||
Nic(Genode::Entrypoint&, Genode::Heap&, Vlan&);
|
||||
|
||||
::Nic::Connection *nic() { return &_nic; }
|
||||
Ethernet_frame::Mac_address mac() { return _mac; }
|
||||
|
@ -11,7 +11,7 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/lock.h>
|
||||
#include <base/log.h>
|
||||
#include <net/arp.h>
|
||||
#include <net/dhcp.h>
|
||||
#include <net/ethernet.h>
|
||||
@ -23,9 +23,7 @@
|
||||
|
||||
using namespace Net;
|
||||
|
||||
static const bool verbose = true;
|
||||
|
||||
void Packet_handler::_ready_to_submit(unsigned)
|
||||
void Packet_handler::_ready_to_submit()
|
||||
{
|
||||
/* as long as packets are available, and we can ack them */
|
||||
while (sink()->packet_avail()) {
|
||||
@ -34,8 +32,7 @@ void Packet_handler::_ready_to_submit(unsigned)
|
||||
handle_ethernet(sink()->packet_content(_packet), _packet.size());
|
||||
|
||||
if (!sink()->ready_to_ack()) {
|
||||
if (verbose)
|
||||
PWRN("ack state FULL");
|
||||
Genode::warning("ack state FULL");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -44,7 +41,7 @@ void Packet_handler::_ready_to_submit(unsigned)
|
||||
}
|
||||
|
||||
|
||||
void Packet_handler::_ready_to_ack(unsigned)
|
||||
void Packet_handler::_ready_to_ack()
|
||||
{
|
||||
/* check for acknowledgements */
|
||||
while (source()->ack_avail())
|
||||
@ -52,11 +49,11 @@ void Packet_handler::_ready_to_ack(unsigned)
|
||||
}
|
||||
|
||||
|
||||
void Packet_handler::_link_state(unsigned)
|
||||
void Packet_handler::_link_state()
|
||||
{
|
||||
Mac_address_node *node = _vlan.mac_list()->first();
|
||||
Mac_address_node *node = _vlan.mac_list.first();
|
||||
while (node) {
|
||||
node->component()->link_state_changed();
|
||||
node->component().link_state_changed();
|
||||
node = node->next();
|
||||
}
|
||||
}
|
||||
@ -68,10 +65,10 @@ void Packet_handler::broadcast_to_clients(Ethernet_frame *eth, Genode::size_t si
|
||||
if (eth->dst() == Ethernet_frame::BROADCAST) {
|
||||
/* iterate through the list of clients */
|
||||
Mac_address_node *node =
|
||||
_vlan.mac_list()->first();
|
||||
_vlan.mac_list.first();
|
||||
while (node) {
|
||||
/* deliver packet */
|
||||
node->component()->send(eth, size);
|
||||
node->component().send(eth, size);
|
||||
node = node->next();
|
||||
}
|
||||
}
|
||||
@ -97,15 +94,15 @@ void Packet_handler::handle_ethernet(void* src, Genode::size_t size)
|
||||
broadcast_to_clients(eth, size);
|
||||
finalize_packet(eth, size);
|
||||
} catch(Arp_packet::No_arp_packet) {
|
||||
PWRN("Invalid ARP packet!");
|
||||
Genode::warning("Invalid ARP packet!");
|
||||
} catch(Ethernet_frame::No_ethernet_frame) {
|
||||
PWRN("Invalid ethernet frame");
|
||||
Genode::warning("Invalid ethernet frame");
|
||||
} catch(Dhcp_packet::No_dhcp_packet) {
|
||||
PWRN("Invalid IPv4 packet!");
|
||||
Genode::warning("Invalid IPv4 packet!");
|
||||
} catch(Ipv4_packet::No_ip_packet) {
|
||||
PWRN("Invalid IPv4 packet!");
|
||||
Genode::warning("Invalid IPv4 packet!");
|
||||
} catch(Udp_packet::No_udp_packet) {
|
||||
PWRN("Invalid UDP packet!");
|
||||
Genode::warning("Invalid UDP packet!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,13 +116,12 @@ void Packet_handler::send(Ethernet_frame *eth, Genode::size_t size)
|
||||
Genode::memcpy((void*)content, (void*)eth, size);
|
||||
source()->submit_packet(packet);
|
||||
} catch(Packet_stream_source< ::Nic::Session::Policy>::Packet_alloc_failed) {
|
||||
if (verbose)
|
||||
PWRN("Packet dropped");
|
||||
Genode::warning("Packet dropped");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Packet_handler::Packet_handler(Server::Entrypoint &ep, Vlan &vlan)
|
||||
Packet_handler::Packet_handler(Genode::Entrypoint &ep, Vlan &vlan)
|
||||
: _vlan(vlan),
|
||||
_sink_ack(ep, *this, &Packet_handler::_ack_avail),
|
||||
_sink_submit(ep, *this, &Packet_handler::_ready_to_submit),
|
||||
|
@ -46,7 +46,7 @@ class Net::Packet_handler
|
||||
/**
|
||||
* submit queue not empty anymore
|
||||
*/
|
||||
void _ready_to_submit(unsigned);
|
||||
void _ready_to_submit();
|
||||
|
||||
/**
|
||||
* acknoledgement queue not full anymore
|
||||
@ -54,12 +54,12 @@ class Net::Packet_handler
|
||||
* TODO: by now, we assume ACK and SUBMIT queue to be equally
|
||||
* dimensioned. That's why we ignore this signal by now.
|
||||
*/
|
||||
void _ack_avail(unsigned) { }
|
||||
void _ack_avail() { }
|
||||
|
||||
/**
|
||||
* acknoledgement queue not empty anymore
|
||||
*/
|
||||
void _ready_to_ack(unsigned);
|
||||
void _ready_to_ack();
|
||||
|
||||
/**
|
||||
* submit queue not full anymore
|
||||
@ -67,24 +67,24 @@ class Net::Packet_handler
|
||||
* TODO: by now, we just drop packets that cannot be transferred
|
||||
* to the other side, that's why we ignore this signal.
|
||||
*/
|
||||
void _packet_avail(unsigned) { }
|
||||
void _packet_avail() { }
|
||||
|
||||
/**
|
||||
* the link-state of changed
|
||||
*/
|
||||
void _link_state(unsigned);
|
||||
void _link_state();
|
||||
|
||||
protected:
|
||||
|
||||
Genode::Signal_rpc_member<Packet_handler> _sink_ack;
|
||||
Genode::Signal_rpc_member<Packet_handler> _sink_submit;
|
||||
Genode::Signal_rpc_member<Packet_handler> _source_ack;
|
||||
Genode::Signal_rpc_member<Packet_handler> _source_submit;
|
||||
Genode::Signal_rpc_member<Packet_handler> _client_link_state;
|
||||
Genode::Signal_handler<Packet_handler> _sink_ack;
|
||||
Genode::Signal_handler<Packet_handler> _sink_submit;
|
||||
Genode::Signal_handler<Packet_handler> _source_ack;
|
||||
Genode::Signal_handler<Packet_handler> _source_submit;
|
||||
Genode::Signal_handler<Packet_handler> _client_link_state;
|
||||
|
||||
public:
|
||||
|
||||
Packet_handler(Server::Entrypoint&, Vlan&);
|
||||
Packet_handler(Genode::Entrypoint&, Vlan&);
|
||||
|
||||
virtual Packet_stream_sink< ::Nic::Session::Policy> * sink() = 0;
|
||||
virtual Packet_stream_source< ::Nic::Session::Policy> * source() = 0;
|
||||
|
63
repos/os/src/server/nic_bridge/ram_session_guard.h
Normal file
63
repos/os/src/server/nic_bridge/ram_session_guard.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* \brief RAM session guard
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2016-06-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _RAM_SESSION_GUARD_H_
|
||||
#define _RAM_SESSION_GUARD_H_
|
||||
|
||||
#include <dataspace/client.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <ram_session/capability.h>
|
||||
|
||||
namespace Genode { struct Ram_session_guard; }
|
||||
|
||||
|
||||
class Genode::Ram_session_guard : public Genode::Ram_session
|
||||
{
|
||||
private:
|
||||
|
||||
Ram_session &_session;
|
||||
size_t _quota;
|
||||
size_t _used;
|
||||
|
||||
public:
|
||||
|
||||
Ram_session_guard(Ram_session &session, size_t quota)
|
||||
: _session(session) { }
|
||||
|
||||
Ram_dataspace_capability alloc(size_t size,
|
||||
Cache_attribute cached = CACHED) override
|
||||
{
|
||||
if (_used + size > _used) throw Quota_exceeded();
|
||||
_used += size;
|
||||
return _session.alloc(size, cached);
|
||||
}
|
||||
|
||||
void free(Ram_dataspace_capability ds) override
|
||||
{
|
||||
size_t size = Dataspace_client(ds).size();
|
||||
_used -= size;
|
||||
_session.free(ds);
|
||||
}
|
||||
|
||||
int ref_account(Ram_session_capability ram_session) override {
|
||||
return -1; }
|
||||
|
||||
int transfer_quota(Ram_session_capability ram_session, size_t amount) override {
|
||||
return -1; }
|
||||
|
||||
size_t quota() override { return _quota; }
|
||||
|
||||
size_t used() override { return _used; }
|
||||
};
|
||||
|
||||
#endif /* _RAM_SESSION_GUARD_H_ */
|
@ -1,6 +1,4 @@
|
||||
TARGET = nic_bridge
|
||||
LIBS = base net config server
|
||||
SRC_CC = component.cc mac.cc main.cc nic.cc packet_handler.cc
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
||||
vpath *.cc $(REP_DIR)/src/server/proxy_arp
|
||||
TARGET = nic_bridge
|
||||
LIBS = base net
|
||||
SRC_CC = component.cc mac.cc main.cc nic.cc packet_handler.cc
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
@ -16,9 +16,9 @@
|
||||
#ifndef _VLAN_H_
|
||||
#define _VLAN_H_
|
||||
|
||||
#include <util/avl_tree.h>
|
||||
#include <util/list.h>
|
||||
#include <address_node.h>
|
||||
#include <avl_safe.h>
|
||||
#include <list_safe.h>
|
||||
|
||||
namespace Net {
|
||||
|
||||
@ -26,27 +26,15 @@ namespace Net {
|
||||
* The Vlan is a database containing all clients
|
||||
* sorted by IP and MAC addresses.
|
||||
*/
|
||||
class Vlan
|
||||
struct Vlan
|
||||
{
|
||||
public:
|
||||
using Mac_address_tree = Genode::Avl_tree<Mac_address_node>;
|
||||
using Ipv4_address_tree = Genode::Avl_tree<Ipv4_address_node>;
|
||||
using Mac_address_list = Genode::List<Mac_address_node>;
|
||||
|
||||
typedef Avl_tree_safe<Mac_address_node> Mac_address_tree;
|
||||
typedef Avl_tree_safe<Ipv4_address_node> Ipv4_address_tree;
|
||||
typedef List_safe<Mac_address_node> Mac_address_list;
|
||||
|
||||
private:
|
||||
|
||||
Mac_address_tree _mac_tree;
|
||||
Mac_address_list _mac_list;
|
||||
Ipv4_address_tree _ip_tree;
|
||||
|
||||
public:
|
||||
|
||||
Vlan() {}
|
||||
|
||||
Mac_address_tree *mac_tree() { return &_mac_tree; }
|
||||
Mac_address_list *mac_list() { return &_mac_list; }
|
||||
Ipv4_address_tree *ip_tree() { return &_ip_tree; }
|
||||
Mac_address_tree mac_tree;
|
||||
Mac_address_list mac_list;
|
||||
Ipv4_address_tree ip_tree;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,7 @@ append config {
|
||||
<start name="nic_bridge">
|
||||
<resource name="RAM" quantum="6M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="usb_drv"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
|
@ -90,6 +90,7 @@ append config {
|
||||
<start name="nic_bridge">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config/>
|
||||
<route>}
|
||||
append_if $use_nic_driver config {
|
||||
<service name="Nic"> <child name="nic_drv"/></service>}
|
||||
|
@ -222,6 +222,7 @@ append_if [expr $use_nic_session && $use_nic_bridge] config {
|
||||
<start name="nic_bridge" priority="-3">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config/>
|
||||
<route>
|
||||
<service name="Nic"><child name="nic_drv"/></service>
|
||||
<any-service><parent/></any-service>
|
||||
|
Loading…
Reference in New Issue
Block a user