mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-13 15:56:32 +00:00
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
This commit is contained in:
parent
d4f08b5a71
commit
49a3a0e0d0
@ -125,8 +125,9 @@ append config {
|
|||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config dhcp_discover_timeout_sec="1">
|
<config dhcp_discover_timeout_sec="1">
|
||||||
<default-policy domain="downlink"/>
|
<default-policy domain="downlink"/>
|
||||||
<domain name="uplink" label="nic">
|
<uplink label="nic" domain="uplink" />
|
||||||
|
<domain name="uplink">
|
||||||
<nat domain="downlink" icmp-ids="999"/>
|
<nat domain="downlink" icmp-ids="999"/>
|
||||||
</domain>
|
</domain>
|
||||||
<domain name="downlink" interface="10.0.1.79/24">
|
<domain name="downlink" interface="10.0.1.79/24">
|
||||||
@ -140,8 +141,9 @@ append config {
|
|||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config dhcp_discover_timeout_sec="1">
|
<config dhcp_discover_timeout_sec="1">
|
||||||
<default-policy domain="downlink"/>
|
<default-policy domain="downlink"/>
|
||||||
<domain name="uplink" label="wifi">
|
<uplink label="wifi" domain="uplink" />
|
||||||
|
<domain name="uplink">
|
||||||
<nat domain="downlink" icmp-ids="999"/>
|
<nat domain="downlink" icmp-ids="999"/>
|
||||||
</domain>
|
</domain>
|
||||||
<domain name="downlink" interface="10.0.1.79/24">
|
<domain name="downlink" interface="10.0.1.79/24">
|
||||||
@ -167,8 +169,9 @@ append config {
|
|||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config dhcp_discover_timeout_sec="1">
|
<config dhcp_discover_timeout_sec="1">
|
||||||
<default-policy domain="downlink"/>
|
<default-policy domain="downlink"/>
|
||||||
<domain name="uplink" label="nic">
|
<uplink label="nic" domain="uplink" />
|
||||||
|
<domain name="uplink">
|
||||||
<nat domain="downlink" icmp-ids="999"/>
|
<nat domain="downlink" icmp-ids="999"/>
|
||||||
</domain>
|
</domain>
|
||||||
<domain name="downlink" interface="10.0.1.79/24">
|
<domain name="downlink" interface="10.0.1.79/24">
|
||||||
@ -182,8 +185,9 @@ append config {
|
|||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config dhcp_discover_timeout_sec="1">
|
<config dhcp_discover_timeout_sec="1">
|
||||||
<default-policy domain="downlink"/>
|
<default-policy domain="downlink"/>
|
||||||
<domain name="uplink" label="nic">
|
<uplink label="nic" domain="uplink" />
|
||||||
|
<domain name="uplink">
|
||||||
<nat domain="downlink" icmp-ids="999"/>
|
<nat domain="downlink" icmp-ids="999"/>
|
||||||
</domain>
|
</domain>
|
||||||
<domain name="downlink" interface="10.0.1.79/24">
|
<domain name="downlink" interface="10.0.1.79/24">
|
||||||
@ -209,8 +213,9 @@ append config {
|
|||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config dhcp_discover_timeout_sec="1">
|
<config dhcp_discover_timeout_sec="1">
|
||||||
<default-policy domain="downlink"/>
|
<default-policy domain="downlink"/>
|
||||||
<domain name="uplink" label="wifi">
|
<uplink label="wifi" domain="uplink" />
|
||||||
|
<domain name="uplink">
|
||||||
<nat domain="downlink" icmp-ids="999"/>
|
<nat domain="downlink" icmp-ids="999"/>
|
||||||
</domain>
|
</domain>
|
||||||
<domain name="downlink" interface="10.0.1.79/24">
|
<domain name="downlink" interface="10.0.1.79/24">
|
||||||
@ -224,8 +229,9 @@ append config {
|
|||||||
<inline>
|
<inline>
|
||||||
|
|
||||||
<config dhcp_discover_timeout_sec="1">
|
<config dhcp_discover_timeout_sec="1">
|
||||||
<default-policy domain="downlink"/>
|
<default-policy domain="downlink"/>
|
||||||
<domain name="uplink" label="nic">
|
<uplink label="nic" domain="uplink" />
|
||||||
|
<domain name="uplink">
|
||||||
<nat domain="downlink" icmp-ids="999"/>
|
<nat domain="downlink" icmp-ids="999"/>
|
||||||
</domain>
|
</domain>
|
||||||
<domain name="downlink" interface="10.0.1.79/24">
|
<domain name="downlink" interface="10.0.1.79/24">
|
||||||
|
@ -15,6 +15,24 @@
|
|||||||
#include <network.h>
|
#include <network.h>
|
||||||
|
|
||||||
|
|
||||||
|
void Sculpt::Network::_generate_nic_router_uplink(Xml_generator &xml,
|
||||||
|
char const *label)
|
||||||
|
{
|
||||||
|
xml.node("uplink", [&] () {
|
||||||
|
xml.attribute("label", label);
|
||||||
|
xml.attribute("domain", "uplink");
|
||||||
|
});
|
||||||
|
gen_named_node(xml, "domain", "uplink", [&] () {
|
||||||
|
xml.node("nat", [&] () {
|
||||||
|
xml.attribute("domain", "default");
|
||||||
|
xml.attribute("tcp-ports", "1000");
|
||||||
|
xml.attribute("udp-ports", "1000");
|
||||||
|
xml.attribute("icmp-ids", "1000");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sculpt::Network::handle_key_press(Codepoint code)
|
void Sculpt::Network::handle_key_press(Codepoint code)
|
||||||
{
|
{
|
||||||
enum { BACKSPACE = 8, ENTER = 10 };
|
enum { BACKSPACE = 8, ENTER = 10 };
|
||||||
@ -70,22 +88,12 @@ void Sculpt::Network::_generate_nic_router_config()
|
|||||||
xml.node("default-policy", [&] () {
|
xml.node("default-policy", [&] () {
|
||||||
xml.attribute("domain", "default"); });
|
xml.attribute("domain", "default"); });
|
||||||
|
|
||||||
if (_nic_target.type() != Nic_target::LOCAL) {
|
bool uplink_exists = true;
|
||||||
gen_named_node(xml, "domain", "uplink", [&] () {
|
switch (_nic_target.type()) {
|
||||||
switch (_nic_target.type()) {
|
case Nic_target::WIRED: _generate_nic_router_uplink(xml, "wired"); break;
|
||||||
case Nic_target::WIRED: xml.attribute("label", "wired"); break;
|
case Nic_target::WIFI: _generate_nic_router_uplink(xml, "wifi"); break;
|
||||||
case Nic_target::WIFI: xml.attribute("label", "wifi"); break;
|
default: uplink_exists = false;
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
xml.node("nat", [&] () {
|
|
||||||
xml.attribute("domain", "default");
|
|
||||||
xml.attribute("tcp-ports", "1000");
|
|
||||||
xml.attribute("udp-ports", "1000");
|
|
||||||
xml.attribute("icmp-ids", "1000");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_named_node(xml, "domain", "default", [&] () {
|
gen_named_node(xml, "domain", "default", [&] () {
|
||||||
xml.attribute("interface", "10.0.1.1/24");
|
xml.attribute("interface", "10.0.1.1/24");
|
||||||
|
|
||||||
@ -96,7 +104,7 @@ void Sculpt::Network::_generate_nic_router_config()
|
|||||||
xml.attribute("dns_server_from", "uplink"); }
|
xml.attribute("dns_server_from", "uplink"); }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_nic_target.type() != Nic_target::LOCAL) {
|
if (uplink_exists) {
|
||||||
xml.node("tcp", [&] () {
|
xml.node("tcp", [&] () {
|
||||||
xml.attribute("dst", "0.0.0.0/0");
|
xml.attribute("dst", "0.0.0.0/0");
|
||||||
xml.node("permit-any", [&] () {
|
xml.node("permit-any", [&] () {
|
||||||
@ -171,19 +179,31 @@ void Sculpt::Network::_handle_nic_router_config(Xml_node config)
|
|||||||
if (!config.has_sub_node("domain"))
|
if (!config.has_sub_node("domain"))
|
||||||
target = Nic_target::OFF;
|
target = Nic_target::OFF;
|
||||||
|
|
||||||
config.for_each_sub_node("domain", [&] (Xml_node domain) {
|
struct Break : Exception { };
|
||||||
|
try {
|
||||||
|
config.for_each_sub_node("domain", [&] (Xml_node domain) {
|
||||||
|
|
||||||
/* skip non-uplink domains */
|
/* skip domains that are not called "uplink" */
|
||||||
if (domain.attribute_value("name", String<16>()) != "uplink")
|
if (domain.attribute_value("name", String<16>()) != "uplink")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (domain.attribute_value("label", String<16>()) == "wired")
|
config.for_each_sub_node("uplink", [&] (Xml_node uplink) {
|
||||||
target = Nic_target::WIRED;
|
|
||||||
|
|
||||||
if (domain.attribute_value("label", String<16>()) == "wifi")
|
/* skip uplinks not assigned to a domain called "uplink" */
|
||||||
target = Nic_target::WIFI;
|
if (uplink.attribute_value("domain", String<16>()) != "uplink")
|
||||||
});
|
return;
|
||||||
|
|
||||||
|
if (uplink.attribute_value("label", String<16>()) == "wired") {
|
||||||
|
target = Nic_target::WIRED;
|
||||||
|
throw Break();
|
||||||
|
}
|
||||||
|
if (uplink.attribute_value("label", String<16>()) == "wifi") {
|
||||||
|
target = Nic_target::WIFI;
|
||||||
|
throw Break();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (Break) { }
|
||||||
_nic_target.manual_type = target;
|
_nic_target.manual_type = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,9 @@ struct Sculpt::Network : Network_dialog::Action
|
|||||||
|
|
||||||
void _generate_nic_router_config();
|
void _generate_nic_router_config();
|
||||||
|
|
||||||
|
void _generate_nic_router_uplink(Xml_generator &xml,
|
||||||
|
char const *label);
|
||||||
|
|
||||||
Access_points _access_points { };
|
Access_points _access_points { };
|
||||||
|
|
||||||
Wifi_connection _wifi_connection = Wifi_connection::disconnected_wifi_connection();
|
Wifi_connection _wifi_connection = Wifi_connection::disconnected_wifi_connection();
|
||||||
|
@ -88,6 +88,7 @@ append config {
|
|||||||
<policy label_prefix="http_server_2" domain="http_server_2" />
|
<policy label_prefix="http_server_2" domain="http_server_2" />
|
||||||
<policy label_prefix="udp_server_1" domain="udp_server_1" />
|
<policy label_prefix="udp_server_1" domain="udp_server_1" />
|
||||||
<policy label_prefix="udp_server_2" domain="udp_server_2" />
|
<policy label_prefix="udp_server_2" domain="udp_server_2" />
|
||||||
|
<uplink domain="uplink" />
|
||||||
|
|
||||||
<domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1">
|
<domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1">
|
||||||
<tcp-forward port="80" domain="http_server_1" to="192.168.1.18" />
|
<tcp-forward port="80" domain="http_server_1" to="192.168.1.18" />
|
||||||
|
@ -158,6 +158,7 @@ proc test_7_config { } {
|
|||||||
<config>
|
<config>
|
||||||
|
|
||||||
<policy label_prefix="lan_2" domain="downlink" />
|
<policy label_prefix="lan_2" domain="downlink" />
|
||||||
|
<uplink domain="uplink" />
|
||||||
|
|
||||||
<domain name="uplink">
|
<domain name="uplink">
|
||||||
<nat domain="downlink" tcp-ports="6" />
|
<nat domain="downlink" tcp-ports="6" />
|
||||||
@ -260,6 +261,8 @@ append config {
|
|||||||
|
|
||||||
<report bytes="yes" config="yes" interval_sec="60" />
|
<report bytes="yes" config="yes" interval_sec="60" />
|
||||||
|
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink"
|
<domain name="uplink"
|
||||||
interface="10.0.2.55/24"
|
interface="10.0.2.55/24"
|
||||||
gateway="10.0.2.1"
|
gateway="10.0.2.1"
|
||||||
|
@ -230,6 +230,8 @@ append config {
|
|||||||
|
|
||||||
<report/>
|
<report/>
|
||||||
|
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink"
|
<domain name="uplink"
|
||||||
interface="10.0.2.55/24"
|
interface="10.0.2.55/24"
|
||||||
gateway="10.0.2.1"
|
gateway="10.0.2.1"
|
||||||
@ -266,6 +268,8 @@ append config {
|
|||||||
tcp_idle_timeout_sec="30"
|
tcp_idle_timeout_sec="30"
|
||||||
tcp_max_segm_lifetime_sec="15">
|
tcp_max_segm_lifetime_sec="15">
|
||||||
|
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink"
|
<domain name="uplink"
|
||||||
interface="10.0.2.55/24"
|
interface="10.0.2.55/24"
|
||||||
gateway="10.0.2.1"
|
gateway="10.0.2.1"
|
||||||
@ -306,6 +310,8 @@ append config {
|
|||||||
|
|
||||||
<report interval_sec="2" bytes="yes" config="no" />
|
<report interval_sec="2" bytes="yes" config="no" />
|
||||||
|
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink"
|
<domain name="uplink"
|
||||||
interface="10.0.2.55/24"
|
interface="10.0.2.55/24"
|
||||||
gateway="10.0.2.1"
|
gateway="10.0.2.1"
|
||||||
@ -338,6 +344,8 @@ append config {
|
|||||||
|
|
||||||
<report interval_sec="2" bytes="yes" config="no" />
|
<report interval_sec="2" bytes="yes" config="no" />
|
||||||
|
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink"
|
<domain name="uplink"
|
||||||
interface="10.0.2.55/24"
|
interface="10.0.2.55/24"
|
||||||
gateway="10.0.2.1"
|
gateway="10.0.2.1"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
<config verbose_domain_state="yes">
|
<config verbose_domain_state="yes">
|
||||||
<default-policy domain="default" />
|
<default-policy domain="default" />
|
||||||
|
<uplink domain="uplink" />
|
||||||
<domain name="uplink">
|
<domain name="uplink">
|
||||||
<nat domain="default"
|
<nat domain="default"
|
||||||
tcp-ports="1000"
|
tcp-ports="1000"
|
||||||
|
@ -93,6 +93,7 @@ append config {
|
|||||||
|
|
||||||
<policy label_prefix="flood_links" domain="flood_links"/>
|
<policy label_prefix="flood_links" domain="flood_links"/>
|
||||||
<policy label_prefix="ping" domain="flood_links"/>
|
<policy label_prefix="ping" domain="flood_links"/>
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink" verbose_packets="no">
|
<domain name="uplink" verbose_packets="no">
|
||||||
<nat domain="flood_links" udp-ports="16384"
|
<nat domain="flood_links" udp-ports="16384"
|
||||||
|
@ -98,6 +98,7 @@ append config {
|
|||||||
|
|
||||||
<policy label_prefix="ping_1" domain="ping_1"/>
|
<policy label_prefix="ping_1" domain="ping_1"/>
|
||||||
<policy label_prefix="ping_2" domain="ping_2"/>
|
<policy label_prefix="ping_2" domain="ping_2"/>
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink">
|
<domain name="uplink">
|
||||||
<nat domain="ping_1" icmp-ids="100"/>
|
<nat domain="ping_1" icmp-ids="100"/>
|
||||||
@ -131,6 +132,7 @@ append config {
|
|||||||
icmp_idle_timeout_sec="10">
|
icmp_idle_timeout_sec="10">
|
||||||
|
|
||||||
<policy label_prefix="ping_2" domain="ping_2"/>
|
<policy label_prefix="ping_2" domain="ping_2"/>
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink" interface="10.0.4.2/24" gateway="10.0.4.1">
|
<domain name="uplink" interface="10.0.4.2/24" gateway="10.0.4.1">
|
||||||
<nat domain="ping_2" icmp-ids="100" udp-ports="100"/>
|
<nat domain="ping_2" icmp-ids="100" udp-ports="100"/>
|
||||||
|
@ -19,22 +19,35 @@ these domains. This is a brief overview of the features thereby provided:
|
|||||||
Basics
|
Basics
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
The 'nic_router' component provides multiple sessions of the 'NIC' service
|
The NIC router can act as server of multiple NIC session clients (downlinks)
|
||||||
(downlinks) while requesting one 'NIC' session (the uplink) itself. Through
|
and at the same time as client of multiple NIC session servers (uplinks).
|
||||||
common Genode session routing, the uplink can be connected to any other NIC
|
Besides the decision which side initiates the NIC session and provides MAC
|
||||||
server. Inside the component, uplink and downlinks are treated the same. Its
|
address respectively link state, uplinks and downlinks are equal to the NIC
|
||||||
routing algorithm is ultimately controlled through the configuration. NIC
|
router.
|
||||||
|
|
||||||
|
The routing algorithm is ultimately controlled through the configuration. NIC
|
||||||
sessions are assigned to domains. Each domain represents one subnet and a
|
sessions are assigned to domains. Each domain represents one subnet and a
|
||||||
corresponding routing configuration. Currently, each domain can contain
|
corresponding routing configuration. The assignment of downlink NIC sessions
|
||||||
only one NIC session at a time. The assignment of sessions to domains is
|
to domains is controlled through the policy tag that is also known from other
|
||||||
controlled through the the common Genode session-policy tag:
|
Genode components:
|
||||||
|
|
||||||
! <policy label_prefix="http_server" domain="http_servers" />
|
! <policy label_prefix="vlan_" domain="vlan" />
|
||||||
! <policy label_prefix="imap_server" domain="imap_servers" />
|
! <policy label_suffix="_server" domain="servers" />
|
||||||
|
! <policy label="nic_bridge_1" domain="wired_bridge" />
|
||||||
|
! <policy label="nic_bridge_2" domain="wired_bridge" />
|
||||||
|
|
||||||
The domain name can be freely choosen but must be unique. There is no need
|
The domain name can be freely choosen but must be unique.
|
||||||
to have a policy for the uplink. It is automatically assigned to the domain
|
The uplink tag instructs the NIC router to create an uplink NIC session that
|
||||||
named "uplink". For each domain there must be a domain tag:
|
is assigned to the give domain:
|
||||||
|
|
||||||
|
! <uplink domain="wired_bridge" />
|
||||||
|
! <uplink label="wired" domain="wired_bridge" />
|
||||||
|
! <uplink label="wifi" domain="wifi_uplink" />
|
||||||
|
|
||||||
|
The label is the session label that is used when requesting the uplink NIC
|
||||||
|
session. The label attribute is optional. It is perfectly fine to have a
|
||||||
|
domain with uplinks and downlinks assigned to at the same time. For each
|
||||||
|
domain there must be a domain tag:
|
||||||
|
|
||||||
! <domain name="uplink" interface="10.0.2.55/24" />
|
! <domain name="uplink" interface="10.0.2.55/24" />
|
||||||
! <domain name="http_servers" interface="192.168.1.18/24" />
|
! <domain name="http_servers" interface="192.168.1.18/24" />
|
||||||
@ -411,27 +424,6 @@ router:
|
|||||||
! dhcp_request_timeout_sec="6">
|
! dhcp_request_timeout_sec="6">
|
||||||
|
|
||||||
|
|
||||||
The uplink domain
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The uplink domain is treated like every other domain wherever possible.
|
|
||||||
However, there are still some differences that are visible to the user:
|
|
||||||
|
|
||||||
* 'policy' tags that target the uplink domain have no effect at all
|
|
||||||
* The domain tag of the uplink is the only domain tag in which the
|
|
||||||
'label' attribute has an effect
|
|
||||||
* The uplink domain, as long as existant, has exactly one NIC session in which
|
|
||||||
the NIC router is the session client
|
|
||||||
* When the uplink 'domain' tag appears, the uplink NIC session is requested by
|
|
||||||
the NIC router using the label denoted in the 'label' attribute of the
|
|
||||||
uplink 'domain' tag (default label "")
|
|
||||||
* When the 'label' attribute of the uplink 'domain' tag changes, the NIC
|
|
||||||
router closes the uplink NIC session and requests it again with the new
|
|
||||||
label
|
|
||||||
* When the uplink 'domain' tag disappears, the NIC router closes the uplink
|
|
||||||
NIC session
|
|
||||||
|
|
||||||
|
|
||||||
Configuring reporting functionality
|
Configuring reporting functionality
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -511,6 +503,7 @@ following configuration:
|
|||||||
|
|
||||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||||
|
! <uplink domain="uplink" />
|
||||||
!
|
!
|
||||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1/24">
|
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1/24">
|
||||||
! <ip dst="192.168.1.0/24" domain="virtnet_a"/>
|
! <ip dst="192.168.1.0/24" domain="virtnet_a"/>
|
||||||
@ -550,6 +543,7 @@ internet. The router would have the following configuration:
|
|||||||
|
|
||||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||||
|
! <uplink domain="uplink" />
|
||||||
!
|
!
|
||||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1/24">
|
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1/24">
|
||||||
! <nat domain="virtnet_a" tcp_ports="1000" udp_ports="1000">
|
! <nat domain="virtnet_a" tcp_ports="1000" udp_ports="1000">
|
||||||
@ -588,6 +582,7 @@ following configuration:
|
|||||||
|
|
||||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||||
|
! <uplink domain="uplink" />
|
||||||
!
|
!
|
||||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1">
|
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1">
|
||||||
! <tcp-forward port="80" domain="virtnet_a" to="192.168.1.2" />
|
! <tcp-forward port="80" domain="virtnet_a" to="192.168.1.2" />
|
||||||
|
@ -101,6 +101,8 @@ Net::Session_component::Session_component(Allocator &alloc,
|
|||||||
config, interfaces, *_tx.sink(), *_rx.source(),
|
config, interfaces, *_tx.sink(), *_rx.source(),
|
||||||
_link_state, _interface_policy }
|
_link_state, _interface_policy }
|
||||||
{
|
{
|
||||||
|
_interface.attach_to_domain();
|
||||||
|
|
||||||
_tx.sigh_ready_to_ack (_interface.sink_ack());
|
_tx.sigh_ready_to_ack (_interface.sink_ack());
|
||||||
_tx.sigh_packet_avail (_interface.sink_submit());
|
_tx.sigh_packet_avail (_interface.sink_submit());
|
||||||
_rx.sigh_ack_avail (_interface.source_ack());
|
_rx.sigh_ack_avail (_interface.source_ack());
|
||||||
|
@ -112,6 +112,13 @@
|
|||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element><!-- policy -->
|
</xs:element><!-- policy -->
|
||||||
|
|
||||||
|
<xs:element name="uplink">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="label" type="Session_label" />
|
||||||
|
<xs:attribute name="domain" type="Domain_name" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element><!-- uplink -->
|
||||||
|
|
||||||
<xs:element name="domain">
|
<xs:element name="domain">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
@ -35,6 +35,17 @@ Configuration::Configuration(Xml_node const node,
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
void Configuration::_invalid_uplink(Uplink &uplink,
|
||||||
|
char const *reason)
|
||||||
|
{
|
||||||
|
if (_verbose) {
|
||||||
|
log("[", uplink.domain(), "] invalid uplink: ", uplink, " (", reason, ")"); }
|
||||||
|
|
||||||
|
_uplinks.remove(uplink);
|
||||||
|
destroy(_alloc, &uplink);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Configuration::_invalid_domain(Domain &domain,
|
void Configuration::_invalid_domain(Domain &domain,
|
||||||
char const *reason)
|
char const *reason)
|
||||||
{
|
{
|
||||||
@ -50,7 +61,8 @@ Configuration::Configuration(Env &env,
|
|||||||
Xml_node const node,
|
Xml_node const node,
|
||||||
Allocator &alloc,
|
Allocator &alloc,
|
||||||
Timer::Connection &timer,
|
Timer::Connection &timer,
|
||||||
Configuration &old_config)
|
Configuration &old_config,
|
||||||
|
Interface_list &interfaces)
|
||||||
:
|
:
|
||||||
_alloc(alloc),
|
_alloc(alloc),
|
||||||
_verbose (node.attribute_value("verbose", false)),
|
_verbose (node.attribute_value("verbose", false)),
|
||||||
@ -129,11 +141,35 @@ Configuration::Configuration(Env &env,
|
|||||||
Report(report_node, timer, _domains, _reporter());
|
Report(report_node, timer, _domains, _reporter());
|
||||||
}
|
}
|
||||||
catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
||||||
|
|
||||||
|
/* initialize uplinks */
|
||||||
|
_node.for_each_sub_node("uplink", [&] (Xml_node const node) {
|
||||||
|
try {
|
||||||
|
Uplink &uplink = *new (_alloc)
|
||||||
|
Uplink { node, alloc, old_config._uplinks, env, timer,
|
||||||
|
interfaces, *this };
|
||||||
|
|
||||||
|
try { _uplinks.insert(uplink); }
|
||||||
|
catch (Uplink_tree::Name_not_unique exception) {
|
||||||
|
_invalid_uplink(uplink, "label not unique");
|
||||||
|
_invalid_uplink(exception.object, "label not unique");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Uplink::Invalid) { }
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
* Destroy old uplinks to ensure that uplink interfaces that were not
|
||||||
|
* re-used are not re-attached to the new domains.
|
||||||
|
*/
|
||||||
|
old_config._uplinks.destroy_each(_alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Configuration::~Configuration()
|
Configuration::~Configuration()
|
||||||
{
|
{
|
||||||
|
/* destroy uplinks */
|
||||||
|
_uplinks.destroy_each(_alloc);
|
||||||
|
|
||||||
/* destroy reporter */
|
/* destroy reporter */
|
||||||
try { destroy(_alloc, &_reporter()); }
|
try { destroy(_alloc, &_reporter()); }
|
||||||
catch (Pointer<Reporter>::Invalid) { }
|
catch (Pointer<Reporter>::Invalid) { }
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
/* local includes */
|
/* local includes */
|
||||||
#include <domain.h>
|
#include <domain.h>
|
||||||
#include <report.h>
|
#include <report.h>
|
||||||
|
#include <uplink.h>
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <os/duration.h>
|
#include <os/duration.h>
|
||||||
@ -46,8 +47,12 @@ class Net::Configuration
|
|||||||
Pointer<Report> _report { };
|
Pointer<Report> _report { };
|
||||||
Pointer<Genode::Reporter> _reporter { };
|
Pointer<Genode::Reporter> _reporter { };
|
||||||
Domain_tree _domains { };
|
Domain_tree _domains { };
|
||||||
|
Uplink_tree _uplinks { };
|
||||||
Genode::Xml_node const _node;
|
Genode::Xml_node const _node;
|
||||||
|
|
||||||
|
void _invalid_uplink(Uplink &uplink,
|
||||||
|
char const *reason);
|
||||||
|
|
||||||
void _invalid_domain(Domain &domain,
|
void _invalid_domain(Domain &domain,
|
||||||
char const *reason);
|
char const *reason);
|
||||||
|
|
||||||
@ -69,7 +74,8 @@ class Net::Configuration
|
|||||||
Genode::Xml_node const node,
|
Genode::Xml_node const node,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Timer::Connection &timer,
|
Timer::Connection &timer,
|
||||||
Configuration &old_config);
|
Configuration &old_config,
|
||||||
|
Interface_list &interfaces);
|
||||||
|
|
||||||
~Configuration();
|
~Configuration();
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ using Genode::uint32_t;
|
|||||||
using Genode::log;
|
using Genode::log;
|
||||||
using Genode::error;
|
using Genode::error;
|
||||||
using Genode::warning;
|
using Genode::warning;
|
||||||
|
using Genode::Exception;
|
||||||
using Genode::construct_at;
|
using Genode::construct_at;
|
||||||
using Genode::Quota_guard;
|
using Genode::Quota_guard;
|
||||||
using Genode::Ram_quota;
|
using Genode::Ram_quota;
|
||||||
@ -256,15 +257,23 @@ void Interface::_detach_from_domain_raw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Interface::_attach_to_domain(Domain_name const &domain_name)
|
void Interface::attach_to_domain()
|
||||||
{
|
{
|
||||||
_attach_to_domain_raw(_config().domains().find_by_name(domain_name));
|
try {
|
||||||
attach_to_domain_finish();
|
_attach_to_domain_raw(_config().domains().find_by_name(
|
||||||
|
_policy.determine_domain_name()));
|
||||||
|
|
||||||
|
attach_to_domain_finish();
|
||||||
|
}
|
||||||
|
catch (Domain_tree::No_match) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Interface::attach_to_domain_finish()
|
void Interface::attach_to_domain_finish()
|
||||||
{
|
{
|
||||||
|
if (!link_state()) {
|
||||||
|
return; }
|
||||||
|
|
||||||
/* if domain has yet no IP config, participate in requesting one */
|
/* if domain has yet no IP config, participate in requesting one */
|
||||||
Domain &domain = _domain();
|
Domain &domain = _domain();
|
||||||
Ipv4_config const &ip_config = domain.ip_config();
|
Ipv4_config const &ip_config = domain.ip_config();
|
||||||
@ -764,6 +773,27 @@ bool Interface::link_state() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Interface::handle_link_state()
|
||||||
|
{
|
||||||
|
struct Keep_ip_config : Exception { };
|
||||||
|
try {
|
||||||
|
attach_to_domain_finish();
|
||||||
|
|
||||||
|
/* if the wholde domain became down, discard IP config */
|
||||||
|
Domain &domain_ = domain();
|
||||||
|
if (!link_state() && domain_.ip_config().valid) {
|
||||||
|
domain_.interfaces().for_each([&] (Interface &interface) {
|
||||||
|
if (interface.link_state()) {
|
||||||
|
throw Keep_ip_config(); }
|
||||||
|
});
|
||||||
|
domain_.discard_ip_config();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Domain::Ip_config_static) { }
|
||||||
|
catch (Keep_ip_config) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Interface::_handle_icmp_query(Ethernet_frame ð,
|
void Interface::_handle_icmp_query(Ethernet_frame ð,
|
||||||
Size_guard &size_guard,
|
Size_guard &size_guard,
|
||||||
Ipv4_packet &ip,
|
Ipv4_packet &ip,
|
||||||
@ -1383,8 +1413,6 @@ Interface::Interface(Genode::Entrypoint &ep,
|
|||||||
_interfaces { interfaces }
|
_interfaces { interfaces }
|
||||||
{
|
{
|
||||||
_interfaces.insert(this);
|
_interfaces.insert(this);
|
||||||
try { _attach_to_domain(_policy.determine_domain_name()); }
|
|
||||||
catch (Domain_tree::No_match) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,8 +274,6 @@ class Net::Interface : private Interface_list::Element
|
|||||||
|
|
||||||
void _detach_from_domain();
|
void _detach_from_domain();
|
||||||
|
|
||||||
void _attach_to_domain(Domain_name const &domain_name);
|
|
||||||
|
|
||||||
void _attach_to_domain_raw(Domain &domain);
|
void _attach_to_domain_raw(Domain &domain);
|
||||||
|
|
||||||
void _apply_foreign_arp();
|
void _apply_foreign_arp();
|
||||||
@ -375,6 +373,8 @@ class Net::Interface : private Interface_list::Element
|
|||||||
|
|
||||||
void handle_config_3();
|
void handle_config_3();
|
||||||
|
|
||||||
|
void attach_to_domain();
|
||||||
|
|
||||||
void detach_from_ip_config();
|
void detach_from_ip_config();
|
||||||
|
|
||||||
void attach_to_ip_config(Domain &domain,
|
void attach_to_ip_config(Domain &domain,
|
||||||
@ -388,6 +388,8 @@ class Net::Interface : private Interface_list::Element
|
|||||||
|
|
||||||
bool link_state() const;
|
bool link_state() const;
|
||||||
|
|
||||||
|
void handle_link_state();
|
||||||
|
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
** Accessors **
|
** Accessors **
|
||||||
|
@ -38,22 +38,12 @@ class Net::Main
|
|||||||
Timer::Connection _timer { _env };
|
Timer::Connection _timer { _env };
|
||||||
Genode::Heap _heap { &_env.ram(), &_env.rm() };
|
Genode::Heap _heap { &_env.ram(), &_env.rm() };
|
||||||
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
|
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
|
||||||
Reference<Configuration> _config { _init_config() };
|
Reference<Configuration> _config { *new (_heap) Configuration { _config_rom.xml(), _heap } };
|
||||||
Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
|
Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
|
||||||
Pointer<Uplink> _uplink { };
|
|
||||||
Root _root { _env.ep(), _timer, _heap, _config(), _env.ram(), _interfaces, _env.rm()};
|
Root _root { _env.ep(), _timer, _heap, _config(), _env.ram(), _interfaces, _env.rm()};
|
||||||
|
|
||||||
void _handle_config();
|
void _handle_config();
|
||||||
|
|
||||||
Configuration &_init_config();
|
|
||||||
|
|
||||||
void _deinit_uplink(Configuration &config);
|
|
||||||
|
|
||||||
void _init_uplink(Configuration &config,
|
|
||||||
Session_label const &label);
|
|
||||||
|
|
||||||
void _uplink_handle_config(Configuration &config);
|
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
void _for_each_interface(FUNC && functor)
|
void _for_each_interface(FUNC && functor)
|
||||||
{
|
{
|
||||||
@ -73,80 +63,22 @@ class Net::Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Configuration &Net::Main::_init_config()
|
|
||||||
{
|
|
||||||
Configuration &dummy_config = *new (_heap)
|
|
||||||
Configuration(_config_rom.xml(), _heap);
|
|
||||||
|
|
||||||
Configuration &config = *new (_heap)
|
|
||||||
Configuration(_env, _config_rom.xml(), _heap, _timer, dummy_config);
|
|
||||||
|
|
||||||
destroy(_heap, &dummy_config);
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Net::Main::Main(Env &env) : _env(env)
|
Net::Main::Main(Env &env) : _env(env)
|
||||||
{
|
{
|
||||||
_uplink_handle_config(_config());
|
|
||||||
_config_rom.sigh(_config_handler);
|
_config_rom.sigh(_config_handler);
|
||||||
|
_handle_config();
|
||||||
env.parent().announce(env.ep().manage(_root));
|
env.parent().announce(env.ep().manage(_root));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Net::Main::_init_uplink(Configuration &config,
|
|
||||||
Session_label const &label)
|
|
||||||
{
|
|
||||||
if (config.verbose()) {
|
|
||||||
log("[uplink] request NIC session \"", label, "\""); }
|
|
||||||
|
|
||||||
Uplink &uplink = *new (_heap) Uplink(_env, _timer, _heap, _interfaces,
|
|
||||||
config, label);
|
|
||||||
_uplink = Pointer<Uplink>(uplink);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Net::Main::_deinit_uplink(Configuration &config)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Uplink &uplink = _uplink();
|
|
||||||
if (config.verbose()) {
|
|
||||||
log("[uplink] close NIC session \"", uplink.label(), "\""); }
|
|
||||||
|
|
||||||
destroy(_heap, &uplink);
|
|
||||||
_uplink = Pointer<Uplink>();
|
|
||||||
}
|
|
||||||
catch (Pointer<Uplink>::Invalid) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Net::Main::_uplink_handle_config(Configuration &config)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Session_label const &label =
|
|
||||||
config.domains().find_by_name("uplink").label();
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (label == _uplink().label()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_deinit_uplink(config);
|
|
||||||
_init_uplink(config, label);
|
|
||||||
}
|
|
||||||
catch (Pointer<Uplink>::Invalid) { _init_uplink(config, label); }
|
|
||||||
}
|
|
||||||
catch (Domain_tree::No_match) { _deinit_uplink(config); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Net::Main::_handle_config()
|
void Net::Main::_handle_config()
|
||||||
{
|
{
|
||||||
_config_rom.update();
|
_config_rom.update();
|
||||||
Configuration &old_config = _config();
|
Configuration &old_config = _config();
|
||||||
Configuration &new_config = *new (_heap)
|
Configuration &new_config = *new (_heap)
|
||||||
Configuration(_env, _config_rom.xml(), _heap, _timer, old_config);
|
Configuration(_env, _config_rom.xml(), _heap, _timer, old_config,
|
||||||
|
_interfaces);
|
||||||
|
|
||||||
_uplink_handle_config(new_config);
|
|
||||||
_root.handle_config(new_config);
|
_root.handle_config(new_config);
|
||||||
_for_each_interface([&] (Interface &intf) { intf.handle_config_1(new_config); });
|
_for_each_interface([&] (Interface &intf) { intf.handle_config_1(new_config); });
|
||||||
_for_each_interface([&] (Interface &intf) { intf.handle_config_2(); });
|
_for_each_interface([&] (Interface &intf) { intf.handle_config_2(); });
|
||||||
@ -157,12 +89,4 @@ void Net::Main::_handle_config()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Env &env)
|
void Component::construct(Env &env) { static Net::Main main(env); }
|
||||||
{
|
|
||||||
try { static Net::Main main(env); }
|
|
||||||
|
|
||||||
catch (Net::Domain_tree::No_match) {
|
|
||||||
error("failed to find configuration for domain 'uplink'");
|
|
||||||
env.parent().exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <net/ethernet.h>
|
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <uplink.h>
|
#include <uplink.h>
|
||||||
@ -23,20 +22,111 @@ using namespace Net;
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
Net::Uplink::Uplink(Env &env,
|
/*****************
|
||||||
Timer::Connection &timer,
|
** Uplink_base **
|
||||||
Genode::Allocator &alloc,
|
*****************/
|
||||||
Interface_list &interfaces,
|
|
||||||
Configuration &config,
|
Net::Uplink_base::Uplink_base(Xml_node const &node)
|
||||||
Session_label const &label)
|
|
||||||
:
|
:
|
||||||
|
_label { node.attribute_value("label", Session_label::String()) },
|
||||||
|
_domain { node.attribute_value("domain", Domain_name()) }
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/************
|
||||||
|
** Uplink **
|
||||||
|
************/
|
||||||
|
|
||||||
|
void Uplink::_invalid(char const *reason) const
|
||||||
|
{
|
||||||
|
if (_config.verbose()) {
|
||||||
|
log("[", domain(), "] invalid uplink: ", *this, " (", reason, ")"); }
|
||||||
|
|
||||||
|
throw Invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Net::Uplink::Uplink(Xml_node const &node,
|
||||||
|
Allocator &alloc,
|
||||||
|
Uplink_tree &old_uplinks,
|
||||||
|
Env &env,
|
||||||
|
Timer::Connection &timer,
|
||||||
|
Interface_list &interfaces,
|
||||||
|
Configuration &config)
|
||||||
|
:
|
||||||
|
Uplink_base { node },
|
||||||
|
Avl_string_base { label().string() },
|
||||||
|
_alloc { alloc },
|
||||||
|
_config { config }
|
||||||
|
{
|
||||||
|
/* if an interface with this label already exists, reuse it */
|
||||||
|
try {
|
||||||
|
Uplink &old_uplink = old_uplinks.find_by_name(label());
|
||||||
|
Uplink_interface &interface = old_uplink._interface();
|
||||||
|
old_uplink._interface = Pointer<Uplink_interface>();
|
||||||
|
interface.domain_name(domain());
|
||||||
|
_interface = interface;
|
||||||
|
}
|
||||||
|
/* if not, create a new one */
|
||||||
|
catch (Uplink_tree::No_match) {
|
||||||
|
if (config.verbose()) {
|
||||||
|
log("[", domain(), "] request uplink NIC session: ", *this); }
|
||||||
|
|
||||||
|
try {
|
||||||
|
_interface = *new (_alloc)
|
||||||
|
Uplink_interface { env, timer, alloc, interfaces, config,
|
||||||
|
domain(), label() };
|
||||||
|
}
|
||||||
|
catch (Insufficient_ram_quota) { _invalid("NIC session RAM quota"); }
|
||||||
|
catch (Insufficient_cap_quota) { _invalid("NIC session CAP quota"); }
|
||||||
|
catch (Service_denied) { _invalid("NIC session denied"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Net::Uplink::~Uplink()
|
||||||
|
{
|
||||||
|
/* if the interface was yet not reused by another uplink, destroy it */
|
||||||
|
try {
|
||||||
|
Uplink_interface &interface = _interface();
|
||||||
|
if (_config.verbose()) {
|
||||||
|
log("[", domain(), "] close uplink NIC session: ", *this); }
|
||||||
|
|
||||||
|
destroy(_alloc, &interface);
|
||||||
|
}
|
||||||
|
catch (Pointer<Uplink_interface>::Invalid) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Net::Uplink::print(Output &output) const
|
||||||
|
{
|
||||||
|
if (label() == Session_label()) {
|
||||||
|
Genode::print(output, "<unlabeled>"); }
|
||||||
|
else {
|
||||||
|
Genode::print(output, label()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
** Uplink_interface **
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
Net::Uplink_interface::Uplink_interface(Env &env,
|
||||||
|
Timer::Connection &timer,
|
||||||
|
Genode::Allocator &alloc,
|
||||||
|
Interface_list &interfaces,
|
||||||
|
Configuration &config,
|
||||||
|
Domain_name const &domain_name,
|
||||||
|
Session_label const &label)
|
||||||
|
:
|
||||||
|
Uplink_interface_base { domain_name },
|
||||||
Nic::Packet_allocator { &alloc },
|
Nic::Packet_allocator { &alloc },
|
||||||
Nic::Connection { env, this, BUF_SIZE, BUF_SIZE, label.string() },
|
Nic::Connection { env, this, BUF_SIZE, BUF_SIZE, label.string() },
|
||||||
_label { label },
|
_link_state_handler { env.ep(), *this,
|
||||||
_link_state_handler { env.ep(), *this, &Uplink::_handle_link_state },
|
&Uplink_interface::_handle_link_state },
|
||||||
_interface { env.ep(), timer, mac_address(), alloc,
|
_interface { env.ep(), timer, mac_address(), alloc,
|
||||||
Mac_address(), config, interfaces, *rx(), *tx(),
|
Mac_address(), config, interfaces, *rx(), *tx(),
|
||||||
_link_state, _intf_policy }
|
_link_state, *this }
|
||||||
{
|
{
|
||||||
/* install packet stream signal handlers */
|
/* install packet stream signal handlers */
|
||||||
rx_channel()->sigh_ready_to_ack (_interface.sink_ack());
|
rx_channel()->sigh_ready_to_ack (_interface.sink_ack());
|
||||||
@ -50,9 +140,8 @@ Net::Uplink::Uplink(Env &env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Net::Uplink::_handle_link_state()
|
void Net::Uplink_interface::_handle_link_state()
|
||||||
{
|
{
|
||||||
_link_state = link_state();
|
_link_state = link_state();
|
||||||
try { _interface.domain().discard_ip_config(); }
|
_interface.handle_link_state();
|
||||||
catch (Domain::Ip_config_static) { }
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <nic/packet_allocator.h>
|
#include <nic/packet_allocator.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
|
#include <avl_string_tree.h>
|
||||||
#include <interface.h>
|
#include <interface.h>
|
||||||
#include <ipv4_address_prefix.h>
|
#include <ipv4_address_prefix.h>
|
||||||
|
|
||||||
@ -27,32 +28,110 @@ namespace Net {
|
|||||||
using Domain_name = Genode::String<160>;
|
using Domain_name = Genode::String<160>;
|
||||||
class Uplink_base;
|
class Uplink_base;
|
||||||
class Uplink;
|
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
|
class Net::Uplink_base
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
struct Interface_policy : Net::Interface_policy
|
Genode::Session_label const _label;
|
||||||
{
|
Domain_name const _domain;
|
||||||
/***************************
|
|
||||||
** Net::Interface_policy **
|
|
||||||
***************************/
|
|
||||||
|
|
||||||
Domain_name determine_domain_name() const override { return Genode::Cstring("uplink"); };
|
public:
|
||||||
void handle_config(Configuration const &) override { }
|
|
||||||
};
|
|
||||||
|
|
||||||
Interface_policy _intf_policy { };
|
Uplink_base(Genode::Xml_node const &node);
|
||||||
|
|
||||||
virtual ~Uplink_base() { }
|
virtual ~Uplink_base() { }
|
||||||
|
|
||||||
|
|
||||||
|
/**************
|
||||||
|
** Acessors **
|
||||||
|
**************/
|
||||||
|
|
||||||
|
Genode::Session_label const &label() const { return _label; }
|
||||||
|
Domain_name const &domain() const { return _domain; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Net::Uplink : public Uplink_base,
|
struct Net::Uplink : public Uplink_base,
|
||||||
public Nic::Packet_allocator,
|
private Genode::Avl_string_base
|
||||||
public Nic::Connection
|
{
|
||||||
|
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:
|
private:
|
||||||
|
|
||||||
@ -61,10 +140,9 @@ class Net::Uplink : public Uplink_base,
|
|||||||
BUF_SIZE = Nic::Session::QUEUE_SIZE * PKT_SIZE,
|
BUF_SIZE = Nic::Session::QUEUE_SIZE * PKT_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::Session_label const &_label;
|
bool _link_state { false };
|
||||||
bool _link_state { false };
|
Genode::Signal_handler<Uplink_interface> _link_state_handler;
|
||||||
Genode::Signal_handler<Uplink> _link_state_handler;
|
Net::Interface _interface;
|
||||||
Net::Interface _interface;
|
|
||||||
|
|
||||||
Ipv4_address_prefix _read_interface();
|
Ipv4_address_prefix _read_interface();
|
||||||
|
|
||||||
@ -72,20 +150,20 @@ class Net::Uplink : public Uplink_base,
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Uplink(Genode::Env &env,
|
Uplink_interface(Genode::Env &env,
|
||||||
Timer::Connection &timer,
|
Timer::Connection &timer,
|
||||||
Genode::Allocator &alloc,
|
Genode::Allocator &alloc,
|
||||||
Interface_list &interfaces,
|
Interface_list &interfaces,
|
||||||
Configuration &config,
|
Configuration &config,
|
||||||
Genode::Session_label const &label);
|
Domain_name const &domain_name,
|
||||||
|
Genode::Session_label const &label);
|
||||||
|
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
Mac_address const &router_mac() const { return _interface.router_mac(); }
|
Mac_address const &router_mac() const { return _interface.router_mac(); }
|
||||||
Genode::Session_label const &label() const { return _label; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _UPLINK_H_ */
|
#endif /* _UPLINK_H_ */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<provides> <service name="Nic"/> </provides>
|
<provides> <service name="Nic"/> </provides>
|
||||||
<config verbose_domain_state="yes">
|
<config verbose_domain_state="yes">
|
||||||
<default-policy domain="default" />
|
<default-policy domain="default" />
|
||||||
|
<uplink domain="uplink" />
|
||||||
<domain name="uplink">
|
<domain name="uplink">
|
||||||
<nat domain="default" tcp-ports="1000" udp-ports="1000"/>
|
<nat domain="default" tcp-ports="1000" udp-ports="1000"/>
|
||||||
</domain>
|
</domain>
|
||||||
|
@ -149,6 +149,7 @@ append_if $use_nic_router config {
|
|||||||
<config verbose_domain_state="yes">
|
<config verbose_domain_state="yes">
|
||||||
|
|
||||||
<policy label_prefix="netserver_genode" domain="server"/>
|
<policy label_prefix="netserver_genode" domain="server"/>
|
||||||
|
<uplink domain="uplink"/>
|
||||||
|
|
||||||
<domain name="uplink"}
|
<domain name="uplink"}
|
||||||
append_if [expr $use_nic_router && [have_spec linux]] config "
|
append_if [expr $use_nic_router && [have_spec linux]] config "
|
||||||
|
@ -64,8 +64,10 @@ append config {
|
|||||||
<resource name="RAM" quantum="10M"/>
|
<resource name="RAM" quantum="10M"/>
|
||||||
<provides><service name="Nic"/></provides>
|
<provides><service name="Nic"/></provides>
|
||||||
<config verbose="no">
|
<config verbose="no">
|
||||||
<policy label_prefix="vfs" domain="default" />
|
<policy label_prefix="vfs" domain="default" />
|
||||||
<policy label_prefix="stubby" domain="dns"/>
|
<policy label_prefix="stubby" domain="dns" />
|
||||||
|
<uplink domain="uplink" />
|
||||||
|
|
||||||
<domain name="uplink">
|
<domain name="uplink">
|
||||||
<nat domain="dns" tcp-ports="64" udp-ports="64"/>
|
<nat domain="dns" tcp-ports="64" udp-ports="64"/>
|
||||||
</domain>
|
</domain>
|
||||||
|
@ -159,6 +159,7 @@ append config {
|
|||||||
dhcp_discover_timeout_sec="1">
|
dhcp_discover_timeout_sec="1">
|
||||||
|
|
||||||
<policy label_prefix="vbox" domain="downlink"/>
|
<policy label_prefix="vbox" domain="downlink"/>
|
||||||
|
<uplink domain="uplink" />
|
||||||
|
|
||||||
<domain name="uplink" label="wifi">
|
<domain name="uplink" label="wifi">
|
||||||
<nat domain="downlink"
|
<nat domain="downlink"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user