From 3560555acc95a80649be9a77938d7b91befe8ae5 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Fri, 13 Oct 2017 16:22:05 +0200 Subject: [PATCH] nic_router: encapsulate IPv4 peer config in class An IPv4 config (for a domain/interface of the router) consists of an IPv4 address, a subnet prefix specifier, an optional gateway IPv4 address, and some flags that declare whether these fields and the config as a whole are valid. To make the handling of those tightly connected values easier and less error prone, we encapsulate them in a new class. Ref #2534 --- repos/os/src/server/nic_router/domain.cc | 16 ++++---- repos/os/src/server/nic_router/domain.h | 10 ++--- repos/os/src/server/nic_router/interface.cc | 15 +++++--- repos/os/src/server/nic_router/interface.h | 3 ++ repos/os/src/server/nic_router/ipv4_config.cc | 31 +++++++++++++++ repos/os/src/server/nic_router/ipv4_config.h | 38 +++++++++++++++++++ repos/os/src/server/nic_router/target.mk | 2 +- 7 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 repos/os/src/server/nic_router/ipv4_config.cc create mode 100644 repos/os/src/server/nic_router/ipv4_config.h diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 347f64c77..aa24dcfb0 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -160,19 +160,17 @@ Domain::Domain(Configuration &config, Xml_node const node, Allocator &alloc) : Domain_base(node), _avl_member(_name, *this), _config(config), _node(node), _alloc(alloc), - _interface_attr(node.attribute_value("interface", Ipv4_address_prefix())), - _gateway(node.attribute_value("gateway", Ipv4_address())), - _gateway_valid(_gateway.valid()) + _ip_config(_node.attribute_value("interface", Ipv4_address_prefix()), + _node.attribute_value("gateway", Ipv4_address())) { - if (_name == Domain_name() || !_interface_attr.valid() || - (_gateway_valid && !_interface_attr.prefix_matches(_gateway))) - { + if (_name == Domain_name() || !_ip_config.interface_valid) { throw Invalid(); } /* try to find configuration for DHCP server role */ try { _dhcp_server.set(*new (alloc) - Dhcp_server(node.sub_node("dhcp-server"), alloc, _interface_attr)); + Dhcp_server(node.sub_node("dhcp-server"), alloc, + _ip_config.interface)); if (_config.verbose()) { log(" DHCP server: ", _dhcp_server.deref()); } @@ -221,8 +219,8 @@ void Domain::create_rules(Domain_tree &domains) Ipv4_address const &Domain::next_hop(Ipv4_address const &ip) const { - if (_interface_attr.prefix_matches(ip)) { return ip; } - if (_gateway_valid) { return _gateway; } + if (_ip_config.interface.prefix_matches(ip)) { return ip; } + if (_ip_config.gateway_valid) { return _ip_config.gateway; } throw No_next_hop(); } diff --git a/repos/os/src/server/nic_router/domain.h b/repos/os/src/server/nic_router/domain.h index 5f97f4bea..e3c9d550d 100644 --- a/repos/os/src/server/nic_router/domain.h +++ b/repos/os/src/server/nic_router/domain.h @@ -22,6 +22,7 @@ #include #include #include +#include /* Genode includes */ #include @@ -128,9 +129,6 @@ class Net::Domain : public Domain_base Configuration &_config; Genode::Xml_node _node; Genode::Allocator &_alloc; - Ipv4_address_prefix _interface_attr; - Ipv4_address const _gateway; - bool const _gateway_valid; Ip_rule_list _ip_rules; Forward_rule_tree _tcp_forward_rules; Forward_rule_tree _udp_forward_rules; @@ -141,6 +139,7 @@ class Net::Domain : public Domain_base Nat_rule_tree _nat_rules; Pointer _interface; Pointer _dhcp_server; + Ipv4_config _ip_config; void _read_forward_rules(Genode::Cstring const &protocol, Domain_tree &domains, @@ -181,15 +180,14 @@ class Net::Domain : public Domain_base ** Accessors ** ***************/ - bool gateway_valid() const { return _gateway_valid; } - Domain_name const &name() { return _name; } + Ipv4_config const &ip_config() const { return _ip_config; } + Domain_name const &name() { 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; } Nat_rule_tree &nat_rules() { return _nat_rules; } - Ipv4_address_prefix &interface_attr() { return _interface_attr; } Pointer &interface() { return _interface; } Configuration &config() const { return _config; } Domain_avl_member &avl_member() { return _avl_member; } diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 1d550d9c4..a16900d91 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -399,11 +399,11 @@ void Interface::_send_dhcp_reply(Dhcp_server const &dhcp_srv, reply_dhcp_opts.append_option(msg_type); reply_dhcp_opts.append_option(_router_ip()); reply_dhcp_opts.append_option(dhcp_srv.ip_lease_time().value / 1000 / 1000); - reply_dhcp_opts.append_option(_domain.interface_attr().subnet_mask()); + reply_dhcp_opts.append_option(_ip_config().interface.subnet_mask()); reply_dhcp_opts.append_option(_router_ip()); if (dhcp_srv.dns_server().valid()) { reply_dhcp_opts.append_option(dhcp_srv.dns_server()); } - reply_dhcp_opts.append_option(_domain.interface_attr().broadcast_address()); + reply_dhcp_opts.append_option(_ip_config().interface.broadcast_address()); reply_dhcp_opts.append_option(); /* fill in header values that need the packet to be complete already */ @@ -723,7 +723,7 @@ void Interface::_handle_arp_reply(Arp_packet &arp) Ipv4_address const &Interface::_router_ip() const { - return _domain.interface_attr().address; + return _ip_config().interface.address; } @@ -739,8 +739,8 @@ void Interface::_handle_arp_request(Ethernet_frame ð, * attribute. */ if (arp.dst_ip() != _router_ip() && - (_domain.gateway_valid() || - _domain.interface_attr().prefix_matches(arp.dst_ip()))) + (_ip_config().gateway_valid || + _ip_config().interface.prefix_matches(arp.dst_ip()))) { if (_config().verbose()) { log("Ignore ARP request"); } @@ -913,7 +913,7 @@ Interface::Interface(Entrypoint &ep, log("Interface connected ", *this); log(" MAC ", _mac); log(" Router identity: MAC ", _router_mac, " IP ", - _router_ip(), "/", _domain.interface_attr().prefix); + _router_ip(), "/", _ip_config().interface.prefix); } _domain.interface().set(*this); } @@ -967,6 +967,9 @@ Interface::~Interface() Configuration &Interface::_config() const { return _domain.config(); } +Ipv4_config const &Interface::_ip_config() const { return _domain.ip_config(); } + + void Interface::print(Output &output) const { Genode::print(output, "\"", _domain.name(), "\""); diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 7c84efd33..f44990eb5 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -29,6 +29,7 @@ namespace Net { using Packet_descriptor = ::Nic::Packet_descriptor; using Packet_stream_sink = ::Nic::Packet_stream_sink< ::Nic::Session::Policy>; using Packet_stream_source = ::Nic::Packet_stream_source< ::Nic::Session::Policy>; + class Ipv4_config; class Forward_rule_tree; class Transport_rule_list; class Ethernet_frame; @@ -210,6 +211,8 @@ class Net::Interface Configuration &_config() const; + Ipv4_config const &_ip_config() const; + Ipv4_address const &_router_ip() const; void _handle_eth(void *const eth_base, diff --git a/repos/os/src/server/nic_router/ipv4_config.cc b/repos/os/src/server/nic_router/ipv4_config.cc new file mode 100644 index 000000000..c5e0f1d30 --- /dev/null +++ b/repos/os/src/server/nic_router/ipv4_config.cc @@ -0,0 +1,31 @@ +/* + * \brief IPv4 peer configuration + * \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. + */ + +/* Genode includes */ +#include + +/* local includes */ +#include + +using namespace Genode; +using namespace Net; + +Ipv4_config::Ipv4_config(Ipv4_address_prefix interface, + Ipv4_address gateway) +: + interface(interface), gateway(gateway) +{ + if (!valid && (interface_valid || gateway_valid)) { + error("Bad IP configuration"); + } +} diff --git a/repos/os/src/server/nic_router/ipv4_config.h b/repos/os/src/server/nic_router/ipv4_config.h new file mode 100644 index 000000000..148f85eee --- /dev/null +++ b/repos/os/src/server/nic_router/ipv4_config.h @@ -0,0 +1,38 @@ +/* + * \brief IPv4 peer configuration + * \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 _IPV4_CONFIG_H_ +#define _IPV4_CONFIG_H_ + +/* local includes */ +#include + +namespace Net { class Ipv4_config; } + +struct Net::Ipv4_config +{ + Ipv4_address_prefix const interface; + bool const interface_valid { interface.valid() }; + Ipv4_address const gateway; + bool const gateway_valid { gateway.valid() }; + bool const valid { interface_valid && + (!gateway_valid || + interface.prefix_matches(gateway)) }; + + Ipv4_config(Ipv4_address_prefix interface, + Ipv4_address gateway); + + Ipv4_config() { } +}; + +#endif /* _IPV4_CONFIG_H_ */ diff --git a/repos/os/src/server/nic_router/target.mk b/repos/os/src/server/nic_router/target.mk index 29e250bd3..5759c921b 100644 --- a/repos/os/src/server/nic_router/target.mk +++ b/repos/os/src/server/nic_router/target.mk @@ -4,7 +4,7 @@ LIBS += base net SRC_CC += arp_waiter.cc ip_rule.cc ipv4_address_prefix.cc SRC_CC += component.cc port_allocator.cc forward_rule.cc -SRC_CC += nat_rule.cc mac_allocator.cc main.cc +SRC_CC += nat_rule.cc mac_allocator.cc main.cc ipv4_config.cc SRC_CC += uplink.cc interface.cc arp_cache.cc configuration.cc SRC_CC += domain.cc l3_protocol.cc direct_rule.cc link.cc SRC_CC += transport_rule.cc leaf_rule.cc permit_rule.cc