From 19ef6da36d31b848cefb453e222b96916e01f240 Mon Sep 17 00:00:00 2001 From: Ramanathan Choodamani Date: Thu, 4 Jan 2024 21:18:34 -0800 Subject: [PATCH] hostapd: Add support to indicate presence of an MLD for creating bonded netdev Add support to notify the driver using vendor subcmd about the presence of a multi link MLD for creating a bonded netdevice before the first link is added. The driver uses this information to differentiate between an SLD and an MLD Signed-off by: Balamurugan Mahalingam Signed-off-by: Ramanathan Choodamani --- hostapd/main.c | 3 +++ src/ap/ap_drv_ops.c | 10 ++++++++ src/ap/ap_drv_ops.h | 1 + src/ap/drv_callbacks.c | 7 ++++++ src/ap/hostapd.c | 6 ++++- src/ap/hostapd.h | 1 + src/common/qca-vendor.h | 11 +++++++++ src/drivers/driver.h | 5 ++++ src/drivers/driver_nl80211.c | 45 ++++++++++++++++++++++++++++++++++++ 9 files changed, 88 insertions(+), 1 deletion(-) --- a/hostapd/main.c +++ b/hostapd/main.c @@ -169,6 +169,7 @@ static int hostapd_driver_init(struct ho u8 *b = conf->bssid; struct wpa_driver_capa capa; struct hostapd_data *h_hapd = NULL; + struct wpabuf *buf; if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) { wpa_printf(MSG_ERROR, "No hostapd driver wrapper available"); @@ -342,6 +343,8 @@ setup_mld: hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr), MAC2STR(hapd->own_addr)); + if (hapd->mld && hapd->mld->is_ml_netdev) + hostapd_drv_mark_mlnetdev(hapd); hostapd_drv_link_add(hapd, hapd->mld_link_id, hapd->own_addr); } --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -24,6 +24,7 @@ #include "ap_drv_ops.h" #ifdef CONFIG_IEEE80211BE #include "scs.h" +#include "common/qca-vendor.h" #endif u32 hostapd_sta_flags_to_drv(u32 flags) @@ -421,6 +422,15 @@ int hostapd_set_scs_params(struct hostap os_memcpy(scs_drv.peer_mac, scs_m->peer_mac, 6); return hapd->driver->set_scs(hapd->drv_priv, &scs_drv); } + +int hostapd_drv_mark_mlnetdev(struct hostapd_data *hapd) +{ + if (hapd->driver == NULL || hapd->driver->mark_mlnetdev == NULL) + return -1; + return hapd->driver->mark_mlnetdev(hapd->drv_priv, + OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION, NULL, + 0, 0, NULL); +} #endif int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr, --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -155,6 +155,7 @@ int hostapd_drv_set_secure_ranging_ctx(s #ifdef CONFIG_IEEE80211BE int hostapd_set_scs_params(struct hostapd_data *hapd, struct sta_info *sta, struct hostapd_qos_mandatory_scs_param *scs_m, u8 req_type); +int hostapd_drv_mark_mlnetdev(struct hostapd_data *hapd); #endif #include "drivers/driver.h" --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -2183,10 +2183,14 @@ static void hostapd_mld_if_disable(struc static void hostapd_mld_if_enable(struct hostapd_data *hapd) { struct hostapd_data *first_link, *link_bss; + struct wpabuf *buf; + buf = wpabuf_alloc(1024); first_link = hostapd_mld_is_first_bss(hapd) ? hapd : hostapd_mld_get_first_bss(hapd); + if (hapd->mld && hapd->mld->is_ml_netdev) + hostapd_drv_mark_mlnetdev(hapd); /* Links are removed at this stage. Re-add all links and enable them. * But enable first link BSS first. */ @@ -2203,6 +2207,7 @@ static void hostapd_mld_if_enable(struct for_each_partner_bss(link_bss, first_link) { if (link_bss == first_link) continue; + hostapd_drv_mark_mlnetdev(hapd); if (hostapd_drv_link_add(link_bss, link_bss->mld_link_id, link_bss->own_addr)) { @@ -2213,6 +2218,8 @@ static void hostapd_mld_if_enable(struct hostpad_if_enable(link_bss); } + + wpabuf_free(buf); } --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1396,6 +1396,7 @@ static int hostapd_setup_bss(struct host u8 if_addr[ETH_ALEN]; int flush_old_stations = 1; struct hostapd_data *h_hapd = NULL; + struct wpabuf *buf; #ifdef CONFIG_IEEE80211BE if (!hostapd_mld_is_first_bss(hapd)) @@ -1706,7 +1707,8 @@ setup_mld: ", own_addr=" MACSTR, hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr), MAC2STR(hapd->own_addr)); - + if (hapd->mld && hapd->mld->is_ml_netdev) + hostapd_drv_mark_mlnetdev(hapd); hostapd_drv_link_add(hapd, hapd->mld_link_id, hapd->own_addr); } @@ -3060,6 +3062,8 @@ static void hostapd_bss_alloc_link_id(st hapd->mld_link_id = hapd->mld->next_link_id++; wpa_printf(MSG_DEBUG, "MLD: %s: Link ID %d assigned.", hapd->mld->name, hapd->mld_link_id); + if (hapd->mld_link_id > 0) + hapd->mld->is_ml_netdev = true; } static void hostapd_bss_setup_multi_link(struct hostapd_data *hapd, --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -578,6 +578,7 @@ struct hostapd_mld { * not be freed when it is 0. */ u8 refcount; + bool is_ml_netdev; struct hostapd_data *fbss; struct dl_list links; /* List HEAD of all affiliated links */ --- a/src/common/qca-vendor.h +++ b/src/common/qca-vendor.h @@ -1236,6 +1236,7 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG = 230, QCA_NL80211_VENDOR_SUBCMD_TDLS_DISC_RSP_EXT = 231, /* 232 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_DS_ML_DEV = 238, }; /* Compatibility defines for previously used subcmd names. @@ -16007,5 +16008,4 @@ enum qca_wlan_vendor_attr_tdls_state { QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX = QCA_WLAN_VENDOR_ATTR_TDLS_STATE_AFTER_LAST - 1, }; - #endif /* QCA_VENDOR_H */ --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -5322,6 +5322,11 @@ struct wpa_driver_ops { u8 *num_multi_hws); #ifdef CONFIG_IEEE80211BE int (*set_scs)(void *priv, struct scs_latency_params *scs_drv); + + int (*mark_mlnetdev)(void *priv, unsigned int vendor_id, + unsigned int subcmd, const u8 *data, size_t data_len, + enum nested_attr nested_attr_flag, + struct wpabuf *buf); #endif }; --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -11692,6 +11692,42 @@ static bool is_cmd_with_nested_attrs(uns } } +static int nl80211_vendor_cmd_ds(void *priv, unsigned int vendor_id, + unsigned int subcmd, const u8 *data, + size_t data_len, enum nested_attr nested_attr, + struct wpabuf *buf) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *attr; + int ret; + struct wpabuf *replybuf; + + wpa_printf(MSG_ERROR," vendor commands ds"); + if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, vendor_id) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd)) + goto fail; + + attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_EHT_MLO_MODE, 1); + nla_nest_end(msg, attr); + + replybuf = wpabuf_alloc(1024); + ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, replybuf, + NULL, NULL); + if (ret) + wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d", + ret); + wpa_printf(MSG_ERROR," vendor commands ds sent successfully"); + wpabuf_free(replybuf); + return ret; +fail: + nlmsg_free(msg); + return -ENOBUFS; +} + static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id, unsigned int subcmd, const u8 *data, @@ -11700,6 +11736,7 @@ static int nl80211_vendor_cmd(void *priv { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; + char data1[2000]; struct nl_msg *msg; int ret, nla_flag; @@ -14488,6 +14525,7 @@ const struct wpa_driver_ops wpa_driver_n .get_drv_shared_status = wpa_driver_get_shared_status, .can_share_drv = wpa_driver_nl80211_can_share_drv, .set_scs = nl80211_set_scs, + .mark_mlnetdev = nl80211_vendor_cmd_ds, #endif /* CONFIG_IEEE80211BE */ .get_multi_hw_info = wpa_driver_get_multi_hw_info, };