nl80211: Hold wdev identification for P2P Device

Add wdev_id to i802_bss. wdev_id_set indicates whether this id is
available. Use wdev_id if assigned, instead of ifindex. Use wdev_id for
events that come from the kernel to identify the relevant interface.
This commit does not assign wdev_id value for the BSS yet, i.e., this is
only preparation for the value to be used in a future commit.

Signed-off-by: David Spinadel <david.spinadel@intel.com>
This commit is contained in:
David Spinadel 2013-06-25 13:33:45 +03:00 committed by Jouni Malinen
parent 7aad838c92
commit d3aaef8034

View file

@ -183,12 +183,14 @@ struct i802_bss {
struct wpa_driver_nl80211_data *drv; struct wpa_driver_nl80211_data *drv;
struct i802_bss *next; struct i802_bss *next;
int ifindex; int ifindex;
u64 wdev_id;
char ifname[IFNAMSIZ + 1]; char ifname[IFNAMSIZ + 1];
char brname[IFNAMSIZ]; char brname[IFNAMSIZ];
unsigned int beacon_set:1; unsigned int beacon_set:1;
unsigned int added_if_into_bridge:1; unsigned int added_if_into_bridge:1;
unsigned int added_bridge:1; unsigned int added_bridge:1;
unsigned int in_deinit:1; unsigned int in_deinit:1;
unsigned int wdev_id_set:1;
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
@ -587,6 +589,19 @@ struct family_data {
}; };
static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
{
if (bss->wdev_id_set)
NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
else
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
return 0;
nla_put_failure:
return -1;
}
static int family_handler(struct nl_msg *msg, void *arg) static int family_handler(struct nl_msg *msg, void *arg)
{ {
struct family_data *res = arg; struct family_data *res = arg;
@ -2594,19 +2609,31 @@ static int process_drv_event(struct nl_msg *msg, void *arg)
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL); genlmsg_attrlen(gnlh, 0), NULL);
if (tb[NL80211_ATTR_IFINDEX]) if (tb[NL80211_ATTR_IFINDEX]) {
ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
for (bss = &drv->first_bss; bss; bss = bss->next) { for (bss = &drv->first_bss; bss; bss = bss->next)
if (ifidx == -1 || ifidx == bss->ifindex) { if (ifidx == -1 || ifidx == bss->ifindex) {
do_process_drv_event(bss, gnlh->cmd, tb); do_process_drv_event(bss, gnlh->cmd, tb);
return NL_SKIP; return NL_SKIP;
}
wpa_printf(MSG_DEBUG,
"nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d)",
gnlh->cmd, ifidx);
} else if (tb[NL80211_ATTR_WDEV]) {
u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device");
for (bss = &drv->first_bss; bss; bss = bss->next) {
if (bss->wdev_id_set && wdev_id == bss->wdev_id) {
do_process_drv_event(bss, gnlh->cmd, tb);
return NL_SKIP;
}
} }
wpa_printf(MSG_DEBUG,
"nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%llx)",
gnlh->cmd, (long long unsigned int) wdev_id);
} }
wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d) for foreign "
"interface (ifindex %d)", gnlh->cmd, ifidx);
return NL_SKIP; return NL_SKIP;
} }
@ -2619,17 +2646,26 @@ static int process_global_event(struct nl_msg *msg, void *arg)
struct wpa_driver_nl80211_data *drv, *tmp; struct wpa_driver_nl80211_data *drv, *tmp;
int ifidx = -1; int ifidx = -1;
struct i802_bss *bss; struct i802_bss *bss;
u64 wdev_id;
int wdev_id_set = 0;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL); genlmsg_attrlen(gnlh, 0), NULL);
if (tb[NL80211_ATTR_IFINDEX]) if (tb[NL80211_ATTR_IFINDEX])
ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
else if (tb[NL80211_ATTR_WDEV]) {
wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
wdev_id_set = 1;
}
dl_list_for_each_safe(drv, tmp, &global->interfaces, dl_list_for_each_safe(drv, tmp, &global->interfaces,
struct wpa_driver_nl80211_data, list) { struct wpa_driver_nl80211_data, list) {
for (bss = &drv->first_bss; bss; bss = bss->next) { for (bss = &drv->first_bss; bss; bss = bss->next) {
if (ifidx == -1 || ifidx == bss->ifindex) { if ((ifidx == -1 && !wdev_id_set) ||
ifidx == bss->ifindex ||
(wdev_id_set && bss->wdev_id_set &&
wdev_id == bss->wdev_id)) {
do_process_drv_event(bss, gnlh->cmd, tb); do_process_drv_event(bss, gnlh->cmd, tb);
return NL_SKIP; return NL_SKIP;
} }
@ -3600,7 +3636,9 @@ static int nl80211_register_frame(struct i802_bss *bss,
nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION); nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); if (nl80211_set_iface_id(msg, bss))
goto nla_put_failure;
NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type); NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match); NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
@ -4020,7 +4058,7 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
static struct nl_msg * static struct nl_msg *
nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd, nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
struct wpa_driver_scan_params *params) struct wpa_driver_scan_params *params, u64 *wdev_id)
{ {
struct nl_msg *msg; struct nl_msg *msg;
size_t i; size_t i;
@ -4031,8 +4069,10 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
nl80211_cmd(drv, msg, 0, cmd); nl80211_cmd(drv, msg, 0, cmd);
if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex) < 0) if (!wdev_id)
goto fail; NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
else
NLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);
if (params->num_ssids) { if (params->num_ssids) {
struct nlattr *ssids; struct nlattr *ssids;
@ -4081,6 +4121,7 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
return msg; return msg;
fail: fail:
nla_put_failure:
nlmsg_free(msg); nlmsg_free(msg);
return NULL; return NULL;
} }
@ -4102,7 +4143,8 @@ static int wpa_driver_nl80211_scan(struct i802_bss *bss,
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request"); wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
drv->scan_for_auth = 0; drv->scan_for_auth = 0;
msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params); msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,
bss->wdev_id_set ? &bss->wdev_id : NULL);
if (!msg) if (!msg)
return -1; return -1;
@ -4205,7 +4247,8 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
return android_pno_start(bss, params); return android_pno_start(bss, params);
#endif /* ANDROID */ #endif /* ANDROID */
msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params); msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params,
bss->wdev_id_set ? &bss->wdev_id : NULL);
if (!msg) if (!msg)
goto nla_put_failure; goto nla_put_failure;
@ -8930,7 +8973,9 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss,
freq, wait, no_cck, no_ack, offchanok); freq, wait, no_cck, no_ack, offchanok);
nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME); nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex); if (nl80211_set_iface_id(msg, bss))
goto nla_put_failure;
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
if (wait) if (wait)
NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait); NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
@ -9052,7 +9097,9 @@ static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL); nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); if (nl80211_set_iface_id(msg, bss))
goto nla_put_failure;
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration); NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
@ -9099,7 +9146,9 @@ static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL); nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); if (nl80211_set_iface_id(msg, bss))
goto nla_put_failure;
NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie); NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
ret = send_and_recv_msgs(drv, msg, NULL, NULL); ret = send_and_recv_msgs(drv, msg, NULL, NULL);