genode/repos/os/src/server/nic_router/uplink.h
Martin Stein 49a3a0e0d0 nic_router: multiple uplinks
Introduce the uplink tag:

! <config>
!    <uplink label="wifi"  domain="uplink">
!    <uplink label="wired" domain="wired_bridge">
!    <uplink               domain="wired_bridge">
! <config/>

For each uplink tag, the NIC router requests a NIC session with the
corresponding label or an empty label if there is no label attribute.
These NIC sessions get attached to the domain that is set in their
uplink tag as soon as the domain appears. This means their lifetime is
not bound to the domain. Uplink NIC sessions can be safely moved from
one domain to another without being closed by reconfiguring the
corresponding domain attribute.

Attention: This may render previously valid NIC router configurations
useless. A domain named "uplink" doesn't automatically request a NIC
session anymore. To fix these configurations, just add

! <uplink domain="uplink"/>

or

! <uplink label="[LABEL]" domain="uplink"/>

as direct subtag of the <config> tag.

Issue #2840
2018-06-29 10:44:53 +02:00

170 lines
3.7 KiB
C++

/*
* \brief Uplink 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 _UPLINK_H_
#define _UPLINK_H_
/* Genode includes */
#include <nic_session/connection.h>
#include <nic/packet_allocator.h>
/* local includes */
#include <avl_string_tree.h>
#include <interface.h>
#include <ipv4_address_prefix.h>
namespace Net {
using Domain_name = Genode::String<160>;
class Uplink_base;
class Uplink;
class Uplink_tree;
class Uplink_interface_base;
class Uplink_interface;
}
class Net::Uplink_tree
:
public Avl_string_tree<Uplink, Genode::Session_label>
{ };
class Net::Uplink_base
{
private:
Genode::Session_label const _label;
Domain_name const _domain;
public:
Uplink_base(Genode::Xml_node const &node);
virtual ~Uplink_base() { }
/**************
** Acessors **
**************/
Genode::Session_label const &label() const { return _label; }
Domain_name const &domain() const { return _domain; }
};
struct Net::Uplink : public Uplink_base,
private Genode::Avl_string_base
{
friend class Avl_string_tree<Uplink, Genode::Session_label>;
friend class Genode::List<Uplink>;
private:
Genode::Allocator &_alloc;
Configuration const &_config;
Pointer<Uplink_interface> _interface { };
void _invalid(char const *reason) const;
public:
struct Invalid : Genode::Exception { };
Uplink(Genode::Xml_node const &node,
Genode::Allocator &alloc,
Uplink_tree &old_uplinks,
Genode::Env &env,
Timer::Connection &timer,
Interface_list &interfaces,
Configuration &config);
~Uplink();
/*********
** log **
*********/
void print(Genode::Output &output) const;
};
class Net::Uplink_interface_base : public Interface_policy
{
private:
Const_reference<Domain_name> _domain_name;
/***************************
** Net::Interface_policy **
***************************/
Domain_name determine_domain_name() const override { return _domain_name(); };
void handle_config(Configuration const &) override { }
public:
Uplink_interface_base(Domain_name const &domain_name) : _domain_name(domain_name) { }
virtual ~Uplink_interface_base() { }
/***************
** Accessors **
***************/
void domain_name(Domain_name const &v) { _domain_name = v; }
};
class Net::Uplink_interface : public Uplink_interface_base,
public Nic::Packet_allocator,
public Nic::Connection
{
private:
enum {
PKT_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PKT_SIZE,
};
bool _link_state { false };
Genode::Signal_handler<Uplink_interface> _link_state_handler;
Net::Interface _interface;
Ipv4_address_prefix _read_interface();
void _handle_link_state();
public:
Uplink_interface(Genode::Env &env,
Timer::Connection &timer,
Genode::Allocator &alloc,
Interface_list &interfaces,
Configuration &config,
Domain_name const &domain_name,
Genode::Session_label const &label);
/***************
** Accessors **
***************/
Mac_address const &router_mac() const { return _interface.router_mac(); }
};
#endif /* _UPLINK_H_ */