diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 2a456a1f6..3790fe2bb 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -675,6 +675,7 @@ struct wiphy_idx_data { int wiphy_idx; enum nl80211_iftype nlmode; u8 *macaddr; + u8 use_4addr; }; @@ -697,6 +698,9 @@ static int netdev_info_handler(struct nl_msg *msg, void *arg) os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN); + if (tb[NL80211_ATTR_4ADDR]) + info->use_4addr = nla_get_u8(tb[NL80211_ATTR_4ADDR]); + return NL_SKIP; } @@ -752,6 +756,21 @@ static int nl80211_get_macaddr(struct i802_bss *bss) } +static int nl80211_get_4addr(struct i802_bss *bss) +{ + struct nl_msg *msg; + struct wiphy_idx_data data = { + .use_4addr = 0, + }; + + if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)) || + send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data, + NULL, NULL)) + return -1; + return data.use_4addr; +} + + static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv, struct nl80211_wiphy_data *w) { @@ -11788,6 +11807,11 @@ static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname, ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); msg = NULL; + if (ret && val && nl80211_get_4addr(bss) == 1) { + wpa_printf(MSG_DEBUG, + "nl80211: 4addr mode was already enabled"); + ret = 0; + } if (!ret) { if (bridge_ifname[0] && val && i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)