P2P: Fix Action frame processing if Interworking is enabled
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 4 Feb 2013 13:38:35 +0000 (15:38 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 4 Feb 2013 13:38:35 +0000 (15:38 +0200)
GAS server used the same public_action_cb mechanism as P2P to process
Action frames. This ended up overriding P2P processing of Action frames
while running an AP/GO interface with a build that enables Interworking
(e.g., for Hotspot 2.0) and a driver that uses hostapd for AP mode
SME/MLME. Fix this by adding a separate callback registration for the
GAS server. This should really be cleaned up by supporting arbitrary
number of callback handlers, but for now, this addresses the regression
with a minimal change.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/ap/gas_serv.c
src/ap/hostapd.h
src/ap/ieee802_11.c

index 851c183..b3574ba 100644 (file)
@@ -1158,8 +1158,8 @@ static void gas_serv_rx_public_action(void *ctx, const u8 *buf, size_t len,
 
 int gas_serv_init(struct hostapd_data *hapd)
 {
-       hapd->public_action_cb = gas_serv_rx_public_action;
-       hapd->public_action_cb_ctx = hapd;
+       hapd->public_action_cb2 = gas_serv_rx_public_action;
+       hapd->public_action_cb2_ctx = hapd;
        hapd->gas_frag_limit = 1400;
        if (hapd->conf->gas_frag_limit > 0)
                hapd->gas_frag_limit = hapd->conf->gas_frag_limit;
index c9087b3..2827232 100644 (file)
@@ -151,6 +151,9 @@ struct hostapd_data {
        void (*public_action_cb)(void *ctx, const u8 *buf, size_t len,
                                 int freq);
        void *public_action_cb_ctx;
+       void (*public_action_cb2)(void *ctx, const u8 *buf, size_t len,
+                                 int freq);
+       void *public_action_cb2_ctx;
 
        int (*vendor_action_cb)(void *ctx, const u8 *buf, size_t len,
                                int freq);
index 79235df..129c5b5 100644 (file)
@@ -1599,8 +1599,14 @@ static void handle_action(struct hostapd_data *hapd,
                        hapd->public_action_cb(hapd->public_action_cb_ctx,
                                               (u8 *) mgmt, len,
                                               hapd->iface->freq);
-                       return;
                }
+               if (hapd->public_action_cb2) {
+                       hapd->public_action_cb2(hapd->public_action_cb_ctx,
+                                               (u8 *) mgmt, len,
+                                               hapd->iface->freq);
+               }
+               if (hapd->public_action_cb || hapd->public_action_cb2)
+                       return;
                break;
        case WLAN_ACTION_VENDOR_SPECIFIC:
                if (hapd->vendor_action_cb) {