Message ID | 20250212162401.130792-4-prestwoj@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | PMKSA support for fullmac drivers | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
prestwoj/iwd-ci-gitlint | success | GitLint |
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,
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); + + /* + * 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,