manager: Simplify parsing using nl80211_parse_attrs

This commit is contained in:
Denis Kenzior 2019-09-19 21:48:47 -05:00
parent d400c7f303
commit bf7e62fafb
2 changed files with 66 additions and 83 deletions

View File

@ -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,83 +252,41 @@ 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)) { return;
l_warn("Invalid interface index attribute"); }
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; if (whitelist_filter) {
break; for (i = 0; (pattern = whitelist_filter[i]); i++) {
if (fnmatch(pattern, ifname, 0) != 0)
continue;
case NL80211_ATTR_WIPHY: whitelisted = true;
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; break;
} }
} }
if (!wdev_idx || !iftype) if (blacklist_filter) {
return; for (i = 0; (pattern = blacklist_filter[i]); i++) {
if (fnmatch(pattern, ifname, 0) != 0)
continue;
if (ifindex) { blacklisted = true;
if (!ifname) break;
return;
if (whitelist_filter) {
for (i = 0; (pattern = whitelist_filter[i]); i++) {
if (fnmatch(pattern, ifname, 0) != 0)
continue;
whitelisted = true;
break;
}
}
if (blacklist_filter) {
for (i = 0; (pattern = blacklist_filter[i]); i++) {
if (fnmatch(pattern, ifname, 0) != 0)
continue;
blacklisted = true;
break;
}
} }
} }
@ -338,32 +295,28 @@ static void manager_get_interface_cb(struct l_genl_msg *msg, void *user_data)
* 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;
} }

View File

@ -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;
} }