diff --git a/repos/libports/run/nic_bridge.run b/repos/libports/run/nic_bridge.run
index b02f0e5a09..0f5ed1a1ae 100644
--- a/repos/libports/run/nic_bridge.run
+++ b/repos/libports/run/nic_bridge.run
@@ -51,23 +51,28 @@ append config {
+
+
-
-
+
+
+
-
+
+
+
@@ -83,7 +88,27 @@ append config {
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -97,6 +122,22 @@ append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
install_config $config
@@ -132,4 +173,10 @@ append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
append qemu_args " -net user "
-run_genode_until ".*\"test-http_clnt\" exited with exit value 0.*\n" 40
+append done_string {.*?\[server_1 -> lwip] rcv .\[32mETH.\[0m 02:02:02:02:42:00}
+append done_string {.*?\[server_2 -> lwip] rcv .\[32mETH.\[0m 02:02:02:02:23:00}
+append done_string {.*?"client_." exited with exit value 0}
+append done_string {.*?"client_." exited with exit value 0}
+append done_string {.*?\n}
+
+run_genode_until $done_string 40
diff --git a/repos/os/src/server/nic_bridge/README b/repos/os/src/server/nic_bridge/README
index d0f7c6e0c8..22814451fc 100644
--- a/repos/os/src/server/nic_bridge/README
+++ b/repos/os/src/server/nic_bridge/README
@@ -14,6 +14,19 @@ For example:
Note that the least relevant byte will be ignored. NIC bridge will use it for
enumerating its clients, starting from 0.
+A fixed MAC can be configured per client of the NIC bridge using the ''
+tag. For example:
+
+!
+! ...
+!
+!
+!
+!
+
+Note that the fixed MAC addresses must not fall in the range that is used for
+runtime MAC allocation.
+
Normally, NIC bridge is expected to be used in scenarios where an DHCP server
is available. However, there are situations where the use of static IPs for
virtual NICs is useful. For example, when using the NIC bridge to create a
diff --git a/repos/os/src/server/nic_bridge/component.h b/repos/os/src/server/nic_bridge/component.h
index 2e46275910..b466fb4ff0 100644
--- a/repos/os/src/server/nic_bridge/component.h
+++ b/repos/os/src/server/nic_bridge/component.h
@@ -211,14 +211,30 @@ class Net::Root : public Genode::Root_component
memset(ip_addr, 0, MAX_IP_ADDR_LENGTH);
Session_label label;
- try {
+ Mac_address mac;
+ try {
label = label_from_args(args);
Session_policy policy(label, _config);
- policy.attribute("ip_addr").value(ip_addr, sizeof(ip_addr));
- } catch (Xml_node::Nonexistent_attribute) {
- Genode::log("Missing \"ip_addr\" attribute in policy definition");
- } catch (Session_policy::No_policy_defined) { }
+ /* determine session MAC address */
+ mac = policy.attribute_value("mac", Mac_address());
+ if (mac == Mac_address()) {
+ mac = _mac_alloc.alloc(); }
+ else if (_mac_alloc.mac_managed_by_allocator(mac)) {
+ Genode::warning("Bad MAC address in policy");
+ throw Service_denied();
+ }
+
+ policy.attribute("ip_addr").value(ip_addr, sizeof(ip_addr));
+ }
+ catch (Xml_node::Nonexistent_attribute) {
+ Genode::log("Missing \"ip_addr\" attribute in policy definition");
+ }
+ catch (Session_policy::No_policy_defined) { }
+ catch (Mac_allocator::Alloc_failed) {
+ Genode::warning("Mac address allocation failed!");
+ throw Service_denied();
+ }
size_t ram_quota =
Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
size_t tx_buf_size =
@@ -230,12 +246,7 @@ class Net::Root : public Genode::Root_component
return new (md_alloc())
Session_component(_env.ram(), _env.rm(), _env.ep(),
ram_quota, tx_buf_size, rx_buf_size,
- _mac_alloc.alloc(), _nic, _verbose,
- label, ip_addr);
- }
- catch (Mac_allocator::Alloc_failed) {
- Genode::warning("Mac address allocation failed!");
- throw Service_denied();
+ mac, _nic, _verbose, label, ip_addr);
}
catch (Out_of_ram) {
Genode::warning("insufficient 'ram_quota'");
diff --git a/repos/os/src/server/nic_bridge/config.xsd b/repos/os/src/server/nic_bridge/config.xsd
index df2dbd2511..e4c84fc295 100644
--- a/repos/os/src/server/nic_bridge/config.xsd
+++ b/repos/os/src/server/nic_bridge/config.xsd
@@ -19,6 +19,7 @@
+
diff --git a/repos/os/src/server/nic_bridge/mac_allocator.h b/repos/os/src/server/nic_bridge/mac_allocator.h
index 69892b399c..d34179e644 100644
--- a/repos/os/src/server/nic_bridge/mac_allocator.h
+++ b/repos/os/src/server/nic_bridge/mac_allocator.h
@@ -52,6 +52,15 @@ class Net::Mac_allocator
}
void free(Mac_address mac) { _free[mac.addr[5]] = true; }
+
+ bool mac_managed_by_allocator(Mac_address &mac)
+ {
+ return _base.addr[0] == mac.addr[0] &&
+ _base.addr[1] == mac.addr[1] &&
+ _base.addr[2] == mac.addr[2] &&
+ _base.addr[3] == mac.addr[3] &&
+ _base.addr[4] == mac.addr[4];
+ }
};
#endif /* _MAC_ALLOCATOR_H_ */
diff --git a/repos/os/xsd/net_types.xsd b/repos/os/xsd/net_types.xsd
index 7d88cdc28f..901c2888a4 100644
--- a/repos/os/xsd/net_types.xsd
+++ b/repos/os/xsd/net_types.xsd
@@ -3,7 +3,7 @@
-
+