]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Add ctrl iface indications for WDS STA interface
authorBhagavathi Perumal S <bperumal@codeaurora.org>
Fri, 20 Apr 2018 09:05:36 +0000 (14:35 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 23 Apr 2018 21:35:47 +0000 (00:35 +0300)
This allows user to get event indication when a new interface is
added/removed for 4addr WDS STA and also WDS STA ifname is informed
through the STA command.

Signed-off-by: Bhagavathi Perumal S <bperumal@codeaurora.org>
src/ap/ctrl_iface_ap.c
src/ap/drv_callbacks.c
src/ap/sta_info.c
src/ap/sta_info.h
src/common/wpa_ctrl.h
src/drivers/driver.h
src/drivers/driver_common.c
src/drivers/driver_nl80211.c

index f230bd41932563ffb10a0d4cadfc0fb3e5fa0f86..21b813ee18d775b5bf7a6cbfcd2bf8ab88dcdfea 100644 (file)
@@ -334,6 +334,13 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
                len += os_snprintf(buf + len, buflen - len, "\n");
        }
 
+       if (sta->flags & WLAN_STA_WDS && sta->ifname_wds) {
+               ret = os_snprintf(buf + len, buflen - len,
+                                 "wds_sta_ifname=%s\n", sta->ifname_wds);
+               if (!os_snprintf_error(buflen - len, ret))
+                       len += ret;
+       }
+
        return len;
 }
 
index 59299ad1bd2ecbf3ad3a58ec6012d9c0f046da10..61f8862380032050756b6f77c746203f0f849462 100644 (file)
@@ -1481,6 +1481,28 @@ static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
 #endif /* NEED_AP_MLME */
 
 
+static void hostapd_event_wds_sta_interface_status(struct hostapd_data *hapd,
+                                                  int istatus,
+                                                  const char *ifname,
+                                                  const u8 *addr)
+{
+       struct sta_info *sta = ap_get_sta(hapd, addr);
+
+       if (sta) {
+               os_free(sta->ifname_wds);
+               if (istatus == INTERFACE_ADDED)
+                       sta->ifname_wds = os_strdup(ifname);
+               else
+                       sta->ifname_wds = NULL;
+       }
+
+       wpa_msg(hapd->msg_ctx, MSG_INFO, "%sifname=%s sta_addr=" MACSTR,
+               istatus == INTERFACE_ADDED ?
+               WDS_STA_INTERFACE_ADDED : WDS_STA_INTERFACE_REMOVED,
+               ifname, MAC2STR(addr));
+}
+
+
 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                          union wpa_event_data *data)
 {
@@ -1695,6 +1717,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                                 data->sta_opmode.chan_width,
                                                 data->sta_opmode.rx_nss);
                break;
+       case EVENT_WDS_STA_INTERFACE_STATUS:
+               hostapd_event_wds_sta_interface_status(
+                       hapd, data->wds_sta_interface.istatus,
+                       data->wds_sta_interface.ifname,
+                       data->wds_sta_interface.sta_addr);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "Unknown event %d", event);
                break;
index cb9be283276ca1665fda1bcd53a2347e5c44e6f8..5e2f055d3b36ad4c6732daa47cf60e3560a8a05b 100644 (file)
@@ -366,6 +366,8 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
 #endif /* CONFIG_WNM_AP */
 
+       os_free(sta->ifname_wds);
+
        os_free(sta);
 }
 
index 896a2b54c77ae235275fdf09fa9c188e29d14646..74910d1d23e51de4fa10ee70acf1c3177858390d 100644 (file)
@@ -257,6 +257,7 @@ struct sta_info {
 #endif /* CONFIG_OWE */
 
        u8 *ext_capability;
+       char *ifname_wds; /* WDS ifname, if in use */
 
 #ifdef CONFIG_TESTING_OPTIONS
        enum wpa_alg last_tk_alg;
index a0a11397b30d2516a40ba78375c3bb145497c6d1..cc481a1cda7c46d128e9d8297417f8724d03d16b 100644 (file)
@@ -351,6 +351,10 @@ extern "C" {
 #define STA_OPMODE_SMPS_MODE_CHANGED "STA-OPMODE-SMPS-MODE-CHANGED "
 #define STA_OPMODE_N_SS_CHANGED "STA-OPMODE-N_SS-CHANGED "
 
+/* New interface addition or removal for 4addr WDS SDA */
+#define WDS_STA_INTERFACE_ADDED "WDS-STA-INTERFACE-ADDED "
+#define WDS_STA_INTERFACE_REMOVED "WDS-STA-INTERFACE-REMOVED "
+
 /* BSS command information masks */
 
 #define WPA_BSS_MASK_ALL               0xFFFDFFFF
index d7aeef99ccb6328ca3649a31ac93d8c7f84f953b..9922962ea1fa35926ed6f3a71e8e2f64f3663dfd 100644 (file)
@@ -4594,6 +4594,13 @@ enum wpa_event_type {
         * must be always assumed that the MAC possibly changed.
         */
        EVENT_INTERFACE_MAC_CHANGED,
+
+       /**
+        * EVENT_WDS_STA_INTERFACE_STATUS - Notify WDS STA interface status
+        *
+        * This event is emitted when an interface is added/removed for WDS STA.
+        */
+       EVENT_WDS_STA_INTERFACE_STATUS,
 };
 
 
@@ -5415,6 +5422,18 @@ union wpa_event_data {
                enum chan_width chan_width;
                u8 rx_nss;
        } sta_opmode;
+
+       /**
+        * struct wds_sta_interface - Data for EVENT_WDS_STA_INTERFACE_STATUS.
+        */
+       struct wds_sta_interface {
+               const u8 *sta_addr;
+               const char *ifname;
+               enum {
+                       INTERFACE_ADDED,
+                       INTERFACE_REMOVED
+               } istatus;
+       } wds_sta_interface;
 };
 
 /**
index ca4668aa86b9294cba3bfd6358e64d1386fb9e15..e773a9d1aad2426bc529e0415aa14fc0d4c8445f 100644 (file)
@@ -86,6 +86,7 @@ const char * event_to_string(enum wpa_event_type event)
        E2S(PORT_AUTHORIZED);
        E2S(STATION_OPMODE_CHANGED);
        E2S(INTERFACE_MAC_CHANGED);
+       E2S(WDS_STA_INTERFACE_STATUS);
        }
 
        return "UNKNOWN";
index 34003476464fe92e5b8ed4689de4e2c9f3c33af3..0c5c6bb6f7981098a518de044382f49b12c40d8b 100644 (file)
@@ -6511,6 +6511,7 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
        struct i802_bss *bss = priv;
        struct wpa_driver_nl80211_data *drv = bss->drv;
        char name[IFNAMSIZ + 1];
+       union wpa_event_data event;
 
        os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
        if (ifname_wds)
@@ -6529,6 +6530,14 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
                            linux_br_add_if(drv->global->ioctl_sock,
                                            bridge_ifname, name) < 0)
                                return -1;
+
+                       os_memset(&event, 0, sizeof(event));
+                       event.wds_sta_interface.sta_addr = addr;
+                       event.wds_sta_interface.ifname = name;
+                       event.wds_sta_interface.istatus = INTERFACE_ADDED;
+                       wpa_supplicant_event(drv->ctx,
+                                            EVENT_WDS_STA_INTERFACE_STATUS,
+                                            &event);
                }
                if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
                        wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
@@ -6542,6 +6551,12 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
 
                i802_set_sta_vlan(priv, addr, bss->ifname, 0);
                nl80211_remove_iface(drv, if_nametoindex(name));
+               os_memset(&event, 0, sizeof(event));
+               event.wds_sta_interface.sta_addr = addr;
+               event.wds_sta_interface.ifname = name;
+               event.wds_sta_interface.istatus = INTERFACE_REMOVED;
+               wpa_supplicant_event(drv->ctx, EVENT_WDS_STA_INTERFACE_STATUS,
+                                    &event);
                return 0;
        }
 }