net: bump u80211

This commit is contained in:
Matheus
2026-09-14 09:08:02 -03:00
parent 68ac5c73cf
commit f7b4348384
10 changed files with 70 additions and 64 deletions
@@ -11,14 +11,14 @@ typedef struct {
size_t entry_count;
} bss_cache_t;
int u80211_bss_cache_init(bss_cache_t *cache);
void u80211_bss_cache_deinit(bss_cache_t *cache);
void u80211_bss_cache_purge(bss_cache_t *cache);
void u80211_bss_cache_insert(bss_cache_t *cache, u80211_ap_t *ap);
void u80211_bss_cache_remove(bss_cache_t *cache, u80211_mac_address_t *mac);
u80211_ap_t *u80211_bss_cache_find(bss_cache_t *cache, u80211_mac_address_t *mac);
int u80211_bss_cache_init(u80211_device_t *device);
void u80211_bss_cache_deinit(u80211_device_t *device);
void u80211_bss_cache_purge(u80211_device_t *device);
void u80211_bss_cache_insert(u80211_device_t *device, u80211_ap_t *ap);
void u80211_bss_cache_remove(u80211_device_t *device, u80211_mac_address_t *mac);
u80211_ap_t *u80211_bss_cache_find(u80211_device_t *device, u80211_mac_address_t *mac);
// each AP pointer written to buffer has an acquired reference that the caller must release.
size_t u80211_bss_cache_get_aps(bss_cache_t *cache, u80211_ap_t **buffer, size_t capacity);
size_t u80211_bss_cache_get_count(bss_cache_t *cache);
size_t u80211_bss_cache_get_aps(u80211_device_t *device, u80211_ap_t **buffer, size_t capacity);
size_t u80211_bss_cache_get_count(u80211_device_t *device);
#endif
@@ -19,12 +19,12 @@ static inline void *u80211_descriptor_allocate_space(u80211_tx_buffer_descriptor
}
typedef struct {
int (*allocate_tx_buffer)(u80211_device_t *device, size_t size, u80211_tx_buffer_descriptor_t *buffer_descriptor);
int (*free_tx_buffer)(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buffer_descriptor);
int (*transmit)(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buffer_descriptor, const u80211_transmit_options_t *options);
int (*set_channel)(u80211_device_t *device, int channel);
int (*set_key)(u80211_device_t *device, const u80211_key_t *key);
int (*del_key)(u80211_device_t *device, uint8_t index, const u80211_mac_address_t *peer, uint32_t flags);
int (*allocate_tx_buffer)(void *driver_data, size_t size, u80211_tx_buffer_descriptor_t *buffer_descriptor);
int (*free_tx_buffer)(void *driver_data, u80211_tx_buffer_descriptor_t *buffer_descriptor);
int (*transmit)(void *driver_data, u80211_tx_buffer_descriptor_t *buffer_descriptor, const u80211_transmit_options_t *options);
int (*set_channel)(void *driver_data, int channel);
int (*set_key)(void *driver_data, const u80211_key_t *key);
int (*del_key)(void *driver_data, uint8_t index, const u80211_mac_address_t *peer, uint32_t flags);
} u80211_device_ops_t;
typedef struct {
+1 -1
View File
@@ -352,7 +352,7 @@ int u80211_associate(u80211_device_t *device, u80211_ap_t *ap, const void *infor
.auth_transaction = 1,
.status = 0,
};
device->ops->set_channel(device, ap->channel);
device->ops->set_channel(device->driver_data, ap->channel);
u80211_send_authentication(device, &auth_data);
u80211_kernel_enqueue_delayed_work(association_context->auth_timeout_work, association_context->auth_timeout_timer,
+17 -9
View File
@@ -1,9 +1,9 @@
#include <stddef.h>
#include <u80211/bss_cache.h>
#include <u80211/kernel_interface.h>
#include <u80211/rbtree.h>
#include <u80211/status.h>
#include <u80211/u80211.h>
#include <u80211/util.h>
static int mac_compare(u80211_mac_address_t *a, u80211_mac_address_t *b) {
@@ -30,7 +30,8 @@ static int rbtree_value_compare(void *a, u80211_rbtree_t *b) {
return mac_compare(a, &ap_b->mac_address);
}
int u80211_bss_cache_init(bss_cache_t *cache) {
int u80211_bss_cache_init(u80211_device_t *device) {
bss_cache_t *cache = &device->bss_cache;
cache->root = NULL;
cache->entry_count = 0;
cache->rwlock = u80211_kernel_allocate_rwlock();
@@ -40,7 +41,8 @@ int u80211_bss_cache_init(bss_cache_t *cache) {
return U80211_STATUS_SUCCESS;
}
void u80211_bss_cache_deinit(bss_cache_t *cache) {
void u80211_bss_cache_deinit(u80211_device_t *device) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_exclusive(cache->rwlock);
u80211_rbtree_t *iterator = cache->root == NULL ? NULL : u80211_rbtree_first(cache->root);
@@ -60,7 +62,8 @@ void u80211_bss_cache_deinit(bss_cache_t *cache) {
cache->root = NULL;
}
void u80211_bss_cache_purge(bss_cache_t *cache) {
void u80211_bss_cache_purge(u80211_device_t *device) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_exclusive(cache->rwlock);
u80211_rbtree_t *iterator = cache->root == NULL ? NULL : u80211_rbtree_first(cache->root);
@@ -80,7 +83,8 @@ void u80211_bss_cache_purge(bss_cache_t *cache) {
u80211_kernel_release_rwlock_exclusive(cache->rwlock);
}
void u80211_bss_cache_insert(bss_cache_t *cache, u80211_ap_t *ap) {
void u80211_bss_cache_insert(u80211_device_t *device, u80211_ap_t *ap) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_exclusive(cache->rwlock);
u80211_rbtree_t *node = u80211_rbtree_lookup(cache->root, &ap->mac_address, rbtree_value_compare);
@@ -96,7 +100,8 @@ void u80211_bss_cache_insert(bss_cache_t *cache, u80211_ap_t *ap) {
u80211_kernel_release_rwlock_exclusive(cache->rwlock);
}
void u80211_bss_cache_remove(bss_cache_t *cache, u80211_mac_address_t *mac) {
void u80211_bss_cache_remove(u80211_device_t *device, u80211_mac_address_t *mac) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_exclusive(cache->rwlock);
u80211_rbtree_t *node = u80211_rbtree_lookup(cache->root, mac, rbtree_value_compare);
@@ -114,7 +119,8 @@ void u80211_bss_cache_remove(bss_cache_t *cache, u80211_mac_address_t *mac) {
u80211_kernel_release_rwlock_exclusive(cache->rwlock);
}
u80211_ap_t *u80211_bss_cache_find(bss_cache_t *cache, u80211_mac_address_t *mac) {
u80211_ap_t *u80211_bss_cache_find(u80211_device_t *device, u80211_mac_address_t *mac) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_shared(cache->rwlock);
u80211_rbtree_t *node = u80211_rbtree_lookup(cache->root, mac, rbtree_value_compare);
@@ -131,7 +137,8 @@ u80211_ap_t *u80211_bss_cache_find(bss_cache_t *cache, u80211_mac_address_t *mac
return ap;
}
size_t u80211_bss_cache_get_aps(bss_cache_t *cache, u80211_ap_t **buffer, size_t capacity) {
size_t u80211_bss_cache_get_aps(u80211_device_t *device, u80211_ap_t **buffer, size_t capacity) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_shared(cache->rwlock);
size_t count = 0;
@@ -148,7 +155,8 @@ size_t u80211_bss_cache_get_aps(bss_cache_t *cache, u80211_ap_t **buffer, size_t
return count;
}
size_t u80211_bss_cache_get_count(bss_cache_t *cache) {
size_t u80211_bss_cache_get_count(u80211_device_t *device) {
bss_cache_t *cache = &device->bss_cache;
u80211_kernel_acquire_rwlock_shared(cache->rwlock);
size_t count = cache->entry_count;
u80211_kernel_release_rwlock_shared(cache->rwlock);
+2 -2
View File
@@ -67,7 +67,7 @@ int u80211_register_device(const u80211_device_metadata_t *metadata, const u8021
device->ops = ops;
device->driver_data = driver_data;
status = u80211_bss_cache_init(&device->bss_cache);
status = u80211_bss_cache_init(device);
if (status != U80211_STATUS_SUCCESS) {
u80211_kernel_free_work(device->association_cleanup_work);
u80211_kernel_free_spinlock(device->association_spinlock);
@@ -88,7 +88,7 @@ void u80211_unregister_device(u80211_device_t *device) {
u80211_kernel_free_work(device->association_cleanup_work);
if (device->disconnected_ap != NULL)
u80211_ap_release(device->disconnected_ap);
u80211_bss_cache_deinit(&device->bss_cache);
u80211_bss_cache_deinit(device);
u80211_kernel_free_spinlock(device->association_spinlock);
u80211_kernel_free_spinlock(device->scan_spinlock);
u80211_kernel_free(device);
+2 -2
View File
@@ -76,7 +76,7 @@ int u80211_set_key(u80211_device_t *device, const u80211_key_t *key) {
if (key->key_len != 0)
u80211_memcpy(metadata->key, key->key, key->key_len);
int status = device->ops->set_key(device, key);
int status = device->ops->set_key(device->driver_data, key);
if (status != U80211_STATUS_SUCCESS) {
destroy_key_metadata(metadata);
return status;
@@ -104,7 +104,7 @@ int u80211_del_key(u80211_device_t *device, uint8_t index, const u80211_mac_addr
if (device->ops->del_key == NULL)
return U80211_STATUS_UNSUPPORTED;
int status = device->ops->del_key(device, index, peer, flags);
int status = device->ops->del_key(device->driver_data, index, peer, flags);
if (status != U80211_STATUS_SUCCESS)
return status;
+9 -9
View File
@@ -111,7 +111,7 @@ static int prepare_tkip_tx(u80211_device_t *device, u80211_header_description_t
}
int u80211_allocate_tx_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_t *descriptor) {
int status = device->ops->allocate_tx_buffer(device, ETHERNET_MAX_FRAME_SIZE + TX_BUFFER_HEADROOM + TX_BUFFER_TAILROOM, descriptor);
int status = device->ops->allocate_tx_buffer(device->driver_data, ETHERNET_MAX_FRAME_SIZE + TX_BUFFER_HEADROOM + TX_BUFFER_TAILROOM, descriptor);
if (status != U80211_STATUS_SUCCESS)
return status;
@@ -131,7 +131,7 @@ int u80211_transmit_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_
u80211_ap_t *ap = device->ap;
if (u80211_get_device_state(device) != U80211_DEVICE_STATE_ASSOCIATED || ap == NULL) {
u80211_kernel_release_spinlock(device->association_spinlock);
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return U80211_STATUS_NOT_ASSOCIATED;
}
u80211_ap_hold(ap);
@@ -140,7 +140,7 @@ int u80211_transmit_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_
size_t ethernet_frame_size = descriptor->size - descriptor->current_offset;
if (ethernet_frame_size < ETHERNET_HEADER_SIZE) {
u80211_ap_release(ap);
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return U80211_STATUS_NOT_ENOUGH_SPACE;
}
@@ -156,7 +156,7 @@ int u80211_transmit_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_
uint8_t *llc_snap = u80211_descriptor_allocate_space(descriptor, LLCSNAP_SIZE);
if (llc_snap == NULL) {
u80211_ap_release(ap);
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return U80211_STATUS_NOT_ENOUGH_SPACE;
}
u80211_memcpy(llc_snap, byte_header, sizeof(byte_header));
@@ -178,7 +178,7 @@ int u80211_transmit_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_
if (key >= 0) {
// supported cipher headers have two bits for key selection
if (key > 3) {
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return U80211_STATUS_NOT_PERMITTED;
}
@@ -192,21 +192,21 @@ int u80211_transmit_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_
cipher_status = prepare_tkip_tx(device, &header, key, descriptor);
break;
default:
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return U80211_STATUS_UNSUPPORTED;
}
if (cipher_status != U80211_STATUS_SUCCESS) {
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return cipher_status;
}
}
int status = u80211_serialize_header(&header, descriptor);
if (status != U80211_STATUS_SUCCESS) {
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return status;
}
const u80211_transmit_options_t options = { .key = key, .cipher = cipher };
return device->ops->transmit(device, descriptor, &options);
return device->ops->transmit(device->driver_data, descriptor, &options);
}
@@ -154,13 +154,13 @@ static size_t serialize_rate_information_elements(uint8_t *destination, const ui
}
static int prepare_management_packet(u80211_device_t *device, const u80211_mac_address_t *address, int subtype, size_t data_size, u80211_tx_buffer_descriptor_t *descriptor, uint8_t **data) {
int status = device->ops->allocate_tx_buffer(device, MANAGEMENT_HEADER_SIZE + data_size, descriptor);
int status = device->ops->allocate_tx_buffer(device->driver_data, MANAGEMENT_HEADER_SIZE + data_size, descriptor);
if (status != U80211_STATUS_SUCCESS)
return status;
*data = u80211_descriptor_allocate_space(descriptor, data_size);
if (*data == NULL) {
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return U80211_STATUS_NOT_ENOUGH_SPACE;
}
@@ -176,7 +176,7 @@ static int prepare_management_packet(u80211_device_t *device, const u80211_mac_a
status = u80211_serialize_header(&header, descriptor);
if (status != U80211_STATUS_SUCCESS)
device->ops->free_tx_buffer(device, descriptor);
device->ops->free_tx_buffer(device->driver_data, descriptor);
return status;
}
@@ -304,7 +304,7 @@ int u80211_send_authentication(u80211_device_t *device, u80211_auth_data_t *auth
serialize_le16(data + 4, auth_data->status);
const u80211_transmit_options_t options = { .key = -1, .cipher = -1 };
return device->ops->transmit(device, &descriptor, &options);
return device->ops->transmit(device->driver_data, &descriptor, &options);
}
int u80211_send_deauthentication(u80211_device_t *device, u80211_deauthentication_data_t *deauthentication_data) {
@@ -317,7 +317,7 @@ int u80211_send_deauthentication(u80211_device_t *device, u80211_deauthenticatio
serialize_le16(data, deauthentication_data->reason);
const u80211_transmit_options_t options = { .key = -1, .cipher = -1 };
return device->ops->transmit(device, &descriptor, &options);
return device->ops->transmit(device->driver_data, &descriptor, &options);
}
int u80211_send_probe_request(u80211_device_t *device) {
@@ -336,7 +336,7 @@ int u80211_send_probe_request(u80211_device_t *device) {
serialize_rate_information_elements(probe_request_data + 2, device->metadata.rate_bitmap, rate_count);
const u80211_transmit_options_t options = { .key = -1, .cipher = -1 };
return device->ops->transmit(device, &descriptor, &options);
return device->ops->transmit(device->driver_data, &descriptor, &options);
}
int u80211_send_association_request(u80211_device_t *device, const void *information_elements, size_t information_elements_size) {
@@ -365,5 +365,5 @@ int u80211_send_association_request(u80211_device_t *device, const void *informa
u80211_memcpy(data + 6 + ssid_size + rate_information_size, information_elements, information_elements_size);
const u80211_transmit_options_t options = { .key = -1, .cipher = -1 };
return device->ops->transmit(device, &descriptor, &options);
return device->ops->transmit(device->driver_data, &descriptor, &options);
}
+4 -4
View File
@@ -142,7 +142,7 @@ static void scan_work(void *ctx) {
if (ap == NULL)
continue;
u80211_bss_cache_insert(&device->bss_cache, ap);
u80211_bss_cache_insert(device, ap);
u80211_ap_release(ap);
}
@@ -156,7 +156,7 @@ static void scan_work(void *ctx) {
scan_state->current_channel = current_channel;
u80211_kernel_release_spinlock(device->scan_spinlock);
device->ops->set_channel(device, scan_state->current_channel);
device->ops->set_channel(device->driver_data, scan_state->current_channel);
u80211_kernel_acquire_spinlock(device->scan_spinlock);
scan_state->receiving = true;
@@ -210,9 +210,9 @@ int u80211_scan(u80211_device_t *device) {
device->scan_context = scan_state;
u80211_kernel_release_spinlock(device->scan_spinlock);
u80211_bss_cache_purge(&device->bss_cache);
u80211_bss_cache_purge(device);
device->ops->set_channel(device, scan_state->current_channel);
device->ops->set_channel(device->driver_data, scan_state->current_channel);
u80211_kernel_acquire_spinlock(device->scan_spinlock);
scan_state->receiving = true;
+14 -16
View File
@@ -22,13 +22,11 @@ typedef struct {
// TODO: proper up/down handling
// TODO: make hardware keys take peer into account too
// TODO: proper concurrency protection for key and channel setting
// TODO: make u80211 bss cache get more generic than having to pass the bss cache directly
// TODO: handle hotplug
// TODO: in u80211_drv *_tx_buffer ops, pass device handle
// TODO: change how netdesc_t is handled in kernel overall (?)
// TODO: map u80211 errors to errnos
// TODO: map u80211 errors to u80211_drv errors
// TODO: in u80211, change the device ops to take a (void *) handle
// TODO: general netdev cleanup:
// - use struct ops instead of having function pointers in netdev struct
// - proper initialize() function
@@ -54,8 +52,8 @@ static void free_id(int id) {
__atomic_fetch_and(&id_bitmap, ~(1lu << id), __ATOMIC_RELAXED);
}
static int allocate_tx_buffer(u80211_device_t *device, size_t size, u80211_tx_buffer_descriptor_t *buffer_descriptor) {
wlan_device_t *wlan = device->driver_data;
static int allocate_tx_buffer(void *driver_data, size_t size, u80211_tx_buffer_descriptor_t *buffer_descriptor) {
wlan_device_t *wlan = driver_data;
buffer_descriptor->size = size;
buffer_descriptor->current_offset = size;
@@ -63,8 +61,8 @@ static int allocate_tx_buffer(u80211_device_t *device, size_t size, u80211_tx_bu
U80211_STATUS_SUCCESS : U80211_STATUS_UNKNOWN_ERROR;
}
static int free_tx_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buffer_descriptor) {
wlan_device_t *wlan = device->driver_data;
static int free_tx_buffer(void *driver_data, u80211_tx_buffer_descriptor_t *buffer_descriptor) {
wlan_device_t *wlan = driver_data;
wlan->ops->free_tx_buffer(buffer_descriptor->data);
return 0;
}
@@ -91,8 +89,8 @@ static int convert_cipher(int cipher, int *drv_cipher) {
}
}
static int transmit(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buffer_descriptor, const u80211_transmit_options_t *options) {
wlan_device_t *wlan = device->driver_data;
static int transmit(void *driver_data, u80211_tx_buffer_descriptor_t *buffer_descriptor, const u80211_transmit_options_t *options) {
wlan_device_t *wlan = driver_data;
u80211_drv_transmit_options_t drv_options = {
.key = options->key
@@ -107,15 +105,15 @@ static int transmit(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buff
U80211_STATUS_SUCCESS : U80211_STATUS_UNKNOWN_ERROR;
}
static int set_channel(u80211_device_t *device, int channel) {
wlan_device_t *wlan = device->driver_data;
static int set_channel(void *driver_data, int channel) {
wlan_device_t *wlan = driver_data;
return wlan->ops->set_channel(wlan->driver_handle, channel) == U80211_DRV_STATUS_SUCCESS ?
U80211_STATUS_SUCCESS : U80211_STATUS_UNKNOWN_ERROR;
}
static int set_key(u80211_device_t *device, const u80211_key_t *key) {
wlan_device_t *wlan = device->driver_data;
static int set_key(void *driver_data, const u80211_key_t *key) {
wlan_device_t *wlan = driver_data;
u80211_drv_key_t drv_key = {
.index = key->index,
@@ -133,10 +131,10 @@ static int set_key(u80211_device_t *device, const u80211_key_t *key) {
U80211_STATUS_SUCCESS : U80211_STATUS_UNKNOWN_ERROR;
}
static int del_key(u80211_device_t *device, uint8_t index, const u80211_mac_address_t *peer, uint32_t flags) {
static int del_key(void *driver_data, uint8_t index, const u80211_mac_address_t *peer, uint32_t flags) {
(void)peer;
(void)flags;
wlan_device_t *wlan = device->driver_data;
wlan_device_t *wlan = driver_data;
return wlan->ops->del_key(wlan->driver_handle, index) == U80211_DRV_STATUS_SUCCESS ?
U80211_STATUS_SUCCESS : U80211_STATUS_UNKNOWN_ERROR;
@@ -293,7 +291,7 @@ int wlan_get_bss_cache(netdev_t *netdev, void *buffer, size_t size, size_t *reco
if (ap_buffer == NULL)
return ENOMEM;
size_t ap_count = u80211_bss_cache_get_aps(&wlan->u80211_device->bss_cache, ap_buffer, MAX_APS);
size_t ap_count = u80211_bss_cache_get_aps(wlan->u80211_device, ap_buffer, MAX_APS);
int error = 0;
*records_written = 0;
@@ -348,7 +346,7 @@ int wlan_associate(netdev_t *netdev, uint8_t bssid[6], void *ie, size_t ie_size)
u80211_mac_address_t mac;
memcpy(&mac, bssid, 6);
u80211_ap_t *ap = u80211_bss_cache_find(&wlan->u80211_device->bss_cache, &mac);
u80211_ap_t *ap = u80211_bss_cache_find(wlan->u80211_device, &mac);
if (ap == NULL)
return EINVAL;