mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
nic_router/nic_bridge: re-work Mac_allocator
The old MAC allocator had several drawbacks: * the address base was a public static that could and must have been written directly from outside the class * the in-use-flag array was based on unsigned values consuming 4 bytes each for only one bit of information * it was a public header that we actually don't want to expose to all components but only to the few networking components * it used the not-so-safe bit notation for integer members of GCC The new version fixes all these drawbacks. Issue #2795
This commit is contained in:
parent
980f3e9c5c
commit
41dbad13e4
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* \brief MAC-address allocator
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2010-08-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-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.
|
||||
*/
|
||||
|
||||
#ifndef _MAC_ALLOCATOR_H_
|
||||
#define _MAC_ALLOCATOR_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/exception.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
namespace Net {
|
||||
|
||||
/**
|
||||
* The MAC allocator is used to administer MAC addresses for
|
||||
* NIC session clients.
|
||||
*/
|
||||
class Mac_allocator
|
||||
{
|
||||
private:
|
||||
|
||||
/* limit available MAC addresses to one byte range */
|
||||
enum { MSB_MAX = 0xFF };
|
||||
|
||||
/* signals, whether most significant byte is in use */
|
||||
typedef struct
|
||||
{
|
||||
unsigned used : 1;
|
||||
} Msb;
|
||||
|
||||
Msb _msbs[MSB_MAX]; /* bitfield of MSBs */
|
||||
|
||||
public:
|
||||
|
||||
class Alloc_failed : Genode::Exception {};
|
||||
|
||||
/**
|
||||
* Reference MAC address
|
||||
*
|
||||
* We take the range 02:02:02:02:02:XX for our MAC address
|
||||
* allocator, it's likely, that we will have no clashes here.
|
||||
* (e.g. Linux uses 02:00... for its tap-devices.)
|
||||
*/
|
||||
Mac_address mac_addr_base { Mac_address(0x02) };
|
||||
|
||||
Mac_allocator() { Genode::memset(&_msbs, 0, sizeof(_msbs)); }
|
||||
|
||||
|
||||
/**
|
||||
* Allocates a new MAC address.
|
||||
*
|
||||
* \throws Alloc_failed if no more MAC addresses are available.
|
||||
* \return MAC address
|
||||
*/
|
||||
Mac_address alloc()
|
||||
{
|
||||
for (int i=0; i < MSB_MAX; i++) {
|
||||
if (!_msbs[i].used) {
|
||||
_msbs[i].used = 1;
|
||||
Mac_address mac = mac_addr_base;
|
||||
mac.addr[5] = i;
|
||||
return mac;
|
||||
}
|
||||
}
|
||||
throw Alloc_failed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a formerly allocated MAC address.
|
||||
*/
|
||||
void free(Mac_address mac) {
|
||||
_msbs[(unsigned)mac.addr[5]].used = 0; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _MAC_ALLOCATOR_H_ */
|
@ -1,7 +1,7 @@
|
||||
SRC_DIR = src/server/nic_router
|
||||
include $(GENODE_DIR)/repos/base/recipes/src/content.inc
|
||||
|
||||
MIRROR_FROM_REP_DIR := lib/mk/net.mk include/net include/nic_bridge src/lib/net
|
||||
MIRROR_FROM_REP_DIR := lib/mk/net.mk include/net src/lib/net
|
||||
|
||||
content: $(MIRROR_FROM_REP_DIR)
|
||||
|
||||
|
@ -14,18 +14,21 @@
|
||||
#ifndef _COMPONENT_H_
|
||||
#define _COMPONENT_H_
|
||||
|
||||
/* Genode */
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/heap.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/rpc_object.h>
|
||||
#include <nic_session/connection.h>
|
||||
#include <nic_bridge/mac_allocator.h>
|
||||
#include <os/ram_session_guard.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <root/component.h>
|
||||
#include <util/arg_string.h>
|
||||
|
||||
/* NIC router includes */
|
||||
#include <mac_allocator.h>
|
||||
|
||||
/* local includes */
|
||||
#include <address_node.h>
|
||||
#include <nic.h>
|
||||
#include <packet_handler.h>
|
||||
@ -187,7 +190,9 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Mac_allocator _mac_alloc { };
|
||||
enum { DEFAULT_MAC = 0x02 };
|
||||
|
||||
Mac_allocator _mac_alloc;
|
||||
Genode::Env &_env;
|
||||
Net::Nic &_nic;
|
||||
Genode::Xml_node _config;
|
||||
@ -242,9 +247,8 @@ class Net::Root : public Genode::Root_component<Net::Session_component>
|
||||
Root(Genode::Env &env, Net::Nic &nic, Genode::Allocator &md_alloc,
|
||||
Genode::Xml_node config)
|
||||
: Genode::Root_component<Session_component>(env.ep(), md_alloc),
|
||||
_mac_alloc(Mac_address(config.attribute_value("mac", (Genode::uint8_t)DEFAULT_MAC))),
|
||||
_env(env), _nic(nic), _config(config) { }
|
||||
|
||||
Mac_address &mac_addr_base() { return _mac_alloc.mac_addr_base; }
|
||||
};
|
||||
|
||||
#endif /* _COMPONENT_H_ */
|
||||
|
57
repos/os/src/server/nic_bridge/mac_allocator.h
Normal file
57
repos/os/src/server/nic_bridge/mac_allocator.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* \brief MAC-address allocator
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2010-08-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-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.
|
||||
*/
|
||||
|
||||
#ifndef _MAC_ALLOCATOR_H_
|
||||
#define _MAC_ALLOCATOR_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/exception.h>
|
||||
#include <net/mac_address.h>
|
||||
|
||||
namespace Net { class Mac_allocator; }
|
||||
|
||||
|
||||
class Net::Mac_allocator
|
||||
{
|
||||
private:
|
||||
|
||||
Mac_address const _base;
|
||||
bool _free[sizeof(_base.addr[0]) << 8];
|
||||
|
||||
public:
|
||||
|
||||
struct Alloc_failed : Genode::Exception {};
|
||||
|
||||
Mac_allocator(Mac_address base) : _base(base)
|
||||
{
|
||||
Genode::memset(&_free, true, sizeof(_free));
|
||||
}
|
||||
|
||||
Mac_address alloc()
|
||||
{
|
||||
for (unsigned id = 0; id < sizeof(_free) / sizeof(_free[0]); id++) {
|
||||
if (!_free[id]) {
|
||||
continue; }
|
||||
|
||||
_free[id] = false;
|
||||
Mac_address mac = _base;
|
||||
mac.addr[5] = id;
|
||||
return mac;
|
||||
}
|
||||
throw Alloc_failed();
|
||||
}
|
||||
|
||||
void free(Mac_address mac) { _free[mac.addr[5]] = true; }
|
||||
};
|
||||
|
||||
#endif /* _MAC_ALLOCATOR_H_ */
|
@ -35,23 +35,9 @@ struct Main
|
||||
Net::Nic nic { env, heap, vlan };
|
||||
Net::Root root { env, nic, heap, config.xml() };
|
||||
|
||||
void handle_config()
|
||||
{
|
||||
/* read MAC address prefix from config file */
|
||||
try {
|
||||
Nic::Mac_address mac;
|
||||
config.xml().attribute("mac").value(&mac);
|
||||
Genode::memcpy(&root.mac_addr_base(), &mac,
|
||||
sizeof(Net::Mac_allocator::mac_addr_base));
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
Main(Genode::Env &e) : env(e)
|
||||
{
|
||||
try {
|
||||
/* read configuration file */
|
||||
handle_config();
|
||||
|
||||
/* show MAC address to use */
|
||||
Net::Mac_address mac(nic.mac());
|
||||
Genode::log("--- NIC bridge started (mac=", mac, ") ---");
|
||||
|
@ -122,11 +122,10 @@ Net::Root::Root(Entrypoint &ep,
|
||||
Region_map ®ion_map)
|
||||
:
|
||||
Root_component<Session_component>(&ep.rpc_ep(), &alloc), _timer(timer),
|
||||
_ep(ep), _router_mac(router_mac), _config(config), _buf_ram(buf_ram),
|
||||
_region_map(region_map), _interfaces(interfaces)
|
||||
{
|
||||
_mac_alloc.mac_addr_base = config.mac_first();
|
||||
}
|
||||
_mac_alloc(config.mac_first()), _ep(ep), _router_mac(router_mac),
|
||||
_config(config), _buf_ram(buf_ram), _region_map(region_map),
|
||||
_interfaces(interfaces)
|
||||
{ }
|
||||
|
||||
|
||||
Session_component *Net::Root::_create_session(char const *args)
|
||||
|
@ -19,9 +19,9 @@
|
||||
#include <root/component.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/rpc_object.h>
|
||||
#include <nic_bridge/mac_allocator.h>
|
||||
|
||||
/* local includes */
|
||||
#include <mac_allocator.h>
|
||||
#include <interface.h>
|
||||
#include <reference.h>
|
||||
|
||||
@ -137,7 +137,7 @@ class Net::Root : public Genode::Root_component<Session_component>
|
||||
private:
|
||||
|
||||
Timer::Connection &_timer;
|
||||
Mac_allocator _mac_alloc { };
|
||||
Mac_allocator _mac_alloc;
|
||||
Genode::Entrypoint &_ep;
|
||||
Mac_address const _router_mac;
|
||||
Reference<Configuration> _config;
|
||||
|
57
repos/os/src/server/nic_router/mac_allocator.h
Normal file
57
repos/os/src/server/nic_router/mac_allocator.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* \brief MAC-address allocator
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2010-08-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-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.
|
||||
*/
|
||||
|
||||
#ifndef _MAC_ALLOCATOR_H_
|
||||
#define _MAC_ALLOCATOR_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/exception.h>
|
||||
#include <net/mac_address.h>
|
||||
|
||||
namespace Net { class Mac_allocator; }
|
||||
|
||||
|
||||
class Net::Mac_allocator
|
||||
{
|
||||
private:
|
||||
|
||||
Mac_address const _base;
|
||||
bool _free[sizeof(_base.addr[0]) << 8];
|
||||
|
||||
public:
|
||||
|
||||
struct Alloc_failed : Genode::Exception {};
|
||||
|
||||
Mac_allocator(Mac_address base) : _base(base)
|
||||
{
|
||||
Genode::memset(&_free, true, sizeof(_free));
|
||||
}
|
||||
|
||||
Mac_address alloc()
|
||||
{
|
||||
for (unsigned id = 0; id < sizeof(_free) / sizeof(_free[0]); id++) {
|
||||
if (!_free[id]) {
|
||||
continue; }
|
||||
|
||||
_free[id] = false;
|
||||
Mac_address mac = _base;
|
||||
mac.addr[5] = id;
|
||||
return mac;
|
||||
}
|
||||
throw Alloc_failed();
|
||||
}
|
||||
|
||||
void free(Mac_address mac) { _free[mac.addr[5]] = true; }
|
||||
};
|
||||
|
||||
#endif /* _MAC_ALLOCATOR_H_ */
|
Loading…
x
Reference in New Issue
Block a user