mirror of
https://github.com/ipxe/ipxe
synced 2025-12-30 04:28:12 +03:00
[netdevice] Separate concept of scope ID from network device name index
The network device index currently serves two purposes: acting as a
sequential index for network device names ("net0", "net1", etc), and
acting as an opaque unique integer identifier used in socket address
scope IDs.
There is no particular need for these usages to be linked, and it can
lead to situations in which devices are named unexpectedly. For
example: if a system has two network devices "net0" and "net1", a VLAN
is created as "net1-42", and then a USB NIC is connected, then the USB
NIC will be named "net3" rather than the expected "net2" since the
VLAN device "net1-42" will have consumed an index.
Separate the usages: rename the "index" field to "scope_id" (matching
its one and only use case), and assign the name without reference to
the scope ID by finding the first unused name. For consistency,
assign the scope ID by similarly finding the first unused scope ID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -55,9 +55,6 @@ struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
|
||||
/** List of open network devices, in reverse order of opening */
|
||||
static struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices );
|
||||
|
||||
/** Network device index */
|
||||
static unsigned int netdev_index = 0;
|
||||
|
||||
/** Network polling profiler */
|
||||
static struct profiler net_poll_profiler __profiler = { .name = "net.poll" };
|
||||
|
||||
@@ -723,6 +720,7 @@ int register_netdev ( struct net_device *netdev ) {
|
||||
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
||||
struct net_driver *driver;
|
||||
struct net_device *duplicate;
|
||||
unsigned int i;
|
||||
uint32_t seed;
|
||||
int rc;
|
||||
|
||||
@@ -757,12 +755,21 @@ int register_netdev ( struct net_device *netdev ) {
|
||||
goto err_duplicate;
|
||||
}
|
||||
|
||||
/* Record device index and create device name */
|
||||
/* Assign a unique device name, if not already set */
|
||||
if ( netdev->name[0] == '\0' ) {
|
||||
snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
|
||||
netdev_index );
|
||||
for ( i = 0 ; ; i++ ) {
|
||||
snprintf ( netdev->name, sizeof ( netdev->name ),
|
||||
"net%d", i );
|
||||
if ( find_netdev ( netdev->name ) == NULL )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign a unique non-zero scope ID */
|
||||
for ( netdev->scope_id = 1 ; ; netdev->scope_id++ ) {
|
||||
if ( find_netdev_by_scope_id ( netdev->scope_id ) == NULL )
|
||||
break;
|
||||
}
|
||||
netdev->index = ++netdev_index;
|
||||
|
||||
/* Use least significant bits of the link-layer address to
|
||||
* improve the randomness of the (non-cryptographic) random
|
||||
@@ -916,10 +923,6 @@ void unregister_netdev ( struct net_device *netdev ) {
|
||||
DBGC ( netdev, "NETDEV %s unregistered\n", netdev->name );
|
||||
list_del ( &netdev->list );
|
||||
netdev_put ( netdev );
|
||||
|
||||
/* Reset network device index if no devices remain */
|
||||
if ( list_empty ( &net_devices ) )
|
||||
netdev_index = 0;
|
||||
}
|
||||
|
||||
/** Enable or disable interrupts
|
||||
@@ -962,17 +965,17 @@ struct net_device * find_netdev ( const char *name ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get network device by index
|
||||
* Get network device by scope ID
|
||||
*
|
||||
* @v index Network device index
|
||||
* @ret netdev Network device, or NULL
|
||||
*/
|
||||
struct net_device * find_netdev_by_index ( unsigned int index ) {
|
||||
struct net_device * find_netdev_by_scope_id ( unsigned int scope_id ) {
|
||||
struct net_device *netdev;
|
||||
|
||||
/* Identify network device by index */
|
||||
list_for_each_entry ( netdev, &net_devices, list ) {
|
||||
if ( netdev->index == index )
|
||||
if ( netdev->scope_id == scope_id )
|
||||
return netdev;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user