diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a8bd453d22b9..08de0c6035f1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -375,6 +375,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
375 | [NL80211_ATTR_VHT_CAPABILITY_MASK] = { | 375 | [NL80211_ATTR_VHT_CAPABILITY_MASK] = { |
376 | .len = NL80211_VHT_CAPABILITY_LEN, | 376 | .len = NL80211_VHT_CAPABILITY_LEN, |
377 | }, | 377 | }, |
378 | [NL80211_ATTR_MDID] = { .type = NLA_U16 }, | ||
379 | [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, | ||
380 | .len = IEEE80211_MAX_DATA_LEN }, | ||
378 | }; | 381 | }; |
379 | 382 | ||
380 | /* policy for the key attributes */ | 383 | /* policy for the key attributes */ |
@@ -8160,6 +8163,27 @@ static int nl80211_get_protocol_features(struct sk_buff *skb, | |||
8160 | return -ENOBUFS; | 8163 | return -ENOBUFS; |
8161 | } | 8164 | } |
8162 | 8165 | ||
8166 | static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info) | ||
8167 | { | ||
8168 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
8169 | struct cfg80211_update_ft_ies_params ft_params; | ||
8170 | struct net_device *dev = info->user_ptr[1]; | ||
8171 | |||
8172 | if (!rdev->ops->update_ft_ies) | ||
8173 | return -EOPNOTSUPP; | ||
8174 | |||
8175 | if (!info->attrs[NL80211_ATTR_MDID] || | ||
8176 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | ||
8177 | return -EINVAL; | ||
8178 | |||
8179 | memset(&ft_params, 0, sizeof(ft_params)); | ||
8180 | ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]); | ||
8181 | ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | ||
8182 | ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | ||
8183 | |||
8184 | return rdev_update_ft_ies(rdev, dev, &ft_params); | ||
8185 | } | ||
8186 | |||
8163 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 8187 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
8164 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 8188 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
8165 | #define NL80211_FLAG_NEED_RTNL 0x04 | 8189 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -8841,6 +8865,14 @@ static struct genl_ops nl80211_ops[] = { | |||
8841 | .doit = nl80211_get_protocol_features, | 8865 | .doit = nl80211_get_protocol_features, |
8842 | .policy = nl80211_policy, | 8866 | .policy = nl80211_policy, |
8843 | }, | 8867 | }, |
8868 | { | ||
8869 | .cmd = NL80211_CMD_UPDATE_FT_IES, | ||
8870 | .doit = nl80211_update_ft_ies, | ||
8871 | .policy = nl80211_policy, | ||
8872 | .flags = GENL_ADMIN_PERM, | ||
8873 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
8874 | NL80211_FLAG_NEED_RTNL, | ||
8875 | }, | ||
8844 | }; | 8876 | }; |
8845 | 8877 | ||
8846 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 8878 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
@@ -10542,6 +10574,50 @@ static struct notifier_block nl80211_netlink_notifier = { | |||
10542 | .notifier_call = nl80211_netlink_notify, | 10574 | .notifier_call = nl80211_netlink_notify, |
10543 | }; | 10575 | }; |
10544 | 10576 | ||
10577 | void cfg80211_ft_event(struct net_device *netdev, | ||
10578 | struct cfg80211_ft_event_params *ft_event) | ||
10579 | { | ||
10580 | struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy; | ||
10581 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
10582 | struct sk_buff *msg; | ||
10583 | void *hdr; | ||
10584 | int err; | ||
10585 | |||
10586 | trace_cfg80211_ft_event(wiphy, netdev, ft_event); | ||
10587 | |||
10588 | if (!ft_event->target_ap) | ||
10589 | return; | ||
10590 | |||
10591 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
10592 | if (!msg) | ||
10593 | return; | ||
10594 | |||
10595 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); | ||
10596 | if (!hdr) { | ||
10597 | nlmsg_free(msg); | ||
10598 | return; | ||
10599 | } | ||
10600 | |||
10601 | nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
10602 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | ||
10603 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap); | ||
10604 | if (ft_event->ies) | ||
10605 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies); | ||
10606 | if (ft_event->ric_ies) | ||
10607 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | ||
10608 | ft_event->ric_ies); | ||
10609 | |||
10610 | err = genlmsg_end(msg, hdr); | ||
10611 | if (err < 0) { | ||
10612 | nlmsg_free(msg); | ||
10613 | return; | ||
10614 | } | ||
10615 | |||
10616 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
10617 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | ||
10618 | } | ||
10619 | EXPORT_SYMBOL(cfg80211_ft_event); | ||
10620 | |||
10545 | /* initialisation/exit functions */ | 10621 | /* initialisation/exit functions */ |
10546 | 10622 | ||
10547 | int nl80211_init(void) | 10623 | int nl80211_init(void) |