diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-01-14 00:09:20 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-01-14 00:09:20 +0000 |
commit | 47af48012e2afaaf56108466fb967009670660bb (patch) | |
tree | 6548d6bf0626faddf1a1aefdc080dbd7b9590626 /src/net | |
parent | ab19546386b13d6c54aea1647fac06960c544efc (diff) | |
download | ipxe-47af48012e2afaaf56108466fb967009670660bb.tar.gz |
[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>
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/ipv4.c | 2 | ||||
-rw-r--r-- | src/net/ipv6.c | 12 | ||||
-rw-r--r-- | src/net/ndp.c | 4 | ||||
-rw-r--r-- | src/net/netdevice.c | 31 | ||||
-rw-r--r-- | src/net/peerdisc.c | 2 | ||||
-rw-r--r-- | src/net/udp/dhcpv6.c | 2 |
6 files changed, 28 insertions, 25 deletions
diff --git a/src/net/ipv4.c b/src/net/ipv4.c index b9ce5e7f7..b91fa2ad0 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -163,7 +163,7 @@ static struct ipv4_miniroute * ipv4_route ( unsigned int scope_id, /* If destination is non-global, and the scope ID * matches this network device, then use this route. */ - if ( miniroute->netdev->index == scope_id ) + if ( miniroute->netdev->scope_id == scope_id ) return miniroute; } else { diff --git a/src/net/ipv6.c b/src/net/ipv6.c index 901203c40..ef5e51daa 100644 --- a/src/net/ipv6.c +++ b/src/net/ipv6.c @@ -330,7 +330,7 @@ struct ipv6_miniroute * ipv6_route ( unsigned int scope_id, /* Skip entries with a non-matching scope ID, if * destination specifies a scope ID. */ - if ( scope_id && ( miniroute->netdev->index != scope_id ) ) + if ( scope_id && ( miniroute->netdev->scope_id != scope_id ) ) continue; /* Skip entries that are out of scope */ @@ -789,12 +789,12 @@ static int ipv6_rx ( struct io_buffer *iobuf, struct net_device *netdev, src.sin6.sin6_family = AF_INET6; memcpy ( &src.sin6.sin6_addr, &iphdr->src, sizeof ( src.sin6.sin6_addr ) ); - src.sin6.sin6_scope_id = netdev->index; + src.sin6.sin6_scope_id = netdev->scope_id; memset ( &dest, 0, sizeof ( dest ) ); dest.sin6.sin6_family = AF_INET6; memcpy ( &dest.sin6.sin6_addr, &iphdr->dest, sizeof ( dest.sin6.sin6_addr ) ); - dest.sin6.sin6_scope_id = netdev->index; + dest.sin6.sin6_scope_id = netdev->scope_id; iob_pull ( iobuf, hdrlen ); pshdr_csum = ipv6_pshdr_chksum ( iphdr, iob_len ( iobuf ), next_header, TCPIP_EMPTY_CSUM ); @@ -957,7 +957,7 @@ static const char * ipv6_sock_ntoa ( struct sockaddr *sa ) { /* Identify network device, if applicable */ if ( IN6_IS_ADDR_LINKLOCAL ( in ) || IN6_IS_ADDR_MULTICAST ( in ) ) { - netdev = find_netdev_by_index ( sin6->sin6_scope_id ); + netdev = find_netdev_by_scope_id ( sin6->sin6_scope_id ); netdev_name = ( netdev ? netdev->name : "UNKNOWN" ); } else { netdev_name = NULL; @@ -1020,7 +1020,7 @@ static int ipv6_sock_aton ( const char *string, struct sockaddr *sa ) { rc = -ENODEV; goto err_find_netdev; } - sin6->sin6_scope_id = netdev->index; + sin6->sin6_scope_id = netdev->scope_id; } else if ( IN6_IS_ADDR_LINKLOCAL ( &in ) || IN6_IS_ADDR_MULTICAST ( &in ) ) { @@ -1031,7 +1031,7 @@ static int ipv6_sock_aton ( const char *string, struct sockaddr *sa ) { */ netdev = last_opened_netdev(); if ( netdev ) - sin6->sin6_scope_id = netdev->index; + sin6->sin6_scope_id = netdev->scope_id; } /* Copy IPv6 address portion to socket address */ diff --git a/src/net/ndp.c b/src/net/ndp.c index c8e8ebad3..373a9360b 100644 --- a/src/net/ndp.c +++ b/src/net/ndp.c @@ -140,7 +140,7 @@ static int ndp_tx_request ( struct net_device *netdev, /* Construct multicast destination address */ memset ( &sin6_dest, 0, sizeof ( sin6_dest ) ); sin6_dest.sin6_family = AF_INET6; - sin6_dest.sin6_scope_id = netdev->index; + sin6_dest.sin6_scope_id = netdev->scope_id; ipv6_solicited_node ( &sin6_dest.sin6_addr, net_dest ); /* Construct neighbour header */ @@ -177,7 +177,7 @@ static int ndp_tx_router_solicitation ( struct net_device *netdev ) { /* Construct multicast destination address */ memset ( &sin6_dest, 0, sizeof ( sin6_dest ) ); sin6_dest.sin6_family = AF_INET6; - sin6_dest.sin6_scope_id = netdev->index; + sin6_dest.sin6_scope_id = netdev->scope_id; ipv6_all_routers ( &sin6_dest.sin6_addr ); /* Construct router solicitation */ diff --git a/src/net/netdevice.c b/src/net/netdevice.c index 51d1831cc..597c62285 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -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; } diff --git a/src/net/peerdisc.c b/src/net/peerdisc.c index d7e0d2989..86ff94a87 100644 --- a/src/net/peerdisc.c +++ b/src/net/peerdisc.c @@ -189,7 +189,7 @@ static void peerdisc_socket_tx ( const char *uuid, const char *id ) { /* Skip unopened network devices */ if ( ! netdev_is_open ( netdev ) ) continue; - address.st.st_scope_id = netdev->index; + address.st.st_scope_id = netdev->scope_id; /* Discard request (for test purposes) if applicable */ if ( inject_fault ( PEERDISC_DISCARD_RATE ) ) diff --git a/src/net/udp/dhcpv6.c b/src/net/udp/dhcpv6.c index 253032e4e..28c6f7be4 100644 --- a/src/net/udp/dhcpv6.c +++ b/src/net/udp/dhcpv6.c @@ -955,7 +955,7 @@ int start_dhcpv6 ( struct interface *job, struct net_device *netdev, addresses.client.sin6.sin6_port = htons ( DHCPV6_CLIENT_PORT ); addresses.server.sin6.sin6_family = AF_INET6; ipv6_all_dhcp_relay_and_servers ( &addresses.server.sin6.sin6_addr ); - addresses.server.sin6.sin6_scope_id = netdev->index; + addresses.server.sin6.sin6_scope_id = netdev->scope_id; addresses.server.sin6.sin6_port = htons ( DHCPV6_SERVER_PORT ); /* Construct client DUID from system UUID */ |