mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-30 14:22:37 +01:00
netdev: Add netdev watch infrastructure
This commit is contained in:
parent
b19a683c36
commit
e1bdd7ce1e
88
src/netdev.c
88
src/netdev.c
@ -39,9 +39,20 @@ struct netdev_data {
|
|||||||
char ifname[IF_NAMESIZE];
|
char ifname[IF_NAMESIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct netdev_watchlist_item {
|
||||||
|
uint32_t id;
|
||||||
|
netdev_watch_func_t added;
|
||||||
|
netdev_watch_func_t removed;
|
||||||
|
void *userdata;
|
||||||
|
netdev_destroy_func_t destroy;
|
||||||
|
};
|
||||||
|
|
||||||
static struct l_netlink *rtnl = NULL;
|
static struct l_netlink *rtnl = NULL;
|
||||||
static struct l_hashmap *netdev_list = NULL;
|
static struct l_hashmap *netdev_list = NULL;
|
||||||
|
|
||||||
|
static struct l_queue *netdev_watches = NULL;
|
||||||
|
static uint32_t netdev_next_watch_id = 0;
|
||||||
|
|
||||||
static void do_debug(const char *str, void *user_data)
|
static void do_debug(const char *str, void *user_data)
|
||||||
{
|
{
|
||||||
const char *prefix = user_data;
|
const char *prefix = user_data;
|
||||||
@ -188,6 +199,79 @@ static void link_notify(uint16_t type, const void *data, uint32_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void netdev_watchlist_item_free(void *userdata)
|
||||||
|
{
|
||||||
|
struct netdev_watchlist_item *item = userdata;
|
||||||
|
|
||||||
|
if (item->destroy)
|
||||||
|
item->destroy(item->userdata);
|
||||||
|
|
||||||
|
l_free(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool netdev_watchlist_item_match(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const struct netdev_watchlist_item *item = a;
|
||||||
|
uint32_t id = L_PTR_TO_UINT(b);
|
||||||
|
|
||||||
|
return item->id == id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t netdev_watch_add(netdev_watch_func_t added,
|
||||||
|
netdev_watch_func_t removed,
|
||||||
|
void *userdata, netdev_destroy_func_t destroy)
|
||||||
|
{
|
||||||
|
struct netdev_watchlist_item *item;
|
||||||
|
|
||||||
|
item = l_new(struct netdev_watchlist_item, 1);
|
||||||
|
item->id = ++netdev_next_watch_id;
|
||||||
|
item->added = added;
|
||||||
|
item->removed = removed;
|
||||||
|
item->userdata = userdata;
|
||||||
|
item->destroy = destroy;
|
||||||
|
|
||||||
|
l_queue_push_tail(netdev_watches, item);
|
||||||
|
|
||||||
|
return item->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool netdev_watch_remove(uint32_t id)
|
||||||
|
{
|
||||||
|
struct netdev_watchlist_item *item;
|
||||||
|
|
||||||
|
item = l_queue_remove_if(netdev_watches, netdev_watchlist_item_match,
|
||||||
|
L_UINT_TO_PTR(id));
|
||||||
|
if (!item)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
netdev_watchlist_item_free(item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __netdev_watch_call_added(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
const struct l_queue_entry *e;
|
||||||
|
|
||||||
|
for (e = l_queue_get_entries(netdev_watches); e; e = e->next) {
|
||||||
|
struct netdev_watchlist_item *item = e->data;
|
||||||
|
|
||||||
|
if (item->added)
|
||||||
|
item->added(netdev, item->userdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __netdev_watch_call_removed(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
const struct l_queue_entry *e;
|
||||||
|
|
||||||
|
for (e = l_queue_get_entries(netdev_watches); e; e = e->next) {
|
||||||
|
struct netdev_watchlist_item *item = e->data;
|
||||||
|
|
||||||
|
if (item->removed)
|
||||||
|
item->removed(netdev, item->userdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void netdev_destroy(void)
|
static void netdev_destroy(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -225,6 +309,8 @@ bool netdev_init(void)
|
|||||||
goto destroy;
|
goto destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netdev_watches = l_queue_new();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
destroy:
|
destroy:
|
||||||
@ -242,5 +328,7 @@ bool netdev_exit(void)
|
|||||||
|
|
||||||
netdev_destroy();
|
netdev_destroy();
|
||||||
|
|
||||||
|
l_queue_destroy(netdev_watches, netdev_watchlist_item_free);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
13
src/netdev.h
13
src/netdev.h
@ -22,6 +22,11 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct netdev;
|
||||||
|
|
||||||
|
typedef void (*netdev_watch_func_t)(struct netdev *netdev, void *userdata);
|
||||||
|
typedef void (*netdev_destroy_func_t)(void *userdata);
|
||||||
|
|
||||||
typedef void (*netdev_command_func_t) (bool result, void *user_data);
|
typedef void (*netdev_command_func_t) (bool result, void *user_data);
|
||||||
|
|
||||||
enum netdev_state {
|
enum netdev_state {
|
||||||
@ -36,5 +41,13 @@ void netdev_set_linkmode_and_operstate(uint32_t ifindex,
|
|||||||
uint8_t linkmode, uint8_t operstate,
|
uint8_t linkmode, uint8_t operstate,
|
||||||
netdev_command_func_t cb, void *user_data);
|
netdev_command_func_t cb, void *user_data);
|
||||||
|
|
||||||
|
uint32_t netdev_watch_add(netdev_watch_func_t added,
|
||||||
|
netdev_watch_func_t removed,
|
||||||
|
void *userdata, netdev_destroy_func_t destroy);
|
||||||
|
bool netdev_watch_remove(uint32_t id);
|
||||||
|
|
||||||
|
void __netdev_watch_call_added(struct netdev *netdev);
|
||||||
|
void __netdev_watch_call_removed(struct netdev *netdev);
|
||||||
|
|
||||||
bool netdev_init(void);
|
bool netdev_init(void);
|
||||||
bool netdev_exit(void);
|
bool netdev_exit(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user