}
-int ap_sta_set_vlan(struct hostapd_data *hapd, struct sta_info *sta,
- struct vlan_description *vlan_desc)
+static int ap_sta_set_vlan_helper(struct hostapd_data *hapd,
+ struct sta_info *sta,
+ struct vlan_description *vlan_desc)
{
struct hostapd_vlan *vlan = NULL, *wildcard_vlan = NULL;
struct hostapd_data *vlan_bss = hapd;
}
-int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta)
+int ap_sta_set_vlan(struct hostapd_data *hapd, struct sta_info *sta,
+ struct vlan_description *vlan_desc)
+{
+ int ret;
+#ifdef CONFIG_IEEE80211BE
+ size_t i;
+#endif /* CONFIG_IEEE80211BE */
+ struct hapd_interfaces *interfaces = hapd->iface->interfaces;
+
+ ret = ap_sta_set_vlan_helper(hapd, sta, vlan_desc);
+ if (ret)
+ return ret;
+#ifdef CONFIG_IEEE80211BE
+ for (i = 0; interfaces && i < interfaces->count; i++) {
+ struct sta_info *tmp_sta;
+ struct hostapd_data *tmp_hapd = interfaces->iface[i]->bss[0];
+
+ if (!tmp_hapd->conf->mld_ap ||
+ hapd == tmp_hapd ||
+ !hostapd_is_ml_partner(hapd, tmp_hapd))
+ continue;
+
+ tmp_sta = ap_get_sta(tmp_hapd, sta->addr);
+ if (tmp_sta)
+ ap_sta_set_vlan_helper(tmp_hapd, tmp_sta, vlan_desc);
+ }
+
+#endif /* CONFIG_IEEE80211BE */
+
+ return 0;
+}
+
+
+static int ap_sta_bind_vlan_helper(struct hostapd_data *hapd,
+ struct sta_info *sta)
{
#ifndef CONFIG_NO_VLAN
const char *iface;
HOSTAPD_LEVEL_DEBUG, "binding station to interface "
"'%s'", iface);
- if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
+ if (wpa_auth_sta_set_vlan(sta->wpa_sm, hapd->wpa_auth,
+ sta->vlan_id) < 0)
wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
ret = hostapd_drv_set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id,
}
+int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta)
+{
+ int ret;
+#ifdef CONFIG_IEEE80211BE
+ size_t i;
+#endif /* CONFIG_IEEE80211BE */
+ struct hapd_interfaces *interfaces = hapd->iface->interfaces;
+
+ ret = ap_sta_bind_vlan_helper(hapd, sta);
+ if (ret)
+ return ret;
+#ifdef CONFIG_IEEE80211BE
+ for (i = 0; interfaces && i < interfaces->count; i++) {
+ struct sta_info *tmp_sta;
+ struct hostapd_data *tmp_hapd = interfaces->iface[i]->bss[0];
+
+ if (!tmp_hapd->conf->mld_ap ||
+ hapd == tmp_hapd ||
+ !hostapd_is_ml_partner(hapd, tmp_hapd))
+ continue;
+
+ tmp_sta = ap_get_sta(tmp_hapd, sta->addr);
+ if (tmp_sta)
+ ap_sta_bind_vlan_helper(tmp_hapd, tmp_sta);
+ }
+#endif /* CONFIG_IEEE80211BE */
+
+ return 0;
+}
+
+
void ap_sta_set_sa_query_timeout(struct hostapd_data *hapd,
struct sta_info *sta, int value)
{
struct wpa_group *group);
static void wpa_group_put(struct wpa_authenticator *wpa_auth,
struct wpa_group *group);
+static void wpa_group_put_vlan(struct wpa_authenticator *wpa_auth,
+ int vlan_id);
static int ieee80211w_kde_len(struct wpa_state_machine *sm);
static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos);
static void wpa_group_update_gtk(struct wpa_authenticator *wpa_auth,
wpa_auth = link->wpa_auth;
if (wpa_auth) {
link->wpa_auth = NULL;
- wpa_group_put(wpa_auth, wpa_auth->group);
+ wpa_group_put_vlan(wpa_auth, sm->group->vlan_id);
}
}
}
wpa_auth = sm->mld_links[link_id].wpa_auth;
sm->mld_links[link_id].wpa_auth = NULL;
sm->mld_links[link_id].valid = false;
- wpa_group_put(wpa_auth, wpa_auth->group);
+ wpa_group_put_vlan(wpa_auth, sm->group->vlan_id);
}
#endif /* CONFIG_IEEE80211BE */
wpa_group_put(sm->wpa_auth, sm->group);
u8 rsc[WPA_KEY_RSC_LEN];
wpa_printf(MSG_DEBUG,
- "MLD: Get group key info: link_id=%u, IGTK=%u, BIGTK=%u",
- info->link_id, mgmt_frame_prot, beacon_prot);
+ "MLD: Get group key info: link_id=%u, IGTK=%u, BIGTK=%u VLAN ID:%d",
+ info->link_id, mgmt_frame_prot, beacon_prot, vlan_id);
if (vlan_id)
gsm = wpa_select_vlan_wpa_group(gsm, vlan_id);
}
+static void wpa_group_put_vlan(struct wpa_authenticator *wpa_auth,
+ int vlan_id)
+{
+ struct wpa_group *vlan_group =
+ wpa_select_vlan_wpa_group(wpa_auth->group, vlan_id);
+
+ wpa_group_put(wpa_auth, vlan_group);
+}
+
+
/*
* Add a group that has its references counter set to zero. Caller needs to
* call wpa_group_get() on the return value to mark the entry in use.
}
-int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
+int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm,
+ struct wpa_authenticator *wpa_auth, int vlan_id)
{
struct wpa_group *group;
if (!sm || !sm->wpa_auth)
return 0;
- group = sm->wpa_auth->group;
+ group = wpa_auth->group;
while (group) {
if (group->vlan_id == vlan_id)
break;
}
if (!group) {
- group = wpa_auth_add_group(sm->wpa_auth, vlan_id);
+ group = wpa_auth_add_group(wpa_auth, vlan_id);
if (!group)
return -1;
}
+#ifdef CONFIG_IEEE80211BE
+ if (sm->mld_assoc_link_id >= 0 &&
+ (sm->mld_assoc_link_id != wpa_auth->link_id)) {
+ wpa_group_get(wpa_auth, group);
+ return 0;
+ }
+#endif /* CONFIG_IEEE80211BE */
+
if (sm->group == group)
return 0;
struct wpa_state_machine *sm,
struct wpa_authenticator *wpa_auth,
u8 *pmkid, u8 *pmk, size_t *pmk_len);
-int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id);
+int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm,
+ struct wpa_authenticator *wpa_auth, int vlan_id);
void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm, int ack);