mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
nic_bridge: fixed MAC addresses
Enable configuration of a fixed MAC address for each client. Fixes #3040
This commit is contained in:
parent
a062ba6dd2
commit
e0b7fb1929
@ -51,23 +51,28 @@ append config {
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="nic_drv">
|
||||
<binary name="} [nic_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="nic_bridge" caps="200">
|
||||
<resource name="RAM" quantum="24M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config verbose="yes">
|
||||
<policy label_prefix="test-lwip_httpsrv" ip_addr="10.0.2.55"/>
|
||||
<config verbose="yes" mac="02:02:02:02:42:00">
|
||||
<policy label_prefix="server_1" ip_addr="10.0.2.55"/>
|
||||
<policy label_prefix="server_2" ip_addr="10.0.2.56" mac="02:02:02:02:23:00"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_drv"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="test-lwip_httpsrv">
|
||||
|
||||
<start name="server_1">
|
||||
<binary name="test-lwip_httpsrv"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
@ -83,7 +88,27 @@ append config {
|
||||
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="test-http_clnt" caps="120">
|
||||
|
||||
<start name="server_2">
|
||||
<binary name="test-lwip_httpsrv"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
<config port="80">
|
||||
<vfs>
|
||||
<dir name="socket">
|
||||
<lwip ip_addr="10.0.2.56" netmask="255.255.255.0" gateway="10.0.2.1"/>
|
||||
</dir>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="client_1" caps="120">
|
||||
<binary name="test-http_clnt"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
@ -97,6 +122,22 @@ append config {
|
||||
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="client_2" caps="120">
|
||||
<binary name="test-http_clnt"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
<config server_ip="10.0.2.56" server_port="80">
|
||||
<vfs>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
</start>
|
||||
</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
|
||||
|
@ -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 '<policy>'
|
||||
tag. For example:
|
||||
|
||||
!<start name="nic_bridge">
|
||||
! ...
|
||||
! <config>
|
||||
! <policy label_prefix="lighttpd" mac="02:02:02:01:23:45"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
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
|
||||
|
@ -211,14 +211,30 @@ class Net::Root : public Genode::Root_component<Net::Session_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<Net::Session_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'");
|
||||
|
@ -19,6 +19,7 @@
|
||||
<xs:complexContent>
|
||||
<xs:extension base="Session_policy">
|
||||
<xs:attribute name="ip_addr" type="Ipv4_address" />
|
||||
<xs:attribute name="mac" type="Mac_address" />
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
@ -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_ */
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
<xs:simpleType name="Mac_address">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern value="[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}.[0-9a-fA-F]{2}"/>
|
||||
<xs:pattern value="[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType><!-- Mac_address -->
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user