Re: [PATCH 3/4] netdev: implement PMKSA for fullmac drivers

James Prestwood
2025-02-12T16:27:22Z

On 2/12/25 8:24 AM, James Prestwood wrote:
> Supporting PMKSA on fullmac drivers requires that we set the PMKSA
> into the kernel as well as remove it. Since station has a removal
> path netdev_remove_pmksa needed to be added which station will
> call. This will handle both removing IWD's PMKSA cache as well as
> in the kernels.
>
> On addition its similar, we add to both IWDs cache and the kernels.
> ---
> src/netdev.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> src/netdev.h | 2 ++
> 2 files changed, 70 insertions(+)
>
> diff --git a/src/netdev.c b/src/netdev.c
> index 06282c2a..42fb6a4b 100644
> --- a/src/netdev.c
> +++ b/src/netdev.c
> @@ -1498,6 +1498,52 @@ static void netdev_setting_keys_failed(struct netdev_handshake_state *nhs,
> handshake_event(&nhs->super, HANDSHAKE_EVENT_SETTING_KEYS_FAILED, &err);
> }
>
> +static void netdev_set_pmksa(struct handshake_state *hs)
> +{
> + struct l_genl_msg *msg;
> + uint32_t expiration = (uint32_t)hs->expiration;
> +
> + if (!hs->have_pmkid)
> + return;
> +
> + msg = l_genl_msg_new(NL80211_CMD_SET_PMKSA);
> +
> + l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &hs->ifindex);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_PMKID, 16, hs->pmkid);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, hs->aa);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, hs->ssid_len, hs->ssid);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_PMK_LIFETIME, 4, &expiration);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_PMK, hs->pmk_len, hs->pmk);
> +
> + if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL))
> + l_error("error sending SET_PMKSA");
> +}
> +
> +void netdev_remove_pmksa(struct netdev *netdev)
> +{
> + struct l_genl_msg *msg;
> + struct handshake_state *hs = netdev->handshake;
> + struct netdev_handshake_state *nhs = l_container_of(hs,
> + struct netdev_handshake_state, super);
> +
> + handshake_state_remove_pmksa(netdev->handshake);
> +
> + if (nhs->type != CONNECTION_TYPE_FULLMAC)
> + return;
> +
> + /* Fullmac cards need to set/remove the PMKSA within the kernel */
> +
> + msg = l_genl_msg_new(NL80211_CMD_DEL_PMKSA);
> +
> + l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_PMKID, 16, hs->pmkid);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, hs->aa);
> + l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, hs->ssid_len, hs->ssid);
> +
> + if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL))
> + l_error("error sending DEL_PMKSA");
> +}
> +
> static void try_handshake_complete(struct netdev_handshake_state *nhs)
> {
> l_debug("ptk_installed: %u, gtk_installed: %u, igtk_installed: %u",
> @@ -1518,6 +1564,9 @@ static void try_handshake_complete(struct netdev_handshake_state *nhs)
>
> l_debug("Invoking handshake_event()");
>
> + if (nhs->type == CONNECTION_TYPE_FULLMAC)
> + netdev_set_pmksa(&nhs->super);
> +
> handshake_state_cache_pmksa(&nhs->super);
>
> if (handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE))
> @@ -6469,6 +6518,23 @@ static void netdev_get_link(struct netdev *netdev)
> L_WARN_ON(netdev->get_link_cmd_id == 0);
> }
>
> +static void netdev_flush_pmksa(struct netdev *netdev)
> +{
> + struct l_genl_msg *msg = l_genl_msg_new(NL80211_CMD_FLUSH_PMKSA);
Just noticed this is leaking memory. I'll fix after reviews.
> +
> + /*
> + * We only utilize the kernel's PMKSA cache for fullmac cards, so no
> + * need to flush if this is a softmac
> + */
> + if (wiphy_supports_cmds_auth_assoc(netdev->wiphy))
> + return;
> +
> + l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
> +
> + if (!l_genl_family_send(nl80211, msg, NULL, NULL, NULL))
> + l_error("Failed to flush PMKSA");
> +}
> +
> struct netdev *netdev_create_from_genl(struct l_genl_msg *msg,
> const uint8_t *set_mac)
> {
> @@ -6544,6 +6610,8 @@ struct netdev *netdev_create_from_genl(struct l_genl_msg *msg,
>
> netdev_get_link(netdev);
>
> + netdev_flush_pmksa(netdev);
> +
> return netdev;
> }
>
> diff --git a/src/netdev.h b/src/netdev.h
> index 6299934e..0c7d7550 100644
> --- a/src/netdev.h
> +++ b/src/netdev.h
> @@ -218,6 +218,8 @@ int netdev_get_all_stations(struct netdev *netdev, netdev_get_station_cb_t cb,
>
> void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code);
>
> +void netdev_remove_pmksa(struct netdev *netdev);
> +
> struct netdev *netdev_find(int ifindex);
>
> uint32_t netdev_watch_add(netdev_watch_func_t func,