genode/repos/os/src/server/nic_router/domain.h

230 lines
8.0 KiB
C
Raw Normal View History

/*
* \brief Reflects an effective domain configuration node
* \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 _DOMAIN_H_
#define _DOMAIN_H_
/* local includes */
#include "forward_rule.h"
#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"
#include "avl_string_tree.h"
/* Genode includes */
#include <util/reconstructible.h>
namespace Genode {
class Xml_generator;
class Allocator;
}
namespace Net {
class Interface;
class Configuration;
class Domain_base;
class Domain;
using Domain_name = Genode::String<160>;
class Domain_tree;
class Domain_link_stats;
class Domain_object_stats;
}
struct Net::Domain_object_stats
{
Genode::size_t destroyed { 0 };
void dissolve_interface(Interface_object_stats const &stats);
void report(Genode::Xml_generator &xml);
};
struct Net::Domain_link_stats : Domain_object_stats
{
Genode::size_t refused_for_ram { 0 };
Genode::size_t refused_for_ports { 0 };
Genode::size_t destroyed { 0 };
void dissolve_interface(Interface_link_stats const &stats);
void report(Genode::Xml_generator &xml);
};
class Net::Domain_tree : public Avl_string_tree<Domain, Domain_name> { };
class Net::Domain_base
{
protected:
Domain_name const _name;
Domain_base(Genode::Xml_node const node);
};
class Net::Domain : public Domain_base,
public List<Domain>::Element,
public Genode::Avl_string_base
{
private:
Configuration &_config;
Genode::Xml_node _node;
Genode::Allocator &_alloc;
Ip_rule_list _ip_rules { };
Forward_rule_tree _tcp_forward_rules { };
Forward_rule_tree _udp_forward_rules { };
Transport_rule_list _tcp_rules { };
Transport_rule_list _udp_rules { };
Ip_rule_list _icmp_rules { };
Port_allocator _tcp_port_alloc { };
Port_allocator _udp_port_alloc { };
Port_allocator _icmp_port_alloc { };
Nat_rule_tree _nat_rules { };
Interface_list _interfaces { };
unsigned long _interface_cnt { 0 };
Pointer<Dhcp_server> _dhcp_server { };
Genode::Reconstructible<Ipv4_config> _ip_config;
nic_router: re-use dynamic IPv4 config if possible When re-configuring the NIC router, determine for each domain if at least one interface stays with the domain. If a domain fullfills this and has a dynamic IP config (received via a DHCP client), keep the IP config. To achieve this, the following changes have been made to the existing NIC router code: * Split-up Interface::handle_config into three steps: 1) Determine for each interface if its domain can keep its IP config or or if it has to mark it invalid. This must be done before (re-)attaching any interface because during "attach" several decisions are made based on the validity of the IP config of corresponding the domain. (E.g. whether to participate in sending DHCP DISCOVERs {IP config invalid} or whether to participate in sending pending ARP REQUESTs {IP config valid} ). 2) Detach, attach, or re-attach each interface according to the configuration. This must be done before re-considering the temporary state objects of each interface because the latter might have effects on the interfaces of remote domains which must then be in place already. 3) Re-consider temporary state objects of each interface. (E.g. transport layer connection states) * Re-work IP-config setter in a way that it works as follows: 1) If the old IP config is valid, let all local interfaces as well as remote interfaces that depend on the IP config of the domain detach from the old IP config. 2) Overwrite with new IP config 3) If the new IP config is valid, let all local interfaces as well as remote interfaces that depend on the IP config of the domain attach to the new IP config. Issue #2815
2018-05-16 13:55:13 +02:00
bool const _ip_config_dynamic { !ip_config().valid };
List<Domain> _ip_config_dependents { };
Arp_cache _arp_cache { *this };
Arp_waiter_list _foreign_arp_waiters { };
Link_side_tree _tcp_links { };
Link_side_tree _udp_links { };
Link_side_tree _icmp_links { };
Genode::size_t _tx_bytes { 0 };
Genode::size_t _rx_bytes { 0 };
bool const _verbose_packets;
bool const _verbose_packet_drop;
bool const _icmp_echo_server;
Genode::Session_label const _label;
Domain_link_stats _udp_stats { };
Domain_link_stats _tcp_stats { };
Domain_link_stats _icmp_stats { };
Domain_object_stats _arp_stats { };
Domain_object_stats _dhcp_stats { };
void _read_forward_rules(Genode::Cstring const &protocol,
Domain_tree &domains,
Genode::Xml_node const node,
char const *type,
Forward_rule_tree &rules);
void _read_transport_rules(Genode::Cstring const &protocol,
Domain_tree &domains,
Genode::Xml_node const node,
char const *type,
Transport_rule_list &rules);
void _invalid(char const *reason) const;
void _log_ip_config() const;
void __FIXME__dissolve_foreign_arp_waiters();
public:
struct Invalid : Genode::Exception { };
struct Ip_config_static : Genode::Exception { };
struct No_next_hop : Genode::Exception { };
Domain(Configuration &config,
Genode::Xml_node const node,
Genode::Allocator &alloc);
~Domain();
void init(Domain_tree &domains);
void deinit();
Ipv4_address const &next_hop(Ipv4_address const &ip) const;
nic_router: re-use dynamic IPv4 config if possible When re-configuring the NIC router, determine for each domain if at least one interface stays with the domain. If a domain fullfills this and has a dynamic IP config (received via a DHCP client), keep the IP config. To achieve this, the following changes have been made to the existing NIC router code: * Split-up Interface::handle_config into three steps: 1) Determine for each interface if its domain can keep its IP config or or if it has to mark it invalid. This must be done before (re-)attaching any interface because during "attach" several decisions are made based on the validity of the IP config of corresponding the domain. (E.g. whether to participate in sending DHCP DISCOVERs {IP config invalid} or whether to participate in sending pending ARP REQUESTs {IP config valid} ). 2) Detach, attach, or re-attach each interface according to the configuration. This must be done before re-considering the temporary state objects of each interface because the latter might have effects on the interfaces of remote domains which must then be in place already. 3) Re-consider temporary state objects of each interface. (E.g. transport layer connection states) * Re-work IP-config setter in a way that it works as follows: 1) If the old IP config is valid, let all local interfaces as well as remote interfaces that depend on the IP config of the domain detach from the old IP config. 2) Overwrite with new IP config 3) If the new IP config is valid, let all local interfaces as well as remote interfaces that depend on the IP config of the domain attach to the new IP config. Issue #2815
2018-05-16 13:55:13 +02:00
void ip_config(Ipv4_config const &ip_config);
void ip_config(Ipv4_address ip,
Ipv4_address subnet_mask,
Ipv4_address gateway,
Ipv4_address dns_server);
void discard_ip_config();
nic_router: re-use dynamic IPv4 config if possible When re-configuring the NIC router, determine for each domain if at least one interface stays with the domain. If a domain fullfills this and has a dynamic IP config (received via a DHCP client), keep the IP config. To achieve this, the following changes have been made to the existing NIC router code: * Split-up Interface::handle_config into three steps: 1) Determine for each interface if its domain can keep its IP config or or if it has to mark it invalid. This must be done before (re-)attaching any interface because during "attach" several decisions are made based on the validity of the IP config of corresponding the domain. (E.g. whether to participate in sending DHCP DISCOVERs {IP config invalid} or whether to participate in sending pending ARP REQUESTs {IP config valid} ). 2) Detach, attach, or re-attach each interface according to the configuration. This must be done before re-considering the temporary state objects of each interface because the latter might have effects on the interfaces of remote domains which must then be in place already. 3) Re-consider temporary state objects of each interface. (E.g. transport layer connection states) * Re-work IP-config setter in a way that it works as follows: 1) If the old IP config is valid, let all local interfaces as well as remote interfaces that depend on the IP config of the domain detach from the old IP config. 2) Overwrite with new IP config 3) If the new IP config is valid, let all local interfaces as well as remote interfaces that depend on the IP config of the domain attach to the new IP config. Issue #2815
2018-05-16 13:55:13 +02:00
void try_reuse_ip_config(Domain const &domain);
Link_side_tree &links(L3_protocol const protocol);
void attach_interface(Interface &interface);
void detach_interface(Interface &interface);
void raise_rx_bytes(Genode::size_t bytes) { _rx_bytes += bytes; }
void raise_tx_bytes(Genode::size_t bytes) { _tx_bytes += bytes; }
void report(Genode::Xml_generator &xml);
/*********
** log **
*********/
void print(Genode::Output &output) const;
/***************
** Accessors **
***************/
bool verbose_packets() const { return _verbose_packets; }
bool verbose_packet_drop() const { return _verbose_packet_drop; }
bool icmp_echo_server() const { return _icmp_echo_server; }
Genode::Session_label const &label() const { return _label; }
Ipv4_config const &ip_config() const { return *_ip_config; }
List<Domain> &ip_config_dependents() { return _ip_config_dependents; }
Domain_name const &name() const { return _name; }
Ip_rule_list &ip_rules() { return _ip_rules; }
Forward_rule_tree &tcp_forward_rules() { return _tcp_forward_rules; }
Forward_rule_tree &udp_forward_rules() { return _udp_forward_rules; }
Transport_rule_list &tcp_rules() { return _tcp_rules; }
Transport_rule_list &udp_rules() { return _udp_rules; }
Ip_rule_list &icmp_rules() { return _icmp_rules; }
Nat_rule_tree &nat_rules() { return _nat_rules; }
Interface_list &interfaces() { return _interfaces; }
Configuration &config() const { return _config; }
Dhcp_server &dhcp_server();
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; }
Link_side_tree &icmp_links() { return _icmp_links; }
Domain_link_stats &udp_stats() { return _udp_stats; }
Domain_link_stats &tcp_stats() { return _tcp_stats; }
Domain_link_stats &icmp_stats() { return _icmp_stats; }
Domain_object_stats &arp_stats() { return _arp_stats; }
Domain_object_stats &dhcp_stats() { return _dhcp_stats; }
};
#endif /* _DOMAIN_H_ */