struct wpa_driver_nl80211_data *drv;
struct i802_bss *next;
int ifindex;
+ u64 wdev_id;
char ifname[IFNAMSIZ + 1];
char brname[IFNAMSIZ];
unsigned int beacon_set:1;
unsigned int added_if_into_bridge:1;
unsigned int added_bridge:1;
unsigned int in_deinit:1;
+ unsigned int wdev_id_set:1;
u8 addr[ETH_ALEN];
};
+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)
{
struct family_data *res = arg;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
- if (tb[NL80211_ATTR_IFINDEX])
+ if (tb[NL80211_ATTR_IFINDEX]) {
ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
- for (bss = &drv->first_bss; bss; bss = bss->next) {
- if (ifidx == -1 || ifidx == bss->ifindex) {
- do_process_drv_event(bss, gnlh->cmd, tb);
- return NL_SKIP;
+ for (bss = &drv->first_bss; bss; bss = bss->next)
+ if (ifidx == -1 || ifidx == bss->ifindex) {
+ do_process_drv_event(bss, gnlh->cmd, tb);
+ 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;
}
struct wpa_driver_nl80211_data *drv, *tmp;
int ifidx = -1;
struct i802_bss *bss;
+ u64 wdev_id;
+ int wdev_id_set = 0;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (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,
struct wpa_driver_nl80211_data, list) {
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);
return NL_SKIP;
}
case NL80211_IFTYPE_ADHOC:
info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
break;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ info->capa->flags |=
+ WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
+ break;
case NL80211_IFTYPE_P2P_GO:
info->p2p_go_supported = 1;
break;
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(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
static struct nl_msg *
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;
size_t i;
nl80211_cmd(drv, msg, 0, cmd);
- if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, drv->ifindex) < 0)
- goto fail;
+ if (!wdev_id)
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+ else
+ NLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);
if (params->num_ssids) {
struct nlattr *ssids;
return msg;
fail:
+nla_put_failure:
nlmsg_free(msg);
return NULL;
}
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
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)
return -1;
return android_pno_start(bss, params);
#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)
goto nla_put_failure;
return "P2P_CLIENT";
case NL80211_IFTYPE_P2P_GO:
return "P2P_GO";
+ case NL80211_IFTYPE_P2P_DEVICE:
+ return "P2P_DEVICE";
default:
return "unknown";
}
static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
const char *ifname,
enum nl80211_iftype iftype,
- const u8 *addr, int wds)
+ const u8 *addr, int wds,
+ int (*handler)(struct nl_msg *, void *),
+ void *arg)
{
struct nl_msg *msg;
int ifidx;
NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
}
- ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ ret = send_and_recv_msgs(drv, msg, handler, arg);
msg = NULL;
if (ret) {
nla_put_failure:
return ret;
}
+ if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: New P2P Device interface %s created",
+ ifname);
+ return 0;
+ }
+
ifidx = if_nametoindex(ifname);
wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
ifname, ifidx);
static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
const char *ifname, enum nl80211_iftype iftype,
- const u8 *addr, int wds)
+ const u8 *addr, int wds,
+ int (*handler)(struct nl_msg *, void *),
+ void *arg)
{
int ret;
- ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds);
+ ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
+ arg);
/* if error occurred and interface exists already */
if (ret == -ENFILE && if_nametoindex(ifname)) {
/* Try to create the interface again */
ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
- wds);
+ wds, handler, arg);
}
if (ret >= 0 && is_p2p_net_interface(iftype))
drv->monitor_ifidx =
nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
- 0);
+ 0, NULL, NULL);
if (drv->monitor_ifidx == -EOPNOTSUPP) {
/*
if (!if_nametoindex(name)) {
if (nl80211_create_iface(drv, name,
NL80211_IFTYPE_AP_VLAN,
- bss->addr, 1) < 0)
+ bss->addr, 1, NULL, NULL) < 0)
return -1;
if (bridge_ifname &&
linux_br_add_if(drv->global->ioctl_sock,
return NL80211_IFTYPE_AP;
case WPA_IF_P2P_GO:
return NL80211_IFTYPE_P2P_GO;
+ case WPA_IF_P2P_DEVICE:
+ return NL80211_IFTYPE_P2P_DEVICE;
}
return -1;
}
os_memcpy(if_addr, addr, ETH_ALEN);
ifidx = nl80211_create_iface(drv, ifname,
wpa_driver_nl80211_if_type(type), addr,
- 0);
+ 0, NULL, NULL);
if (ifidx < 0) {
#ifdef HOSTAPD
os_free(new_bss);
freq, wait, no_cck, no_ack, offchanok);
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);
if (wait)
NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
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_DURATION, duration);
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);
ret = send_and_recv_msgs(drv, msg, NULL, NULL);