3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-10-04 18:38:48 +02:00

netdev: Track interface name changes

This commit is contained in:
Andrew Zaborowski 2016-07-14 02:38:05 +02:00 committed by Denis Kenzior
parent 6fbc9d59cc
commit 940f4fce46
3 changed files with 53 additions and 13 deletions

View File

@ -1024,17 +1024,21 @@ static bool device_remove_network(const void *key, void *data, void *user_data)
return true; return true;
} }
static void device_netdev_notify(struct netdev *netdev, bool up, static void device_netdev_notify(struct netdev *netdev,
enum netdev_watch_event event,
void *user_data) void *user_data)
{ {
struct device *device = user_data; struct device *device = user_data;
struct l_dbus *dbus = dbus_get_bus(); struct l_dbus *dbus = dbus_get_bus();
if (up) { if (event == NETDEV_EVENT_UP) {
device_enter_state(device, DEVICE_STATE_AUTOCONNECT); device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
__device_watch_call_added(device); __device_watch_call_added(device);
} else {
l_dbus_property_changed(dbus, device_get_path(device),
IWD_DEVICE_INTERFACE, "Powered");
} else if (event == NETDEV_EVENT_DOWN) {
device_enter_state(device, DEVICE_STATE_OFF); device_enter_state(device, DEVICE_STATE_OFF);
if (device->scan_pending) if (device->scan_pending)
@ -1072,11 +1076,11 @@ static void device_netdev_notify(struct netdev *netdev, bool up,
device->networks_sorted = l_queue_new(); device->networks_sorted = l_queue_new();
__device_watch_call_removed(device); __device_watch_call_removed(device);
}
l_dbus_property_changed(dbus, device_get_path(device), l_dbus_property_changed(dbus, device_get_path(device),
IWD_DEVICE_INTERFACE, "Powered"); IWD_DEVICE_INTERFACE, "Powered");
} }
}
struct device *device_create(struct wiphy *wiphy, struct netdev *netdev) struct device *device_create(struct wiphy *wiphy, struct netdev *netdev)
{ {
@ -1103,7 +1107,8 @@ struct device *device_create(struct wiphy *wiphy, struct netdev *netdev)
scan_ifindex_add(device->index); scan_ifindex_add(device->index);
device_netdev_notify(netdev, netdev_get_is_up(netdev), device); device_netdev_notify(netdev, netdev_get_is_up(netdev) ?
NETDEV_EVENT_UP : NETDEV_EVENT_DOWN, device);
device->netdev_watch_id = device->netdev_watch_id =
netdev_watch_add(netdev, device_netdev_notify, device); netdev_watch_add(netdev, device_netdev_notify, device);

View File

@ -1166,33 +1166,61 @@ static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data)
} }
} }
struct netdev_watch_event_data {
struct netdev *netdev;
enum netdev_watch_event type;
};
static void netdev_watch_notify(void *data, void *user_data) static void netdev_watch_notify(void *data, void *user_data)
{ {
struct netdev_watch *watch = data; struct netdev_watch *watch = data;
struct netdev *netdev = user_data; struct netdev_watch_event_data *event = user_data;
watch->callback(netdev, netdev_get_is_up(netdev), watch->user_data); watch->callback(event->netdev, event->type, watch->user_data);
} }
static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes) static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes)
{ {
struct netdev *netdev; struct netdev *netdev;
bool old_up, new_up; bool old_up, new_up;
char old_name[IFNAMSIZ];
struct rtattr *attr;
struct netdev_watch_event_data event;
netdev = netdev_find(ifi->ifi_index); netdev = netdev_find(ifi->ifi_index);
if (!netdev) if (!netdev)
return; return;
old_up = netdev_get_is_up(netdev); old_up = netdev_get_is_up(netdev);
strcpy(old_name, netdev->name);
netdev->ifi_flags = ifi->ifi_flags; netdev->ifi_flags = ifi->ifi_flags;
for (attr = IFLA_RTA(ifi); RTA_OK(attr, bytes);
attr = RTA_NEXT(attr, bytes)) {
if (attr->rta_type != IFLA_IFNAME)
continue;
strcpy(netdev->name, RTA_DATA(attr));
break;
}
new_up = netdev_get_is_up(netdev); new_up = netdev_get_is_up(netdev);
if (old_up == new_up) if (old_up != new_up) {
return; event.netdev = netdev;
event.type = new_up ? NETDEV_EVENT_UP : NETDEV_EVENT_DOWN;
l_queue_foreach(netdev->watches, netdev_watch_notify, netdev); l_queue_foreach(netdev->watches, netdev_watch_notify, &event);
}
if (strcmp(old_name, netdev->name)) {
event.netdev = netdev;
event.type = NETDEV_EVENT_NAME_CHANGE;
l_queue_foreach(netdev->watches, netdev_watch_notify, &event);
}
} }
static void netdev_dellink_notify(const struct ifinfomsg *ifi, int bytes) static void netdev_dellink_notify(const struct ifinfomsg *ifi, int bytes)

View File

@ -43,6 +43,12 @@ enum netdev_event {
NETDEV_EVENT_DISCONNECT_BY_AP, NETDEV_EVENT_DISCONNECT_BY_AP,
}; };
enum netdev_watch_event {
NETDEV_EVENT_UP,
NETDEV_EVENT_DOWN,
NETDEV_EVENT_NAME_CHANGE,
};
typedef void (*netdev_command_func_t) (bool result, void *user_data); typedef void (*netdev_command_func_t) (bool result, void *user_data);
typedef void (*netdev_connect_cb_t)(struct netdev *netdev, typedef void (*netdev_connect_cb_t)(struct netdev *netdev,
enum netdev_result result, enum netdev_result result,
@ -52,7 +58,8 @@ typedef void (*netdev_event_func_t)(struct netdev *netdev,
void *user_data); void *user_data);
typedef void (*netdev_disconnect_cb_t)(struct netdev *netdev, bool result, typedef void (*netdev_disconnect_cb_t)(struct netdev *netdev, bool result,
void *user_data); void *user_data);
typedef void (*netdev_watch_func_t)(struct netdev *netdev, bool up, typedef void (*netdev_watch_func_t)(struct netdev *netdev,
enum netdev_watch_event event,
void *user_data); void *user_data);
typedef void (*netdev_set_powered_cb_t)(struct netdev *netdev, int result, typedef void (*netdev_set_powered_cb_t)(struct netdev *netdev, int result,
void *user_data); void *user_data);