diff --git a/src/adhoc.c b/src/adhoc.c index a3ae9fca..b1723a45 100644 --- a/src/adhoc.c +++ b/src/adhoc.c @@ -62,7 +62,7 @@ struct sta_state { bool authenticated : 1; }; -static uint32_t device_watch; +static uint32_t netdev_watch; static void adhoc_sta_free(void *data) { @@ -180,20 +180,6 @@ static void adhoc_handshake_event(struct handshake_state *hs, } } -static void adhoc_netdev_notify(struct netdev *netdev, - enum netdev_watch_event event, void *user_data) -{ - struct adhoc_state *ap = user_data; - - switch (event) { - case NETDEV_WATCH_EVENT_DOWN: - adhoc_reset(ap); - break; - default: - break; - } -} - static struct eapol_sm *adhoc_new_sm(struct sta_state *sta, bool authenticator) { struct netdev *netdev = device_get_netdev(sta->adhoc->device); @@ -250,10 +236,6 @@ static struct eapol_sm *adhoc_new_sm(struct sta_state *sta, bool authenticator) static void adhoc_free(struct adhoc_state *adhoc) { adhoc_reset(adhoc); - - netdev_watch_remove(device_get_netdev(adhoc->device), - adhoc->netdev_watch_id); - l_free(adhoc); } @@ -542,7 +524,6 @@ static void adhoc_destroy_interface(void *user_data) adhoc_free(adhoc); } - static void adhoc_add_interface(struct device *device) { struct adhoc_state *adhoc; @@ -551,9 +532,6 @@ static void adhoc_add_interface(struct device *device) adhoc = l_new(struct adhoc_state, 1); adhoc->device = device; - adhoc->netdev_watch_id = netdev_watch_add(device_get_netdev(device), - adhoc_netdev_notify, adhoc); - /* setup ap dbus interface */ l_dbus_object_add_interface(dbus_get_bus(), device_get_path(device), IWD_ADHOC_INTERFACE, adhoc); @@ -565,15 +543,24 @@ static void adhoc_remove_interface(struct device *device) device_get_path(device), IWD_ADHOC_INTERFACE); } -static void ap_device_event(struct device *device, enum device_event event, - void *userdata) +static void adhoc_netdev_watch(struct netdev *netdev, + enum netdev_watch_event event, void *userdata) { + struct device *device = netdev_get_device(netdev); + + if (!device) + return; + switch (event) { - case DEVICE_EVENT_MODE_CHANGED: - if (device_get_mode(device) == DEVICE_MODE_ADHOC) + case NETDEV_WATCH_EVENT_UP: + case NETDEV_WATCH_EVENT_NEW: + if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_ADHOC) adhoc_add_interface(device); - else - adhoc_remove_interface(device); + break; + case NETDEV_WATCH_EVENT_DOWN: + case NETDEV_WATCH_EVENT_DEL: + adhoc_remove_interface(device); + break; default: break; } @@ -581,17 +568,14 @@ static void ap_device_event(struct device *device, enum device_event event, bool adhoc_init(void) { - device_watch = device_watch_add(ap_device_event, NULL, NULL); - if (!device_watch) - return false; - - return l_dbus_register_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE, + netdev_watch = netdev_watch_add(adhoc_netdev_watch, NULL, NULL); + l_dbus_register_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE, adhoc_setup_interface, adhoc_destroy_interface, false); + return true; } void adhoc_exit(void) { - device_watch_remove(device_watch); - + netdev_watch_remove(netdev_watch); l_dbus_unregister_interface(dbus_get_bus(), IWD_ADHOC_INTERFACE); } diff --git a/src/ap.c b/src/ap.c index 7b946439..984cb360 100644 --- a/src/ap.c +++ b/src/ap.c @@ -55,7 +55,6 @@ struct ap_state { uint8_t pmk[32]; struct l_queue *frame_watch_ids; uint32_t start_stop_cmd_id; - uint32_t netdev_watch_id; uint16_t last_aid; struct l_queue *sta_states; @@ -81,7 +80,7 @@ struct sta_state { }; static struct l_genl_family *nl80211 = NULL; -static uint32_t device_watch; +static uint32_t netdev_watch; static void ap_sta_free(void *data) { @@ -128,8 +127,6 @@ static void ap_reset(struct ap_state *ap) if (ap->start_stop_cmd_id) l_genl_family_cancel(nl80211, ap->start_stop_cmd_id); - netdev_watch_remove(netdev, ap->netdev_watch_id); - l_queue_destroy(ap->sta_states, ap_sta_free); if (ap->rates) @@ -1126,20 +1123,6 @@ static void ap_deauth_cb(struct netdev *netdev, const struct mmpdu_header *hdr, ap_sta_free(sta); } -static void ap_netdev_notify(struct netdev *netdev, - enum netdev_watch_event event, void *user_data) -{ - struct ap_state *ap = user_data; - - switch (event) { - case NETDEV_WATCH_EVENT_DOWN: - ap_reset(ap); - break; - default: - break; - } -} - static void ap_start_cb(struct l_genl_msg *msg, void *user_data) { struct ap_state *ap = user_data; @@ -1308,8 +1291,6 @@ static int ap_start(struct ap_state *ap, const char *ssid, const char *psk, goto error; } - ap->netdev_watch_id = netdev_watch_add(netdev, ap_netdev_notify, ap); - ap->pending = l_dbus_message_ref(message); return 0; @@ -1465,15 +1446,24 @@ static void ap_remove_interface(struct device *device) device_get_path(device), IWD_AP_INTERFACE); } -static void ap_device_event(struct device *device, enum device_event event, - void *userdata) +static void ap_netdev_watch(struct netdev *netdev, + enum netdev_watch_event event, void *userdata) { + struct device *device = netdev_get_device(netdev); + + if (!device) + return; + switch (event) { - case DEVICE_EVENT_MODE_CHANGED: - if (device_get_mode(device) == DEVICE_MODE_AP) + case NETDEV_WATCH_EVENT_UP: + case NETDEV_WATCH_EVENT_NEW: + if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_AP) ap_add_interface(device); - else - ap_remove_interface(device); + break; + case NETDEV_WATCH_EVENT_DOWN: + case NETDEV_WATCH_EVENT_DEL: + ap_remove_interface(device); + break; default: break; } @@ -1481,10 +1471,7 @@ static void ap_device_event(struct device *device, enum device_event event, bool ap_init(struct l_genl_family *in) { - device_watch = device_watch_add(ap_device_event, NULL, NULL); - if (!device_watch) - return false; - + netdev_watch = netdev_watch_add(ap_netdev_watch, NULL, NULL); nl80211 = in; return l_dbus_register_interface(dbus_get_bus(), IWD_AP_INTERFACE, @@ -1497,7 +1484,6 @@ bool ap_init(struct l_genl_family *in) void ap_exit(void) { - device_watch_remove(device_watch); - + netdev_watch_remove(netdev_watch); l_dbus_unregister_interface(dbus_get_bus(), IWD_AP_INTERFACE); } diff --git a/src/device.c b/src/device.c index 749d467d..d2896664 100644 --- a/src/device.c +++ b/src/device.c @@ -74,7 +74,6 @@ struct device { struct l_queue *autoconnect_list; struct l_dbus_message *connect_pending; struct l_dbus_message *disconnect_pending; - uint32_t netdev_watch_id; struct watchlist state_watches; struct timespec roam_min_time; struct l_timeout *roam_trigger_timeout; @@ -106,25 +105,14 @@ struct signal_agent { unsigned int disconnect_watch; }; -static struct watchlist device_watches; static struct l_queue *device_list; +static uint32_t netdev_watch; static void device_roam_timeout_rearm(struct device *device, int seconds); static void device_netdev_event(struct netdev *netdev, enum netdev_event event, void *user_data); -uint32_t device_watch_add(device_watch_func_t func, - void *userdata, device_destroy_func_t destroy) -{ - return watchlist_add(&device_watches, func, userdata, destroy); -} - -bool device_watch_remove(uint32_t id) -{ - return watchlist_remove(&device_watches, id); -} - void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data) { const struct l_queue_entry *device_entry; @@ -2515,9 +2503,6 @@ static struct l_dbus_message *device_change_mode(struct device *device, device->mode = mode; - WATCHLIST_NOTIFY(&device_watches, device_watch_func_t, device, - DEVICE_EVENT_MODE_CHANGED); - return NULL; } @@ -2598,17 +2583,17 @@ static void device_netdev_notify(struct netdev *netdev, enum netdev_watch_event event, void *user_data) { - struct device *device = user_data; + struct device *device = netdev_get_device(netdev); struct l_dbus *dbus = dbus_get_bus(); + if (!device) + return; + switch (event) { case NETDEV_WATCH_EVENT_UP: device->autoconnect = true; device_enter_state(device, DEVICE_STATE_AUTOCONNECT); - WATCHLIST_NOTIFY(&device_watches, device_watch_func_t, - device, DEVICE_EVENT_INSERTED); - l_dbus_property_changed(dbus, device_get_path(device), IWD_DEVICE_INTERFACE, "Powered"); break; @@ -2637,9 +2622,6 @@ static void device_netdev_notify(struct netdev *netdev, l_queue_destroy(device->networks_sorted, NULL); device->networks_sorted = l_queue_new(); - WATCHLIST_NOTIFY(&device_watches, device_watch_func_t, - device, DEVICE_EVENT_REMOVED); - l_dbus_property_changed(dbus, device_get_path(device), IWD_DEVICE_INTERFACE, "Powered"); break; @@ -2651,6 +2633,8 @@ static void device_netdev_notify(struct netdev *netdev, l_dbus_property_changed(dbus, device_get_path(device), IWD_DEVICE_INTERFACE, "Address"); break; + default: + break; } } @@ -2687,15 +2671,6 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) scan_ifindex_add(device->index); - netdev_set_iftype(device->netdev, NETDEV_IFTYPE_STATION); - - device_netdev_notify(netdev, netdev_get_is_up(netdev) ? - NETDEV_WATCH_EVENT_UP : - NETDEV_WATCH_EVENT_DOWN, - device); - device->netdev_watch_id = - netdev_watch_add(netdev, device_netdev_notify, device); - /* * register for AP roam transition watch */ @@ -2703,6 +2678,9 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) action_ap_roam_prefix, sizeof(action_ap_roam_prefix), device_ap_roam_frame_event, device); + if (netdev_get_is_up(netdev)) + device_enter_state(device, DEVICE_STATE_AUTOCONNECT); + return device; } @@ -2727,9 +2705,6 @@ static void device_free(void *user) signal_agent_free(device->signal_agent); } - if (device->state != DEVICE_STATE_OFF) - WATCHLIST_NOTIFY(&device_watches, device_watch_func_t, - device, DEVICE_EVENT_REMOVED); watchlist_destroy(&device->state_watches); @@ -2743,8 +2718,6 @@ static void device_free(void *user) l_queue_destroy(device->old_bss_list, bss_free); l_queue_destroy(device->autoconnect_list, l_free); - netdev_watch_remove(device->netdev, device->netdev_watch_id); - l_timeout_remove(device->roam_trigger_timeout); scan_ifindex_remove(device->index); @@ -2770,7 +2743,7 @@ bool device_init(void) NULL, false)) return false; - watchlist_init(&device_watches, NULL); + netdev_watch = netdev_watch_add(device_netdev_notify, NULL, NULL); device_list = l_queue_new(); return true; @@ -2783,8 +2756,7 @@ void device_exit(void) l_queue_destroy(device_list, device_free); device_list = NULL; - - watchlist_destroy(&device_watches); + netdev_watch_remove(netdev_watch); l_dbus_unregister_interface(dbus_get_bus(), IWD_DEVICE_INTERFACE); } diff --git a/src/device.h b/src/device.h index 7969d4bf..eb5f1f31 100644 --- a/src/device.h +++ b/src/device.h @@ -56,10 +56,6 @@ typedef void (*device_watch_func_t)(struct device *device, typedef void (*device_state_watch_func_t)(enum device_state, void *userdata); typedef void (*device_destroy_func_t)(void *userdata); -uint32_t device_watch_add(device_watch_func_t func, - void *userdata, device_destroy_func_t destroy); -bool device_watch_remove(uint32_t id); - struct network *device_get_connected_network(struct device *device); const char *device_get_path(struct device *device); bool device_is_busy(struct device *device); diff --git a/src/netdev.c b/src/netdev.c index beb6290c..67e5cc83 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -109,8 +109,6 @@ struct netdev { void *set_powered_user_data; netdev_destroy_func_t set_powered_destroy; - struct watchlist event_watches; - struct watchlist frame_watches; struct watchlist station_watches; @@ -150,6 +148,7 @@ static struct l_genl_family *nl80211; static struct l_queue *netdev_list; static char **whitelist_filter; static char **blacklist_filter; +static struct watchlist netdev_watches; static void do_debug(const char *str, void *user_data) { @@ -606,8 +605,10 @@ static void netdev_free(void *data) netdev->set_powered_cmd_id = 0; } + WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t, + netdev, NETDEV_WATCH_EVENT_DEL); device_remove(netdev->device); - watchlist_destroy(&netdev->event_watches); + watchlist_destroy(&netdev->frame_watches); watchlist_destroy(&netdev->station_watches); @@ -4009,16 +4010,16 @@ static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes) new_up = netdev_get_is_up(netdev); if (old_up != new_up) - WATCHLIST_NOTIFY(&netdev->event_watches, netdev_watch_func_t, + WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t, netdev, new_up ? NETDEV_WATCH_EVENT_UP : NETDEV_WATCH_EVENT_DOWN); if (strcmp(old_name, netdev->name)) - WATCHLIST_NOTIFY(&netdev->event_watches, netdev_watch_func_t, + WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t, netdev, NETDEV_WATCH_EVENT_NAME_CHANGE); if (memcmp(old_addr, netdev->addr, ETH_ALEN)) - WATCHLIST_NOTIFY(&netdev->event_watches, netdev_watch_func_t, + WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t, netdev, NETDEV_WATCH_EVENT_ADDRESS_CHANGE); } @@ -4067,6 +4068,8 @@ static void netdev_initial_up_cb(int error, uint16_t type, const void *data, l_debug("Interface %i initialized", netdev->index); netdev->device = device_create(netdev->wiphy, netdev); + WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t, + netdev, NETDEV_WATCH_EVENT_NEW); } static void netdev_initial_down_cb(int error, uint16_t type, const void *data, @@ -4409,7 +4412,6 @@ static void netdev_create_from_genl(struct l_genl_msg *msg) netdev_pae_destroy); } - watchlist_init(&netdev->event_watches, NULL); watchlist_init(&netdev->frame_watches, &netdev_frame_watch_ops); watchlist_init(&netdev->station_watches, NULL); @@ -4530,17 +4532,6 @@ static void netdev_link_notify(uint16_t type, const void *data, uint32_t len, } } -uint32_t netdev_watch_add(struct netdev *netdev, netdev_watch_func_t func, - void *user_data) -{ - return watchlist_add(&netdev->event_watches, func, user_data, NULL); -} - -bool netdev_watch_remove(struct netdev *netdev, uint32_t id) -{ - return watchlist_remove(&netdev->event_watches, id); -} - uint32_t netdev_station_watch_add(struct netdev *netdev, netdev_station_watch_func_t func, void *user_data) { @@ -4552,6 +4543,17 @@ bool netdev_station_watch_remove(struct netdev *netdev, uint32_t id) return watchlist_remove(&netdev->station_watches, id); } +uint32_t netdev_watch_add(netdev_watch_func_t func, + void *user_data, netdev_destroy_func_t destroy) +{ + return watchlist_add(&netdev_watches, func, user_data, destroy); +} + +bool netdev_watch_remove(uint32_t id) +{ + return watchlist_remove(&netdev_watches, id); +} + bool netdev_init(const char *whitelist, const char *blacklist) { if (rtnl) @@ -4575,6 +4577,7 @@ bool netdev_init(const char *whitelist, const char *blacklist) return false; } + watchlist_init(&netdev_watches, NULL); netdev_list = l_queue_new(); __handshake_set_install_tk_func(netdev_set_tk); @@ -4626,6 +4629,7 @@ void netdev_exit(void) l_strfreev(whitelist_filter); l_strfreev(blacklist_filter); + watchlist_destroy(&netdev_watches); nl80211 = NULL; l_debug("Closing route netlink socket"); diff --git a/src/netdev.h b/src/netdev.h index bb82f292..3b0c18d1 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -50,6 +50,8 @@ enum netdev_event { }; enum netdev_watch_event { + NETDEV_WATCH_EVENT_NEW, + NETDEV_WATCH_EVENT_DEL, NETDEV_WATCH_EVENT_UP, NETDEV_WATCH_EVENT_DOWN, NETDEV_WATCH_EVENT_NAME_CHANGE, @@ -167,9 +169,9 @@ void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code); struct netdev *netdev_find(int ifindex); -uint32_t netdev_watch_add(struct netdev *netdev, netdev_watch_func_t func, - void *user_data); -bool netdev_watch_remove(struct netdev *netdev, uint32_t id); +uint32_t netdev_watch_add(netdev_watch_func_t func, + void *user_data, netdev_destroy_func_t destroy); +bool netdev_watch_remove(uint32_t id); uint32_t netdev_station_watch_add(struct netdev *netdev, netdev_station_watch_func_t func, void *user_data); diff --git a/src/wsc.c b/src/wsc.c index c36f92e7..b0ea777a 100644 --- a/src/wsc.c +++ b/src/wsc.c @@ -46,7 +46,7 @@ #define WALK_TIME 120 -static uint32_t device_watch = 0; +static uint32_t netdev_watch = 0; struct wsc { struct device *device; @@ -1043,7 +1043,7 @@ static void wsc_free(void *userdata) l_free(wsc); } -static void device_appeared(struct device *device, void *userdata) +static void wsc_add_interface(struct device *device) { struct l_dbus *dbus = dbus_get_bus(); struct wsc *wsc; @@ -1059,7 +1059,7 @@ static void device_appeared(struct device *device, void *userdata) } } -static void device_disappeared(struct device *device, void *userdata) +static void wsc_remove_interface(struct device *device) { struct l_dbus *dbus = dbus_get_bus(); @@ -1067,55 +1067,44 @@ static void device_disappeared(struct device *device, void *userdata) IWD_WSC_INTERFACE); } -static void device_mode_changed(struct device *device, void *userdata) +static void wsc_netdev_watch(struct netdev *netdev, + enum netdev_watch_event event, void *userdata) { - enum device_mode mode = device_get_mode(device); + struct device *device = netdev_get_device(netdev); - switch (mode) { - case DEVICE_MODE_STATION: - device_appeared(device, userdata); + if (!device) + return; + + switch (event) { + case NETDEV_WATCH_EVENT_UP: + case NETDEV_WATCH_EVENT_NEW: + if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION) + wsc_add_interface(device); + break; + case NETDEV_WATCH_EVENT_DOWN: + case NETDEV_WATCH_EVENT_DEL: + wsc_remove_interface(device); break; default: - device_disappeared(device, userdata); break; } } -static void device_event(struct device *device, enum device_event event, - void *userdata) -{ - switch (event) { - case DEVICE_EVENT_INSERTED: - return device_appeared(device, userdata); - case DEVICE_EVENT_REMOVED: - return device_disappeared(device, userdata); - case DEVICE_EVENT_MODE_CHANGED: - return device_mode_changed(device, userdata); - } -} - bool wsc_init(void) { - if (!l_dbus_register_interface(dbus_get_bus(), IWD_WSC_INTERFACE, + l_debug(""); + netdev_watch = netdev_watch_add(wsc_netdev_watch, NULL, NULL); + l_dbus_register_interface(dbus_get_bus(), IWD_WSC_INTERFACE, setup_wsc_interface, - wsc_free, false)) - return false; - - device_watch = device_watch_add(device_event, NULL, NULL); - if (!device_watch) { - l_dbus_unregister_interface(dbus_get_bus(), IWD_WSC_INTERFACE); - return false; - } - + wsc_free, false); return true; } bool wsc_exit() { l_debug(""); - l_dbus_unregister_interface(dbus_get_bus(), IWD_WSC_INTERFACE); - device_watch_remove(device_watch); + netdev_watch_remove(netdev_watch); return true; }