nl80211: Add support to parse out link from error reply
The kernel may report the link that caused an error by setting NLMSGERR_ATTR_OFFS pointing to the NL80211_ATTR_MLO_LINKS element that was the reason for the error. Parse this information if the optional struct nl80211_err_info is passed to send_and_recv_msgs(). Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
parent
e6eebd0d5c
commit
6ba9b9440b
5 changed files with 225 additions and 151 deletions
File diff suppressed because it is too large
Load diff
|
@ -269,6 +269,10 @@ struct wpa_driver_nl80211_data {
|
|||
|
||||
struct nl_msg;
|
||||
|
||||
struct nl80211_err_info {
|
||||
int link_id;
|
||||
};
|
||||
|
||||
void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
|
||||
struct nl_msg *msg, int flags, uint8_t cmd);
|
||||
struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd);
|
||||
|
@ -279,7 +283,8 @@ int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, struct nl_msg *msg,
|
|||
int (*valid_handler)(struct nl_msg *, void *),
|
||||
void *valid_data,
|
||||
int (*ack_handler_custom)(struct nl_msg *, void *),
|
||||
void *ack_data);
|
||||
void *ack_data,
|
||||
struct nl80211_err_info *err_info);
|
||||
struct nl_sock * get_connect_handle(struct i802_bss *bss);
|
||||
int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||
const char *ifname, enum nl80211_iftype iftype,
|
||||
|
|
|
@ -51,7 +51,7 @@ static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
|
|||
}
|
||||
|
||||
if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat,
|
||||
NULL, NULL) == 0)
|
||||
NULL, NULL, NULL) == 0)
|
||||
return feat;
|
||||
|
||||
return 0;
|
||||
|
@ -1202,7 +1202,8 @@ static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info, NULL, NULL))
|
||||
if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info, NULL, NULL,
|
||||
NULL))
|
||||
return -1;
|
||||
|
||||
if (info->auth_supported)
|
||||
|
@ -1312,7 +1313,7 @@ static void qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data *drv)
|
|||
}
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, dfs_info_handler, &dfs_capability,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
if (!ret && dfs_capability)
|
||||
drv->capa.flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
|
||||
}
|
||||
|
@ -1400,7 +1401,7 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
|
|||
os_memset(&info, 0, sizeof(info));
|
||||
info.capa = &drv->capa;
|
||||
ret = send_and_recv_msgs(drv, msg, features_info_handler, &info,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
if (ret || !info.flags)
|
||||
return;
|
||||
|
||||
|
@ -2541,7 +2542,7 @@ static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
|
|||
}
|
||||
|
||||
return send_and_recv_msgs(drv, msg, nl80211_get_reg, results,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2634,7 +2635,7 @@ nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
|
|||
}
|
||||
|
||||
if (send_and_recv_msgs(drv, msg, phy_info_handler, &result,
|
||||
NULL, NULL) == 0) {
|
||||
NULL, NULL, NULL) == 0) {
|
||||
struct hostapd_hw_modes *modes;
|
||||
|
||||
nl80211_set_regulatory_flags(drv, &result);
|
||||
|
|
|
@ -388,7 +388,7 @@ drv_get_connect_fail_reason_code(struct wpa_driver_nl80211_data *drv)
|
|||
|
||||
ret = send_and_recv_msgs(drv, msg,
|
||||
qca_drv_connect_fail_reason_code_handler,
|
||||
&reason_code, NULL, NULL);
|
||||
&reason_code, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Get connect fail reason_code failed: ret=%d (%s)",
|
||||
|
|
|
@ -83,7 +83,7 @@ static int nl80211_get_noise_for_scan_results(
|
|||
os_memset(info, 0, sizeof(*info));
|
||||
msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
|
||||
return send_and_recv_msgs(drv, msg, get_noise_for_scan_results, info,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,7 +95,7 @@ static int nl80211_abort_scan(struct i802_bss *bss)
|
|||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Abort scan");
|
||||
msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_ABORT_SCAN);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL, NULL);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Abort scan failed: ret=%d (%s)",
|
||||
ret, strerror(-ret));
|
||||
|
@ -126,7 +126,7 @@ static int nl80211_abort_vendor_scan(struct wpa_driver_nl80211_data *drv,
|
|||
|
||||
nla_nest_end(msg, params);
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL, NULL);
|
||||
msg = NULL;
|
||||
if (ret) {
|
||||
wpa_printf(MSG_INFO,
|
||||
|
@ -389,7 +389,7 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL, NULL);
|
||||
msg = NULL;
|
||||
if (ret) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
|
||||
|
@ -642,7 +642,7 @@ int wpa_driver_nl80211_sched_scan(void *priv,
|
|||
params->sched_scan_start_delay))
|
||||
goto fail;
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
/* TODO: if we get an error here, we should fall back to normal scan */
|
||||
|
||||
|
@ -679,7 +679,7 @@ int wpa_driver_nl80211_stop_sched_scan(void *priv)
|
|||
#endif /* ANDROID */
|
||||
|
||||
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_STOP_SCHED_SCAN);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL, NULL);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Sched scan stop failed: ret=%d (%s)",
|
||||
|
@ -984,7 +984,8 @@ try_again:
|
|||
|
||||
arg.drv = drv;
|
||||
arg.res = res;
|
||||
ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg, NULL, NULL,
|
||||
NULL);
|
||||
if (ret == -EAGAIN) {
|
||||
count++;
|
||||
if (count >= 10) {
|
||||
|
@ -1069,7 +1070,7 @@ void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
|
|||
msg = nl80211_cmd_msg(drv->first_bss, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
|
||||
if (msg)
|
||||
send_and_recv_msgs(drv, msg, nl80211_dump_scan_handler, &ctx,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1263,7 +1264,7 @@ int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
|
|||
nla_nest_end(msg, attr);
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, scan_cookie_handler, &cookie,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
msg = NULL;
|
||||
if (ret) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
|
@ -1326,7 +1327,7 @@ int nl80211_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len)
|
|||
|
||||
nla_nest_end(msg, attr);
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL, NULL);
|
||||
msg = NULL;
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
|
|
Loading…
Reference in a new issue