manager: Simplify parsing using nl80211_parse_attrs
This commit is contained in:
parent
d400c7f303
commit
bf7e62fafb
|
@ -236,12 +236,11 @@ static void manager_del_interface_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
static void manager_get_interface_cb(struct l_genl_msg *msg, void *user_data)
|
static void manager_get_interface_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
{
|
{
|
||||||
struct wiphy_setup_state *state = user_data;
|
struct wiphy_setup_state *state = user_data;
|
||||||
struct l_genl_attr attr;
|
uint32_t wiphy;
|
||||||
uint16_t type, len;
|
uint32_t ifindex;
|
||||||
const void *data;
|
uint32_t iftype;
|
||||||
const uint32_t *ifindex = NULL, *iftype = NULL;
|
uint64_t wdev;
|
||||||
const uint64_t *wdev_idx = NULL;
|
const char *ifname;
|
||||||
const char *ifname = NULL;
|
|
||||||
struct l_genl_msg *del_msg;
|
struct l_genl_msg *del_msg;
|
||||||
unsigned cmd_id;
|
unsigned cmd_id;
|
||||||
char *pattern;
|
char *pattern;
|
||||||
|
@ -253,64 +252,23 @@ static void manager_get_interface_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
if (state->aborted)
|
if (state->aborted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!l_genl_attr_init(&attr, msg))
|
if (nl80211_parse_attrs(msg, NL80211_ATTR_WDEV, &wdev,
|
||||||
|
NL80211_ATTR_WIPHY, &wiphy,
|
||||||
|
NL80211_ATTR_IFTYPE, &iftype,
|
||||||
|
NL80211_ATTR_UNSPEC) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (l_genl_attr_next(&attr, &type, &len, &data)) {
|
if (wiphy != state->id) {
|
||||||
switch (type) {
|
l_debug("Wiphy attribute mis-match, wanted: %u, got %u",
|
||||||
case NL80211_ATTR_IFINDEX:
|
state->id, wiphy);
|
||||||
if (len != sizeof(uint32_t)) {
|
|
||||||
l_warn("Invalid interface index attribute");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifindex = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_WDEV:
|
if (nl80211_parse_attrs(msg, NL80211_ATTR_IFINDEX, &ifindex,
|
||||||
if (len != sizeof(uint64_t)) {
|
NL80211_ATTR_IFNAME, &ifname,
|
||||||
l_warn("Invalid wdev index attribute");
|
NL80211_ATTR_UNSPEC) < 0)
|
||||||
return;
|
goto delete_interface;
|
||||||
}
|
|
||||||
|
|
||||||
wdev_idx = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_WIPHY:
|
|
||||||
if (len != sizeof(uint32_t) ||
|
|
||||||
*((uint32_t *) data) != state->id) {
|
|
||||||
l_warn("Invalid wiphy attribute");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_IFTYPE:
|
|
||||||
if (len != sizeof(uint32_t)) {
|
|
||||||
l_warn("Invalid interface type attribute");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iftype = data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NL80211_ATTR_IFNAME:
|
|
||||||
if (len < 1 || !memchr(data + 1, 0, len - 1)) {
|
|
||||||
l_warn("Invalid interface name attribute");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifname = data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wdev_idx || !iftype)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ifindex) {
|
|
||||||
if (!ifname)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (whitelist_filter) {
|
if (whitelist_filter) {
|
||||||
for (i = 0; (pattern = whitelist_filter[i]); i++) {
|
for (i = 0; (pattern = whitelist_filter[i]); i++) {
|
||||||
|
@ -331,39 +289,34 @@ static void manager_get_interface_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this interface is usable as our default netdev in case the
|
* If this interface is usable as our default netdev in case the
|
||||||
* driver does not support interface manipulation, save the message
|
* driver does not support interface manipulation, save the message
|
||||||
* just in case.
|
* just in case.
|
||||||
*/
|
*/
|
||||||
if ((*iftype == NL80211_IFTYPE_ADHOC ||
|
if ((iftype == NL80211_IFTYPE_ADHOC ||
|
||||||
*iftype == NL80211_IFTYPE_STATION ||
|
iftype == NL80211_IFTYPE_STATION ||
|
||||||
*iftype == NL80211_IFTYPE_AP) &&
|
iftype == NL80211_IFTYPE_AP) &&
|
||||||
ifindex && *ifindex != 0 &&
|
|
||||||
!state->default_if_msg &&
|
!state->default_if_msg &&
|
||||||
(!whitelist_filter || whitelisted) &&
|
(!whitelist_filter || whitelisted) &&
|
||||||
!blacklisted)
|
!blacklisted)
|
||||||
state->default_if_msg = l_genl_msg_ref(msg);
|
state->default_if_msg = l_genl_msg_ref(msg);
|
||||||
|
|
||||||
|
delete_interface:
|
||||||
if (state->use_default)
|
if (state->use_default)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
del_msg = l_genl_msg_new(NL80211_CMD_DEL_INTERFACE);
|
del_msg = l_genl_msg_new(NL80211_CMD_DEL_INTERFACE);
|
||||||
|
l_genl_msg_append_attr(del_msg, NL80211_ATTR_WDEV, 8, &wdev);
|
||||||
if (ifindex)
|
|
||||||
l_genl_msg_append_attr(del_msg, NL80211_ATTR_IFINDEX, 4, ifindex);
|
|
||||||
|
|
||||||
l_genl_msg_append_attr(del_msg, NL80211_ATTR_WDEV, 8, wdev_idx);
|
|
||||||
l_genl_msg_append_attr(del_msg, NL80211_ATTR_WIPHY, 4, &state->id);
|
l_genl_msg_append_attr(del_msg, NL80211_ATTR_WIPHY, 4, &state->id);
|
||||||
cmd_id = l_genl_family_send(nl80211, del_msg,
|
cmd_id = l_genl_family_send(nl80211, del_msg,
|
||||||
manager_del_interface_cb, state,
|
manager_del_interface_cb, state,
|
||||||
manager_setup_cmd_done);
|
manager_setup_cmd_done);
|
||||||
|
|
||||||
if (!cmd_id) {
|
if (!cmd_id) {
|
||||||
l_error("Sending DEL_INTERFACE for %s failed",
|
l_error("Sending DEL_INTERFACE for wdev: %" PRIu64" failed",
|
||||||
ifname ?: "unnamed interface");
|
wdev);
|
||||||
state->use_default = true;
|
state->use_default = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,31 @@ static bool extract_ifindex(const void *data, uint16_t len, void *o)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool extract_name(const void *data, uint16_t len, void *o)
|
||||||
|
{
|
||||||
|
const char **out = o;
|
||||||
|
|
||||||
|
if (len < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!memchr(data + 1, 0, len - 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*out = data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool extract_uint64(const void *data, uint16_t len, void *o)
|
||||||
|
{
|
||||||
|
uint64_t *out = o;
|
||||||
|
|
||||||
|
if (len != 8)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*out = l_get_u64(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool extract_uint32(const void *data, uint16_t len, void *o)
|
static bool extract_uint32(const void *data, uint16_t len, void *o)
|
||||||
{
|
{
|
||||||
uint32_t *out = o;
|
uint32_t *out = o;
|
||||||
|
@ -66,7 +91,12 @@ static attr_handler handler_for_type(enum nl80211_attrs type)
|
||||||
case NL80211_ATTR_IFINDEX:
|
case NL80211_ATTR_IFINDEX:
|
||||||
return extract_ifindex;
|
return extract_ifindex;
|
||||||
case NL80211_ATTR_WIPHY:
|
case NL80211_ATTR_WIPHY:
|
||||||
|
case NL80211_ATTR_IFTYPE:
|
||||||
return extract_uint32;
|
return extract_uint32;
|
||||||
|
case NL80211_ATTR_WDEV:
|
||||||
|
return extract_uint64;
|
||||||
|
case NL80211_ATTR_IFNAME:
|
||||||
|
return extract_name;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue