genode/repos/os/src/server/nic_router/main.cc

94 lines
2.5 KiB
C++
Raw Normal View History

/*
* \brief Server component for Network Address Translation on NIC sessions
* \author Martin Stein
* \date 2016-08-24
*/
/*
* 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 */
#include <base/component.h>
#include <base/heap.h>
#include <base/attached_rom_dataspace.h>
#include <nic/xml_node.h>
#include <timer_session/connection.h>
/* local includes */
#include "component.h"
#include "uplink.h"
#include "configuration.h"
using namespace Net;
using namespace Genode;
namespace Net { class Main; }
class Net::Main
{
private:
Genode::Env &_env;
Quota _shared_quota { };
Interface_list _interfaces { };
Timer::Connection _timer { _env };
Genode::Heap _heap { &_env.ram(), &_env.rm() };
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
Reference<Configuration> _config { *new (_heap) Configuration { _config_rom.xml(), _heap } };
Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
Root _root { _env, _timer, _heap, _config(), _shared_quota, _interfaces };
void _handle_config();
template <typename FUNC>
void _for_each_interface(FUNC && functor)
{
_interfaces.for_each([&] (Interface &interface) {
functor(interface);
});
_config().domains().for_each([&] (Domain &domain) {
domain.interfaces().for_each([&] (Interface &interface) {
functor(interface);
});
});
}
public:
Main(Env &env);
};
Net::Main::Main(Env &env) : _env(env)
{
_config_rom.sigh(_config_handler);
_handle_config();
env.parent().announce(env.ep().manage(_root));
}
void Net::Main::_handle_config()
{
_config_rom.update();
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
Configuration &old_config = _config();
Configuration &new_config = *new (_heap)
Configuration(_env, _config_rom.xml(), _heap, _timer, old_config,
_shared_quota, _interfaces);
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
_root.handle_config(new_config);
_for_each_interface([&] (Interface &intf) { intf.handle_config_1(new_config); });
_for_each_interface([&] (Interface &intf) { intf.handle_config_2(); });
_config = Reference<Configuration>(new_config);
_for_each_interface([&] (Interface &intf) { intf.handle_config_3(); });
destroy(_heap, &old_config);
}
void Component::construct(Env &env) { static Net::Main main(env); }