Modify the FST peer connection check so it won't skip peers without MB
IEs making it more permissive for peers that didn't provide MB IEs
during association request. This can be helpful, e.g., in cases where a
STA's interface connected before it was added to the FST group. This
allows the AP to receive FST Action frames and initiate session with a
STA via STA's interface that doesn't expose MB IEs.
The adjusted FST protocol is still safe, as it protects itself in many
other ways (checking band info and it's accordance to the interfaces,
Setup IDs, connection states of the interfaces involved, etc.)
effectively avoiding all types of invalid situations.
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
void fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
size_t len)
{
void fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
size_t len)
{
- if (fst_iface_is_connected(iface, mgmt->sa))
+ if (fst_iface_is_connected(iface, mgmt->sa, FALSE))
fst_session_on_action_rx(iface, mgmt, len);
else
wpa_printf(MSG_DEBUG,
fst_session_on_action_rx(iface, mgmt, len);
else
wpa_printf(MSG_DEBUG,
foreach_fst_group(g) {
foreach_fst_group_iface(g, f) {
foreach_fst_group(g) {
foreach_fst_group_iface(g, f) {
- if (fst_iface_is_connected(f, addr)) {
+ if (fst_iface_is_connected(f, addr, TRUE)) {
ret += print_band(num++, f, addr,
buf + ret, buflen - ret);
}
ret += print_band(num++, f, addr,
buf + ret, buflen - ret);
}
fst_mbie_get_peer_addr(mbie);
if (peer_addr &&
fst_mbie_get_peer_addr(mbie);
if (peer_addr &&
- fst_iface_is_connected(iface, peer_addr) &&
+ fst_iface_is_connected(iface, peer_addr,
+ TRUE) &&
band_id == fst_iface_get_band_id(iface)) {
os_memcpy(iface_peer_addr, peer_addr,
ETH_ALEN);
band_id == fst_iface_get_band_id(iface)) {
os_memcpy(iface_peer_addr, peer_addr,
ETH_ALEN);
-Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr)
+Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr,
+ Boolean mb_only)
{
struct fst_get_peer_ctx *ctx;
{
struct fst_get_peer_ctx *ctx;
- const u8 *a = fst_iface_get_peer_first(iface, &ctx, TRUE);
+ const u8 *a = fst_iface_get_peer_first(iface, &ctx, mb_only);
- for (; a != NULL; a = fst_iface_get_peer_next(iface, &ctx, TRUE))
+ for (; a != NULL; a = fst_iface_get_peer_next(iface, &ctx, mb_only))
if (os_memcmp(addr, a, ETH_ALEN) == 0)
return TRUE;
if (os_memcmp(addr, a, ETH_ALEN) == 0)
return TRUE;
return i->iface_obj.get_peer_next(i->iface_obj.ctx, ctx, mb_only);
}
return i->iface_obj.get_peer_next(i->iface_obj.ctx, ctx, mb_only);
}
-Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr);
+Boolean fst_iface_is_connected(struct fst_iface *iface, const u8 *addr,
+ Boolean mb_only);
void fst_iface_attach_mbie(struct fst_iface *i, struct wpabuf *mbie);
enum mb_band_id fst_iface_get_band_id(struct fst_iface *i);
void fst_iface_attach_mbie(struct fst_iface *i, struct wpabuf *mbie);
enum mb_band_id fst_iface_get_band_id(struct fst_iface *i);
- if (!fst_iface_is_connected(s->data.old_iface, s->data.old_peer_addr)) {
+ if (!fst_iface_is_connected(s->data.old_iface, s->data.old_peer_addr,
+ FALSE)) {
fst_printf_session(s, MSG_ERROR,
"The preset old peer address is not connected");
return -EINVAL;
}
fst_printf_session(s, MSG_ERROR,
"The preset old peer address is not connected");
return -EINVAL;
}
- if (!fst_iface_is_connected(s->data.new_iface, s->data.new_peer_addr)) {
+ if (!fst_iface_is_connected(s->data.new_iface, s->data.new_peer_addr,
+ FALSE)) {
fst_printf_session(s, MSG_ERROR,
"The preset new peer address is not connected");
return -EINVAL;
fst_printf_session(s, MSG_ERROR,
"The preset new peer address is not connected");
return -EINVAL;
- if (!fst_iface_is_connected(s->data.old_iface, s->data.old_peer_addr)) {
+ if (!fst_iface_is_connected(s->data.old_iface,
+ s->data.old_peer_addr, FALSE)) {
fst_printf_session(s, MSG_ERROR,
"The preset peer address is not in the peer list");
return -EINVAL;
fst_printf_session(s, MSG_ERROR,
"The preset peer address is not in the peer list");
return -EINVAL;