nic_router: bind uplink session lifetime to domain

Normally, the NIC sessions are independent from the domain tags.
However, by now the uplink session, in contrast to the sessions of the
other domains, is still not a server but a client. This means that only
the NIC router itself can decide when to open and close uplink sessions
and how many. Thus, with this commit, we break with the pattern that
session lifetime is independent from domains by letting the NIC router
create the uplink session when the uplink domain appears and close the
session when the domain disappears.

Fixes #2795
This commit is contained in:
Martin Stein 2018-04-27 14:52:02 +02:00 committed by Christian Helmuth
parent 7085640f05
commit ce57319e4b

View File

@ -40,13 +40,15 @@ class Net::Main
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
Reference<Configuration> _config { _init_config() };
Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
Uplink _uplink { _env, _timer, _heap, _interfaces, _config() };
Pointer<Uplink> _uplink { };
Root _root { _env.ep(), _timer, _heap, _config(), _env.ram(), _interfaces, _env.rm()};
void _handle_config();
Configuration &_init_config();
void _try_init_uplink(Configuration &config);
template <typename FUNC>
void _for_each_interface(FUNC && functor)
{
@ -81,18 +83,40 @@ Configuration &Net::Main::_init_config()
Net::Main::Main(Env &env) : _env(env)
{
_uplink.init();
_try_init_uplink(_config());
_config_rom.sigh(_config_handler);
env.parent().announce(env.ep().manage(_root));
}
void Net::Main::_try_init_uplink(Configuration &config)
{
try {
config.domains().find_by_name("uplink");
Uplink &uplink = *new (_heap) Uplink(_env, _timer, _heap, _interfaces, config);
_uplink = Pointer<Uplink>(uplink);
uplink.init();
}
catch (Domain_tree::No_match) { }
}
void Net::Main::_handle_config()
{
_config_rom.update();
Configuration &config = *new (_heap)
Configuration(_env, _config_rom.xml(), _heap, _timer, _config());
try {
Uplink &uplink = _uplink();
try { config.domains().find_by_name("uplink"); }
catch (Domain_tree::No_match) {
destroy(_heap, &uplink);
_uplink = Pointer<Uplink>();
}
}
catch (Pointer<Uplink>::Invalid) { _try_init_uplink(config); }
_root.handle_config(config);
_for_each_interface([&] (Interface &intf) { intf.handle_config(config); });
_for_each_interface([&] (Interface &intf) { intf.handle_config_aftermath(); });