From a9cbb9526088b9a21d9dcbf95645528cd23dead2 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Mon, 14 Aug 2017 14:49:16 +0200 Subject: [PATCH] netdev: Add interface type setter and getter Modify netdev_get_iftype, which was until now unused, and add netdev_set_iftype. Don't skip interfaces with types other than STATION on startup, instead reset the type to STATION in device.c. netdev_get_iftype is modified to use our own interface type enum to avoid forcing users to include "nl80211.h". Note that setting an interface UP and DOWN wouldn't generally reset the iftype to STATION. Another process may still change the type while iwd is running and iwd would not detect this as it would detect another interface setting interface DOWN, not sure how far we want to go in monitoring all of the properties this way. --- src/device.c | 2 ++ src/netdev.c | 34 +++++++++++++++++++++++++++------- src/netdev.h | 8 +++++++- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/device.c b/src/device.c index ae1ae750..a1e9033f 100644 --- a/src/device.c +++ b/src/device.c @@ -2104,6 +2104,8 @@ 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, diff --git a/src/netdev.c b/src/netdev.c index 42249e38..0083d14f 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -195,9 +195,10 @@ uint32_t netdev_get_ifindex(struct netdev *netdev) return netdev->index; } -uint32_t netdev_get_iftype(struct netdev *netdev) +enum netdev_iftype netdev_get_iftype(struct netdev *netdev) { - return netdev->type; + return netdev->type == NL80211_IFTYPE_AP ? + NETDEV_IFTYPE_AP : NETDEV_IFTYPE_STATION; } const char *netdev_get_name(struct netdev *netdev) @@ -417,6 +418,9 @@ static void netdev_shutdown_one(void *data, void *user_data) { struct netdev *netdev = data; + if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_AP) + netdev_set_iftype(netdev, NETDEV_IFTYPE_STATION); + if (netdev_get_is_up(netdev)) netdev_set_powered(netdev, false, NULL, NULL, NULL); } @@ -2902,6 +2906,27 @@ static int netdev_cqm_rssi_update(struct netdev *netdev) return 0; } +int netdev_set_iftype(struct netdev *netdev, enum netdev_iftype type) +{ + struct l_genl_msg *msg; + uint32_t iftype = (type == NETDEV_IFTYPE_AP) ? + NL80211_IFTYPE_AP : NL80211_IFTYPE_STATION; + + msg = l_genl_msg_new_sized(NL80211_CMD_SET_INTERFACE, 32); + l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index); + l_genl_msg_append_attr(msg, NL80211_ATTR_IFTYPE, 4, &iftype); + + if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL)) { + l_error("CMD_SET_INTERFACE failed"); + + l_genl_msg_unref(msg); + + return -EIO; + } + + return 0; +} + struct netdev_watch_event_data { struct netdev *netdev; enum netdev_watch_event type; @@ -3178,11 +3203,6 @@ static void netdev_create_from_genl(struct l_genl_msg *msg) return; } - if (*iftype != NL80211_IFTYPE_STATION) { - l_warn("Skipping non-STA interfaces"); - return; - } - if (!ifindex || !ifaddr | !ifname) { l_warn("Unable to parse interface information"); return; diff --git a/src/netdev.h b/src/netdev.h index 4ea661c5..94b61d7c 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -56,6 +56,11 @@ enum netdev_watch_event { NETDEV_WATCH_EVENT_ADDRESS_CHANGE, }; +enum netdev_iftype { + NETDEV_IFTYPE_STATION, + NETDEV_IFTYPE_AP, +}; + typedef void (*netdev_command_func_t) (bool result, void *user_data); typedef void (*netdev_connect_cb_t)(struct netdev *netdev, enum netdev_result result, @@ -83,7 +88,8 @@ typedef void (*netdev_preauthenticate_cb_t)(struct netdev *netdev, const uint8_t *netdev_get_address(struct netdev *netdev); uint32_t netdev_get_ifindex(struct netdev *netdev); -uint32_t netdev_get_iftype(struct netdev *netdev); +enum netdev_iftype netdev_get_iftype(struct netdev *netdev); +int netdev_set_iftype(struct netdev *netdev, enum netdev_iftype type); const char *netdev_get_name(struct netdev *netdev); bool netdev_get_is_up(struct netdev *netdev); struct handshake_state *netdev_get_handshake(struct netdev *netdev);