nic_router: multiple interfaces at one domain

Act as hub for the interfaces at a domain. This also changes the roles of the
Domain and Interface classes. By now the Interface held the data structures for
the ARP cache, foreign ARP waiters, and the searchtrees for layer 3 links. All
these structures have moved to the Domain while the memory allocations and
lifetime management for the contents of these structures still come from from
the according Interface object. The mentioned data structures were also adapted
to fit the fact that they now may maintain objects of different interfaces.

Issue #2609
This commit is contained in:
Martin Stein 2017-12-13 17:02:01 +01:00 committed by Christian Helmuth
parent f524fb8e61
commit 4927a6f679
10 changed files with 227 additions and 138 deletions

View File

@ -14,13 +14,14 @@
/* local includes */
#include <arp_waiter.h>
#include <interface.h>
#include <domain.h>
using namespace Net;
using namespace Genode;
Arp_waiter::Arp_waiter(Interface &src,
Interface &dst,
Domain &dst,
Ipv4_address const &ip,
Packet_descriptor const &packet)
:

View File

@ -23,6 +23,7 @@ namespace Net {
using Packet_descriptor = ::Nic::Packet_descriptor;
class Interface;
class Domain;
class Arp_waiter;
using Arp_waiter_list_element = Genode::List_element<Arp_waiter>;
using Arp_waiter_list = Genode::List<Arp_waiter_list_element >;
@ -36,14 +37,14 @@ class Net::Arp_waiter
Arp_waiter_list_element _src_le;
Interface &_src;
Arp_waiter_list_element _dst_le;
Interface &_dst;
Domain &_dst;
Ipv4_address const _ip;
Packet_descriptor const _packet;
public:
Arp_waiter(Interface &src,
Interface &dst,
Domain &dst,
Ipv4_address const &ip,
Packet_descriptor const &packet);

View File

@ -145,8 +145,5 @@ Session_component *Net::Root::_create_session(char const *args)
catch (Xml_node::Nonexistent_attribute) {
error("missing domain attribute in policy");
}
catch (Pointer<Interface>::Valid) {
error("one session per domain only");
}
throw Service_denied();
}

View File

@ -14,6 +14,7 @@
/* local includes */
#include <configuration.h>
#include <l3_protocol.h>
#include <interface.h>
/* Genode includes */
#include <util/xml_node.h>
@ -119,12 +120,21 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc)
throw Invalid();
}
if (_config.verbose_domain_state()) {
log("[", *this, "] NIC sessions: 0");
log("[", *this, "] NIC sessions: ", _interface_cnt);
}
_ip_config_changed();
}
Link_side_tree &Domain::links(L3_protocol const protocol)
{
switch (protocol) {
case L3_protocol::TCP: return _tcp_links;
case L3_protocol::UDP: return _udp_links;
default: throw Interface::Bad_transport_protocol(); }
}
void Domain::_ip_config_changed()
{
if (!ip_config().valid) {
@ -156,6 +166,12 @@ void Domain::_ip_config_changed()
Domain::~Domain()
{
/* let other interfaces destroy their ARP waiters that wait for us */
while (_foreign_arp_waiters.first()) {
Arp_waiter &waiter = *_foreign_arp_waiters.first()->object();
waiter.src().cancel_arp_waiting(waiter);
}
/* destroy DHCP server */
try { destroy(_alloc, &_dhcp_server.deref()); }
catch (Pointer<Dhcp_server>::Invalid) { }
}
@ -198,6 +214,26 @@ Ipv4_address const &Domain::next_hop(Ipv4_address const &ip) const
}
void Domain::manage_interface(Interface &interface)
{
_interfaces.insert(&interface);
_interface_cnt++;
if (_config.verbose_domain_state()) {
log("[", *this, "] NIC sessions: ", _interface_cnt);
}
}
void Domain::dissolve_interface(Interface &interface)
{
_interfaces.remove(&interface);
_interface_cnt--;
if (_config.verbose_domain_state()) {
log("[", *this, "] NIC sessions: ", _interface_cnt);
}
}
/*****************
** Domain_tree **
*****************/

View File

@ -19,10 +19,12 @@
#include <transport_rule.h>
#include <nat_rule.h>
#include <ip_rule.h>
#include <arp_cache.h>
#include <port_allocator.h>
#include <pointer.h>
#include <ipv4_config.h>
#include <dhcp_server.h>
#include <interface.h>
/* Genode includes */
#include <util/avl_string.h>
@ -88,9 +90,14 @@ class Net::Domain : public Domain_base
Port_allocator _tcp_port_alloc;
Port_allocator _udp_port_alloc;
Nat_rule_tree _nat_rules;
Pointer<Interface> _interface;
List<Interface> _interfaces;
unsigned long _interface_cnt { 0 };
Pointer<Dhcp_server> _dhcp_server;
Genode::Reconstructible<Ipv4_config> _ip_config;
Arp_cache _arp_cache;
Arp_waiter_list _foreign_arp_waiters;
Link_side_tree _tcp_links;
Link_side_tree _udp_links;
void _read_forward_rules(Genode::Cstring const &protocol,
Domain_tree &domains,
@ -127,6 +134,12 @@ class Net::Domain : public Domain_base
void discard_ip_config();
Link_side_tree &links(L3_protocol const protocol);
void manage_interface(Interface &interface);
void dissolve_interface(Interface &interface);
/*********
** log **
@ -147,10 +160,14 @@ class Net::Domain : public Domain_base
Transport_rule_list &tcp_rules() { return _tcp_rules; }
Transport_rule_list &udp_rules() { return _udp_rules; }
Nat_rule_tree &nat_rules() { return _nat_rules; }
Pointer<Interface> &interface() { return _interface; }
List<Interface> &interfaces() { return _interfaces; }
Configuration &config() const { return _config; }
Domain_avl_member &avl_member() { return _avl_member; }
Dhcp_server &dhcp_server() { return _dhcp_server.deref(); }
Arp_cache &arp_cache() { return _arp_cache; }
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
Link_side_tree &tcp_links() { return _tcp_links; }
Link_side_tree &udp_links() { return _udp_links; }
};

View File

@ -42,15 +42,15 @@ static void _destroy_closed_links(Link_list &closed_links,
template <typename LINK_TYPE>
static void _destroy_links(Link_side_tree &links,
Link_list &closed_links,
Deallocator &dealloc)
static void _destroy_links(Link_list &links,
Link_list &closed_links,
Deallocator &dealloc)
{
_destroy_closed_links<LINK_TYPE>(closed_links, dealloc);
while (Link_side *link_side = links.first()) {
Link &link = link_side->link();
link.dissolve();
destroy(dealloc, static_cast<LINK_TYPE *>(&link));
while (Link *link = links.first()) {
link->dissolve();
links.remove(link);
destroy(dealloc, static_cast<LINK_TYPE *>(link));
}
}
@ -193,35 +193,39 @@ void
Interface::_new_link(L3_protocol const protocol,
Link_side_id const &local,
Pointer<Port_allocator_guard> const remote_port_alloc,
Interface &remote_interface,
Domain &remote_domain,
Link_side_id const &remote)
{
switch (protocol) {
case L3_protocol::TCP:
{
Tcp_link &link = *new (_alloc)
Tcp_link(*this, local, remote_port_alloc, remote_interface,
Tcp_link(*this, local, remote_port_alloc, remote_domain,
remote, _timer, _config(), protocol);
_tcp_links.insert(&link.client());
remote_interface._tcp_links.insert(&link.server());
_tcp_links.insert(&link);
_domain.tcp_links().insert(&link.client());
remote_domain.tcp_links().insert(&link.server());
if (_config().verbose()) {
log("New TCP client link: ", link.client(), " at ", _domain);
log("New TCP server link: ", link.server(),
" at ", remote_interface._domain);
" at ", remote_domain);
}
return;
}
case L3_protocol::UDP:
{
Udp_link &link = *new (_alloc)
Udp_link(*this, local, remote_port_alloc, remote_interface,
Udp_link(*this, local, remote_port_alloc, remote_domain,
remote, _timer, _config(), protocol);
_udp_links.insert(&link.client());
remote_interface._udp_links.insert(&link.server());
_udp_links.insert(&link);
_domain.udp_links().insert(&link.client());
remote_domain.udp_links().insert(&link.server());
if (_config().verbose()) {
log("New UDP client link: ", link.client(), " at ", _domain);
log("New UDP server link: ", link.server(),
" at ", remote_interface._domain);
" at ", remote_domain);
}
return;
}
@ -229,21 +233,6 @@ Interface::_new_link(L3_protocol const protocol,
}
Link_side_tree &Interface::_links(L3_protocol const protocol)
{
switch (protocol) {
case L3_protocol::TCP: return _tcp_links;
case L3_protocol::UDP: return _udp_links;
default: throw Bad_transport_protocol(); }
}
void Interface::link_closed(Link &link, L3_protocol const prot)
{
_closed_links(prot).insert(&link);
}
void Interface::dhcp_allocation_expired(Dhcp_allocation &allocation)
{
_release_dhcp_allocation(allocation);
@ -251,13 +240,16 @@ void Interface::dhcp_allocation_expired(Dhcp_allocation &allocation)
}
void Interface::dissolve_link(Link_side &link_side, L3_protocol const prot)
Link_list &Interface::links(L3_protocol const protocol)
{
_links(prot).remove(&link_side);
switch (protocol) {
case L3_protocol::TCP: return _tcp_links;
case L3_protocol::UDP: return _udp_links;
default: throw Bad_transport_protocol(); }
}
Link_list &Interface::_closed_links(L3_protocol const protocol)
Link_list &Interface::closed_links(L3_protocol const protocol)
{
switch (protocol) {
case L3_protocol::TCP: return _closed_tcp_links;
@ -270,16 +262,18 @@ void Interface::_adapt_eth(Ethernet_frame &eth,
size_t const eth_size,
Ipv4_address const &ip,
Packet_descriptor const &pkt,
Interface &interface)
Domain &domain)
{
if (!interface.domain().ip_config().valid) {
if (!domain.ip_config().valid) {
throw Drop_packet_inform("target domain has yet no IP config");
}
Ipv4_address const &hop_ip = interface._domain.next_hop(ip);
try { eth.dst(interface._arp_cache.find_by_ip(hop_ip).mac()); }
Ipv4_address const &hop_ip = domain.next_hop(ip);
try { eth.dst(domain.arp_cache().find_by_ip(hop_ip).mac()); }
catch (Arp_cache::No_match) {
interface._broadcast_arp_request(hop_ip);
new (_alloc) Arp_waiter(*this, interface, hop_ip, pkt);
domain.interfaces().for_each([&] (Interface &interface) {
interface._broadcast_arp_request(hop_ip);
});
new (_alloc) Arp_waiter(*this, domain, hop_ip, pkt);
throw Packet_postponed();
}
eth.src(_router_mac);
@ -293,23 +287,25 @@ void Interface::_nat_link_and_pass(Ethernet_frame &eth,
void *const prot_base,
size_t const prot_size,
Link_side_id const &local,
Interface &interface)
Domain &domain)
{
Pointer<Port_allocator_guard> remote_port_alloc;
try {
Nat_rule &nat = interface._domain.nat_rules().find_by_domain(_domain);
Nat_rule &nat = domain.nat_rules().find_by_domain(_domain);
if(_config().verbose()) {
log("Using NAT rule: ", nat); }
_src_port(prot, prot_base, nat.port_alloc(prot).alloc());
ip.src(interface._router_ip());
ip.src(domain.ip_config().interface.address);
remote_port_alloc.set(nat.port_alloc(prot));
}
catch (Nat_rule_tree::No_match) { }
Link_side_id const remote = { ip.dst(), _dst_port(prot, prot_base),
ip.src(), _src_port(prot, prot_base) };
_new_link(prot, local, remote_port_alloc, interface, remote);
interface._pass_prot(eth, eth_size, ip, prot, prot_base, prot_size);
_new_link(prot, local, remote_port_alloc, domain, remote);
domain.interfaces().for_each([&] (Interface &interface) {
interface._pass_prot(eth, eth_size, ip, prot, prot_base, prot_size);
});
}
@ -550,7 +546,12 @@ void Interface::_handle_dhcp_request(Ethernet_frame &eth,
void Interface::_domain_broadcast(Ethernet_frame &eth, size_t eth_size)
{
throw Drop_packet_warn("domain broadcasts not yet supported");
eth.src(_router_mac);
_domain.interfaces().for_each([&] (Interface &interface) {
if (&interface != this) {
interface.send(eth, eth_size);
}
});
}
@ -609,21 +610,23 @@ void Interface::_handle_ip(Ethernet_frame &eth,
/* try to route via existing UDP/TCP links */
try {
Link_side const &local_side = _links(prot).find_by_id(local);
Link_side const &local_side = _domain.links(prot).find_by_id(local);
Link &link = local_side.link();
bool const client = local_side.is_client();
Link_side &remote_side = client ? link.server() : link.client();
Interface &interface = remote_side.interface();
Domain &domain = remote_side.domain();
if (_config().verbose()) {
log("Using ", l3_protocol_name(prot), " link: ", link); }
_adapt_eth(eth, eth_size, remote_side.src_ip(), pkt, interface);
_adapt_eth(eth, eth_size, remote_side.src_ip(), pkt, domain);
ip.src(remote_side.dst_ip());
ip.dst(remote_side.src_ip());
_src_port(prot, prot_base, remote_side.dst_port());
_dst_port(prot, prot_base, remote_side.src_port());
interface._pass_prot(eth, eth_size, ip, prot, prot_base, prot_size);
domain.interfaces().for_each([&] (Interface &interface) {
interface._pass_prot(eth, eth_size, ip, prot, prot_base, prot_size);
});
_link_packet(prot, prot_base, link, client);
return;
}
@ -635,14 +638,14 @@ void Interface::_handle_ip(Ethernet_frame &eth,
Forward_rule const &rule =
_forward_rules(prot).find_by_port(local.dst_port);
Interface &interface = rule.domain().interface().deref();
if(_config().verbose()) {
log("Using forward rule: ", l3_protocol_name(prot), " ", rule); }
_adapt_eth(eth, eth_size, rule.to(), pkt, interface);
Domain &domain = rule.domain();
_adapt_eth(eth, eth_size, rule.to(), pkt, domain);
ip.dst(rule.to());
_nat_link_and_pass(eth, eth_size, ip, prot, prot_base, prot_size,
local, interface);
_nat_link_and_pass(eth, eth_size, ip, prot, prot_base,
prot_size, local, domain);
return;
}
catch (Forward_rule_tree::No_match) { }
@ -655,14 +658,14 @@ void Interface::_handle_ip(Ethernet_frame &eth,
Permit_rule const &permit_rule =
transport_rule.permit_rule(local.dst_port);
Interface &interface = permit_rule.domain().interface().deref();
if(_config().verbose()) {
log("Using ", l3_protocol_name(prot), " rule: ", transport_rule,
" ", permit_rule); }
_adapt_eth(eth, eth_size, local.dst_ip, pkt, interface);
Domain &domain = permit_rule.domain();
_adapt_eth(eth, eth_size, local.dst_ip, pkt, domain);
_nat_link_and_pass(eth, eth_size, ip, prot, prot_base, prot_size,
local, interface);
local, domain);
return;
}
catch (Transport_rule_list::No_match) { }
@ -675,12 +678,15 @@ void Interface::_handle_ip(Ethernet_frame &eth,
Ip_rule const &rule =
_domain.ip_rules().longest_prefix_match(ip.dst());
Interface &interface = rule.domain().interface().deref();
if(_config().verbose()) {
log("Using IP rule: ", rule); }
_adapt_eth(eth, eth_size, ip.dst(), pkt, interface);
interface._pass_ip(eth, eth_size, ip);
Domain &domain = rule.domain();
_adapt_eth(eth, eth_size, ip.dst(), pkt, domain);
domain.interfaces().for_each([&] (Interface &interface) {
interface._pass_ip(eth, eth_size, ip);
});
return;
}
catch (Ip_rule_list::No_match) { }
@ -717,7 +723,7 @@ void Interface::_handle_arp_reply(Ethernet_frame &eth,
{
try {
/* check wether a matching ARP cache entry already exists */
_arp_cache.find_by_ip(arp.src_ip());
_domain.arp_cache().find_by_ip(arp.src_ip());
if (_config().verbose()) {
log("ARP entry already exists"); }
}
@ -725,10 +731,10 @@ void Interface::_handle_arp_reply(Ethernet_frame &eth,
/* by now, no matching ARP cache entry exists, so create one */
Ipv4_address const ip = arp.src_ip();
_arp_cache.new_entry(ip, arp.src_mac());
_domain.arp_cache().new_entry(ip, arp.src_mac());
/* continue handling of packets that waited for the entry */
for (Arp_waiter_list_element *waiter_le = _foreign_arp_waiters.first();
for (Arp_waiter_list_element *waiter_le = _domain.foreign_arp_waiters().first();
waiter_le; )
{
Arp_waiter &waiter = *waiter_le->object();
@ -930,7 +936,7 @@ void Interface::_handle_eth(void *const eth_base,
catch (Domain::No_next_hop) {
error("can not find next hop"); }
catch (Pointer<Interface>::Invalid) {
catch (List<Interface>::Empty) {
error("no interface connected to domain"); }
catch (Alloc_dhcp_msg_buffer_failed) {
@ -976,10 +982,7 @@ Interface::Interface(Entrypoint &ep,
_router_mac(router_mac), _mac(mac), _timer(timer), _alloc(alloc),
_domain(domain)
{
if (_config().verbose_domain_state()) {
log("[", _domain, "] NIC sessions: 1");
}
_domain.interface().set(*this);
_domain.manage_interface(*this);
}
@ -1001,7 +1004,7 @@ void Interface::_ack_packet(Packet_descriptor const &pkt)
}
void Interface::_cancel_arp_waiting(Arp_waiter &waiter)
void Interface::cancel_arp_waiting(Arp_waiter &waiter)
{
warning("waiting for ARP cancelled");
_ack_packet(waiter.packet());
@ -1011,19 +1014,12 @@ void Interface::_cancel_arp_waiting(Arp_waiter &waiter)
Interface::~Interface()
{
_domain.interface().unset();
if (_config().verbose_domain_state()) {
log("[", _domain, "] NIC sessions: 0");
}
_domain.dissolve_interface(*this);
/* destroy ARP waiters */
/* destroy our own ARP waiters */
while (_own_arp_waiters.first()) {
_cancel_arp_waiting(*_foreign_arp_waiters.first()->object()); }
while (_foreign_arp_waiters.first()) {
Arp_waiter &waiter = *_foreign_arp_waiters.first()->object();
waiter.src()._cancel_arp_waiting(waiter); }
cancel_arp_waiting(*_own_arp_waiters.first()->object());
}
/* destroy links */
_destroy_links<Tcp_link>(_tcp_links, _closed_tcp_links, _alloc);
_destroy_links<Udp_link>(_udp_links, _closed_udp_links, _alloc);

View File

@ -16,11 +16,11 @@
/* local includes */
#include <link.h>
#include <arp_cache.h>
#include <arp_waiter.h>
#include <l3_protocol.h>
#include <dhcp_client.h>
#include <dhcp_server.h>
#include <list.h>
/* Genode includes */
#include <nic_session/nic_session.h>
@ -43,7 +43,7 @@ namespace Net {
}
class Net::Interface
class Net::Interface : public Genode::List<Interface>::Element
{
protected:
@ -63,11 +63,9 @@ class Net::Interface
Timer::Connection &_timer;
Genode::Allocator &_alloc;
Domain &_domain;
Arp_cache _arp_cache;
Arp_waiter_list _own_arp_waiters;
Arp_waiter_list _foreign_arp_waiters;
Link_side_tree _tcp_links;
Link_side_tree _udp_links;
Link_list _tcp_links;
Link_list _udp_links;
Link_list _closed_tcp_links;
Link_list _closed_udp_links;
Dhcp_allocation_tree _dhcp_allocations;
@ -77,7 +75,7 @@ class Net::Interface
void _new_link(L3_protocol const protocol,
Link_side_id const &local_id,
Pointer<Port_allocator_guard> const remote_port_alloc,
Interface &remote_interface,
Domain &remote_domain,
Link_side_id const &remote_id);
void _destroy_released_dhcp_allocations();
@ -126,7 +124,7 @@ class Net::Interface
Genode::size_t const eth_size,
Ipv4_address const &ip,
Packet_descriptor const &pkt,
Interface &interface);
Domain &domain);
void _nat_link_and_pass(Ethernet_frame &eth,
Genode::size_t const eth_size,
@ -135,7 +133,7 @@ class Net::Interface
void *const prot_base,
Genode::size_t const prot_size,
Link_side_id const &local_id,
Interface &interface);
Domain &domain);
void _broadcast_arp_request(Ipv4_address const &ip);
@ -154,10 +152,6 @@ class Net::Interface
void _continue_handle_eth(Packet_descriptor const &pkt);
Link_list &_closed_links(L3_protocol const protocol);
Link_side_tree &_links(L3_protocol const protocol);
Configuration &_config() const;
Ipv4_config const &_ip_config() const;
@ -170,8 +164,6 @@ class Net::Interface
void _ack_packet(Packet_descriptor const &pkt);
void _cancel_arp_waiting(Arp_waiter &waiter);
virtual Packet_stream_sink &_sink() = 0;
virtual Packet_stream_source &_source() = 0;
@ -220,23 +212,25 @@ class Net::Interface
~Interface();
void link_closed(Link &link, L3_protocol const prot);
void dhcp_allocation_expired(Dhcp_allocation &allocation);
void dissolve_link(Link_side &link_side, L3_protocol const prot);
void send(Ethernet_frame &eth, Genode::size_t const eth_size);
Link_list &closed_links(L3_protocol const protocol);
Link_list &links(L3_protocol const protocol);
void cancel_arp_waiting(Arp_waiter &waiter);
/***************
** Accessors **
***************/
Domain &domain() { return _domain; }
Mac_address router_mac() const { return _router_mac; }
Arp_waiter_list &own_arp_waiters() { return _own_arp_waiters; }
Arp_waiter_list &foreign_arp_waiters() { return _foreign_arp_waiters; }
Domain &domain() { return _domain; }
Mac_address router_mac() const { return _router_mac; }
Arp_waiter_list &own_arp_waiters() { return _own_arp_waiters; }
};
#endif /* _INTERFACE_H_ */

View File

@ -16,9 +16,7 @@
/* local includes */
#include <link.h>
#include <interface.h>
#include <configuration.h>
#include <l3_protocol.h>
using namespace Net;
using namespace Genode;
@ -51,11 +49,11 @@ bool Link_side_id::operator > (Link_side_id const &id) const
** Link_side **
***************/
Link_side::Link_side(Interface &interface,
Link_side::Link_side(Domain &domain,
Link_side_id const &id,
Link &link)
:
_interface(interface), _id(id), _link(link)
_domain(domain), _id(id), _link(link)
{ }
@ -113,7 +111,7 @@ void Link::print(Output &output) const
Link::Link(Interface &cln_interface,
Link_side_id const &cln_id,
Pointer<Port_allocator_guard> const srv_port_alloc,
Interface &srv_interface,
Domain &srv_domain,
Link_side_id const &srv_id,
Timer::Connection &timer,
Configuration &config,
@ -121,9 +119,10 @@ Link::Link(Interface &cln_interface,
Microseconds const close_timeout)
:
_config(config),
_client(cln_interface, cln_id, *this),
_client(cln_interface.domain(), cln_id, *this),
_client_interface(cln_interface),
_server_port_alloc(srv_port_alloc),
_server(srv_interface, srv_id, *this),
_server(srv_domain, srv_id, *this),
_close_timeout(timer, *this, &Link::_handle_close_timeout),
_close_timeout_us(close_timeout),
_protocol(protocol)
@ -135,14 +134,15 @@ Link::Link(Interface &cln_interface,
void Link::_handle_close_timeout(Duration)
{
dissolve();
_client._interface.link_closed(*this, _protocol);
_client_interface.links(_protocol).remove(this);
_client_interface.closed_links(_protocol).insert(this);
}
void Link::dissolve()
{
_client._interface.dissolve_link(_client, _protocol);
_server._interface.dissolve_link(_server, _protocol);
_client.domain().links(_protocol).remove(&_client);
_server.domain().links(_protocol).remove(&_server);
if (_config.verbose()) {
log("Dissolve ", l3_protocol_name(_protocol), " link: ", *this); }
@ -151,8 +151,8 @@ void Link::dissolve()
if (_config.verbose()) {
log("Free ", l3_protocol_name(_protocol),
" port ", _server.dst_port(),
" at ", _server.interface().domain(),
" that was used by ", _client.interface().domain());
" at ", _server.domain(),
" that was used by ", _client.domain());
}
}
catch (Pointer<Port_allocator_guard>::Invalid) { }
@ -166,13 +166,13 @@ void Link::dissolve()
Tcp_link::Tcp_link(Interface &cln_interface,
Link_side_id const &cln_id,
Pointer<Port_allocator_guard> const srv_port_alloc,
Interface &srv_interface,
Domain &srv_domain,
Link_side_id const &srv_id,
Timer::Connection &timer,
Configuration &config,
L3_protocol const protocol)
:
Link(cln_interface, cln_id, srv_port_alloc, srv_interface, srv_id, timer,
Link(cln_interface, cln_id, srv_port_alloc, srv_domain, srv_id, timer,
config, protocol, config.tcp_idle_timeout())
{ }
@ -227,12 +227,12 @@ void Tcp_link::client_packet(Tcp_packet &tcp)
Udp_link::Udp_link(Interface &cln_interface,
Link_side_id const &cln_id,
Pointer<Port_allocator_guard> const srv_port_alloc,
Interface &srv_interface,
Domain &srv_domain,
Link_side_id const &srv_id,
Timer::Connection &timer,
Configuration &config,
L3_protocol const protocol)
:
Link(cln_interface, cln_id, srv_port_alloc, srv_interface, srv_id, timer,
Link(cln_interface, cln_id, srv_port_alloc, srv_domain, srv_id, timer,
config, protocol, config.udp_idle_timeout())
{ }

View File

@ -30,6 +30,7 @@ namespace Net {
class Configuration;
class Port_allocator_guard;
class Tcp_packet;
class Domain;
class Interface;
class Link_side_id;
class Link_side;
@ -70,13 +71,13 @@ class Net::Link_side : public Genode::Avl_node<Link_side>
private:
Interface &_interface;
Domain &_domain;
Link_side_id const _id;
Link &_link;
public:
Link_side(Interface &interface,
Link_side(Domain &domain,
Link_side_id const &id,
Link &link);
@ -103,7 +104,7 @@ class Net::Link_side : public Genode::Avl_node<Link_side>
** Accessors **
***************/
Interface &interface() const { return _interface; }
Domain &domain() const { return _domain; }
Link &link() const { return _link; }
Ipv4_address const &src_ip() const { return _id.src_ip; }
Ipv4_address const &dst_ip() const { return _id.dst_ip; }
@ -126,6 +127,7 @@ class Net::Link : public Link_list::Element
Configuration &_config;
Link_side _client;
Interface &_client_interface;
Pointer<Port_allocator_guard> const _server_port_alloc;
Link_side _server;
Timer::One_shot_timeout<Link> _close_timeout;
@ -143,7 +145,7 @@ class Net::Link : public Link_list::Element
Link(Interface &cln_interface,
Link_side_id const &cln_id,
Pointer<Port_allocator_guard> const srv_port_alloc,
Interface &srv_interface,
Domain &srv_domain,
Link_side_id const &srv_id,
Timer::Connection &timer,
Configuration &config,
@ -174,11 +176,11 @@ class Net::Tcp_link : public Link
{
private:
bool _client_fin = false;
bool _server_fin = false;
bool _client_fin_acked = false;
bool _server_fin_acked = false;
bool _closed = false;
bool _client_fin { false };
bool _server_fin { false };
bool _client_fin_acked { false };
bool _server_fin_acked { false };
bool _closed { false };
void _fin_acked();
@ -187,7 +189,7 @@ class Net::Tcp_link : public Link
Tcp_link(Interface &cln_interface,
Link_side_id const &cln_id,
Pointer<Port_allocator_guard> const srv_port_alloc,
Interface &srv_interface,
Domain &srv_domain,
Link_side_id const &srv_id,
Timer::Connection &timer,
Configuration &config,
@ -204,7 +206,7 @@ struct Net::Udp_link : Link
Udp_link(Interface &cln_interface,
Link_side_id const &cln_id,
Pointer<Port_allocator_guard> const srv_port_alloc,
Interface &srv_interface,
Domain &srv_domain,
Link_side_id const &srv_id,
Timer::Connection &timer,
Configuration &config,

View File

@ -0,0 +1,45 @@
/*
* \brief Genode list with additional functions needed by NIC router
* \author Martin Stein
* \date 2016-08-19
*/
/*
* 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 _LIST_H_
#define _LIST_H_
/* Genode includes */
#include <util/list.h>
namespace Net {
template <typename> class List;
}
template <typename LT>
struct Net::List : Genode::List<LT>
{
using Base = Genode::List<LT>;
struct Empty : Genode::Exception { };
template <typename FUNC>
void for_each(FUNC && functor)
{
if (!Base::first()) {
throw Empty();
}
for (LT * elem = Base::first(); elem;
elem = elem->Base::Element::next())
{
functor(*elem);
}
}
};
#endif /* _LIST_H_ */