if (tb[NL80211_KEY_DEFAULT_TYPES]) {
struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
- int err = nla_parse_nested(kdt,
- NUM_NL80211_KEY_DEFAULT_TYPES - 1,
- tb[NL80211_KEY_DEFAULT_TYPES],
- nl80211_key_default_policy);
+ err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+ tb[NL80211_KEY_DEFAULT_TYPES],
+ nl80211_key_default_policy);
if (err)
return err;
};
static int parse_station_flags(struct genl_info *info,
+ enum nl80211_iftype iftype,
struct station_parameters *params)
{
struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
nla, sta_flags_policy))
return -EINVAL;
- params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
- params->sta_flags_mask &= ~1;
+ /*
+ * Only allow certain flags for interface types so that
+ * other attributes are silently ignored. Remember that
+ * this is backward compatibility code with old userspace
+ * and shouldn't be hit in other cases anyway.
+ */
+ switch (iftype) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
+ params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
+ BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
+ BIT(NL80211_STA_FLAG_WME) |
+ BIT(NL80211_STA_FLAG_MFP);
+ break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_STATION:
+ params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
+ BIT(NL80211_STA_FLAG_TDLS_PEER);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
+ BIT(NL80211_STA_FLAG_MFP) |
+ BIT(NL80211_STA_FLAG_AUTHORIZED);
+ default:
+ return -EINVAL;
+ }
for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
if (flags[flag])
if (!rdev->ops->change_station)
return -EOPNOTSUPP;
- if (parse_station_flags(info, ¶ms))
+ if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms))
return -EINVAL;
if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
if (!rdev->ops->add_station)
return -EOPNOTSUPP;
- if (parse_station_flags(info, ¶ms))
+ if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms))
return -EINVAL;
switch (dev->ieee80211_ptr->iftype) {
cur_params.dot11MeshHWMPRannInterval);
NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
cur_params.dot11MeshGateAnnouncementProtocol);
+ NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING,
+ cur_params.dot11MeshForwarding);
nla_nest_end(msg, pinfoattr);
genlmsg_end(msg, hdr);
return genlmsg_reply(msg, info);
[NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
+ [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
};
static const struct nla_policy
dot11MeshGateAnnouncementProtocol, mask,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
nla_get_u8);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
+ mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
if (mask_out)
*mask_out = mask;
nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
struct ieee80211_supported_band *sband =
wiphy->bands[ibss.channel->band];
- int err;
err = ieee80211_get_ratemask(sband, rates, n_rates,
&ibss.basic_rates);