In case of FILS shared key offload the parameters can change upon roaming of which user-space needs to be notified.
Unified · Split
| @@ -5624,6 +5624,7 @@ cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid, · 5623 unmodified lines | |||
| 5624 | * @req_ie_len: association request IEs length | 5624 | * @req_ie_len: association request IEs length |
| 5625 | * @resp_ie: association response IEs (may be %NULL) | 5625 | * @resp_ie: association response IEs (may be %NULL) |
| 5626 | * @resp_ie_len: assoc response IEs length | 5626 | * @resp_ie_len: assoc response IEs length |
| 5627 | * @fils: FILS related roaming information. | ||
| 5627 | */ | 5628 | */ |
| 5628 | struct cfg80211_roam_info { | 5629 | struct cfg80211_roam_info { |
| 5629 | struct ieee80211_channel *channel; | 5630 | struct ieee80211_channel *channel; |
| @@ -5633,6 +5634,7 @@ struct cfg80211_roam_info { · 3 unmodified lines | |||
| 5633 | size_t req_ie_len; | 5634 | size_t req_ie_len; |
| 5634 | const u8 *resp_ie; | 5635 | const u8 *resp_ie; |
| 5635 | size_t resp_ie_len; | 5636 | size_t resp_ie_len; |
| 5637 | struct cfg80211_fils_resp_params fils; | ||
| 5636 | }; | 5638 | }; |
| 5637 | 5639 | ||
| 5638 | /** | 5640 | /** |
| @@ -215,7 +215,8 @@ · 214 unmodified lines | |||
| 215 | * as specified in IETF RFC 6696. | 215 | * as specified in IETF RFC 6696. |
| 216 | * | 216 | * |
| 217 | * When FILS shared key authentication is completed, driver needs to provide the | 217 | * When FILS shared key authentication is completed, driver needs to provide the |
| 218 | * below additional parameters to userspace. | 218 | * below additional parameters to userspace, which can be either after setting |
| 219 | * up a connection or after roaming. | ||
| 219 | * %NL80211_ATTR_FILS_KEK - used for key renewal | 220 | * %NL80211_ATTR_FILS_KEK - used for key renewal |
| 220 | * %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used in further EAP-RP exchanges | 221 | * %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used in further EAP-RP exchanges |
| 221 | * %NL80211_ATTR_PMKID - used to identify the PMKSA used/generated | 222 | * %NL80211_ATTR_PMKID - used to identify the PMKSA used/generated |
| @@ -14264,7 +14264,9 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, · 14263 unmodified lines | |||
| 14264 | void *hdr; | 14264 | void *hdr; |
| 14265 | const u8 *bssid = info->bss ? info->bss->bssid : info->bssid; | 14265 | const u8 *bssid = info->bss ? info->bss->bssid : info->bssid; |
| 14266 | 14266 | ||
| 14267 | msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len, gfp); | 14267 | msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len + |
| 14268 | info->fils.kek_len + info->fils.pmk_len + | ||
| 14269 | (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp); | ||
| 14268 | if (!msg) | 14270 | if (!msg) |
| 14269 | return; | 14271 | return; |
| 14270 | 14272 | ||
| @@ -14282,7 +14284,17 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, · 11 unmodified lines | |||
| 14282 | info->req_ie)) || | 14284 | info->req_ie)) || |
| 14283 | (info->resp_ie && | 14285 | (info->resp_ie && |
| 14284 | nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len, | 14286 | nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len, |
| 14285 | info->resp_ie))) | 14287 | info->resp_ie)) || |
| 14288 | (info->fils.update_erp_next_seq_num && | ||
| 14289 | nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM, | ||
| 14290 | info->fils.erp_next_seq_num)) || | ||
| 14291 | (info->fils.kek && | ||
| 14292 | nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len, | ||
| 14293 | info->fils.kek)) || | ||
| 14294 | (info->fils.pmk && | ||
| 14295 | nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) || | ||
| 14296 | (info->fils.pmkid && | ||
| 14297 | nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid))) | ||
| 14286 | goto nla_put_failure; | 14298 | goto nla_put_failure; |
| 14287 | 14299 | ||
| 14288 | genlmsg_end(msg, hdr); | 14300 | genlmsg_end(msg, hdr); |
| @@ -932,6 +932,7 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, · 931 unmodified lines | |||
| 932 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 932 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
| 933 | struct cfg80211_event *ev; | 933 | struct cfg80211_event *ev; |
| 934 | unsigned long flags; | 934 | unsigned long flags; |
| 935 | u8 *next; | ||
| 935 | 936 | ||
| 936 | if (!info->bss) { | 937 | if (!info->bss) { |
| 937 | info->bss = cfg80211_get_bss(wdev->wiphy, info->channel, | 938 | info->bss = cfg80211_get_bss(wdev->wiphy, info->channel, |
| @@ -944,19 +945,52 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, · 6 unmodified lines | |||
| 944 | if (WARN_ON(!info->bss)) | 945 | if (WARN_ON(!info->bss)) |
| 945 | return; | 946 | return; |
| 946 | 947 | ||
| 947 | ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len, gfp); | 948 | ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len + |
| 949 | info->fils.kek_len + info->fils.pmk_len + | ||
| 950 | (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp); | ||
| 948 | if (!ev) { | 951 | if (!ev) { |
| 949 | cfg80211_put_bss(wdev->wiphy, info->bss); | 952 | cfg80211_put_bss(wdev->wiphy, info->bss); |
| 950 | return; | 953 | return; |
| 951 | } | 954 | } |
| 952 | 955 | ||
| 953 | ev->type = EVENT_ROAMED; | 956 | ev->type = EVENT_ROAMED; |
| 954 | ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); | 957 | next = ((u8 *)ev) + sizeof(*ev); |
| 955 | ev->rm.req_ie_len = info->req_ie_len; | 958 | if (info->req_ie_len) { |
| 956 | memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len); | 959 | ev->rm.req_ie = next; |
| 957 | ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + info->req_ie_len; | 960 | ev->rm.req_ie_len = info->req_ie_len; |
| 958 | ev->rm.resp_ie_len = info->resp_ie_len; | 961 | memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len); |
| 959 | memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len); | 962 | next += info->req_ie_len; |
| 963 | } | ||
| 964 | if (info->resp_ie_len) { | ||
| 965 | ev->rm.resp_ie = next; | ||
| 966 | ev->rm.resp_ie_len = info->resp_ie_len; | ||
| 967 | memcpy((void *)ev->rm.resp_ie, info->resp_ie, | ||
| 968 | info->resp_ie_len); | ||
| 969 | next += info->resp_ie_len; | ||
| 970 | } | ||
| 971 | if (info->fils.kek_len) { | ||
| 972 | ev->rm.fils.kek = next; | ||
| 973 | ev->rm.fils.kek_len = info->fils.kek_len; | ||
| 974 | memcpy((void *)ev->rm.fils.kek, info->fils.kek, | ||
| 975 | info->fils.kek_len); | ||
| 976 | next += info->fils.kek_len; | ||
| 977 | } | ||
| 978 | if (info->fils.pmk_len) { | ||
| 979 | ev->rm.fils.pmk = next; | ||
| 980 | ev->rm.fils.pmk_len = info->fils.pmk_len; | ||
| 981 | memcpy((void *)ev->rm.fils.pmk, info->fils.pmk, | ||
| 982 | info->fils.pmk_len); | ||
| 983 | next += info->fils.pmk_len; | ||
| 984 | } | ||
| 985 | if (info->fils.pmkid) { | ||
| 986 | ev->rm.fils.pmkid = next; | ||
| 987 | memcpy((void *)ev->rm.fils.pmkid, info->fils.pmkid, | ||
| 988 | WLAN_PMKID_LEN); | ||
| 989 | next += WLAN_PMKID_LEN; | ||
| 990 | } | ||
| 991 | ev->rm.fils.update_erp_next_seq_num = info->fils.update_erp_next_seq_num; | ||
| 992 | if (info->fils.update_erp_next_seq_num) | ||
| 993 | ev->rm.fils.erp_next_seq_num = info->fils.erp_next_seq_num; | ||
| 960 | ev->rm.bss = info->bss; | 994 | ev->rm.bss = info->bss; |
| 961 | 995 | ||
| 962 | spin_lock_irqsave(&wdev->event_lock, flags); | 996 | spin_lock_irqsave(&wdev->event_lock, flags); |