Merge bss_add/bss_remove drivers ops into if_add/if_remove
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 9 Dec 2009 14:49:28 +0000 (16:49 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 9 Dec 2009 14:49:28 +0000 (16:49 +0200)
if_add/if_remove can now be used as the generic driver ops for adding
and removing virtual interfaces of various types. In addition,
driver_nl80211.c is now including this code unconditionally, so that
the functions are not limited only for hostapd.

hostapd/driver_i.h
hostapd/hostapd.c
hostapd/vlan_init.c
src/drivers/driver.h
src/drivers/driver_ndis.c
src/drivers/driver_nl80211.c
src/drivers/driver_test.c

index f1cac8f..e6e3400 100644 (file)
@@ -372,22 +372,6 @@ hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
 }
 
 static inline int
-hostapd_bss_add(struct hostapd_data *hapd, const char *ifname, const u8 *bssid)
-{
-       if (hapd->driver == NULL || hapd->driver->bss_add == NULL)
-               return 0;
-       return hapd->driver->bss_add(hapd->drv_priv, ifname, bssid);
-}
-
-static inline int
-hostapd_bss_remove(struct hostapd_data *hapd, const char *ifname)
-{
-       if (hapd->driver == NULL || hapd->driver->bss_remove == NULL)
-               return 0;
-       return hapd->driver->bss_remove(hapd->drv_priv, ifname);
-}
-
-static inline int
 hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
                       const u8 *mask)
 {
@@ -397,8 +381,8 @@ hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
 }
 
 static inline int
-hostapd_if_add(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
-              char *ifname, const u8 *addr)
+hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
+              const char *ifname, const u8 *addr)
 {
        if (hapd->driver == NULL || hapd->driver->if_add == NULL)
                return -1;
@@ -407,12 +391,12 @@ hostapd_if_add(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
 }
 
 static inline int
-hostapd_if_remove(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
-                 char *ifname, const u8 *addr)
+hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
+                 const char *ifname)
 {
        if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
                return -1;
-       return hapd->driver->if_remove(hapd->drv_priv, type, ifname, addr);
+       return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
 }
 
 static inline struct hostapd_hw_modes *
index cd68eba..fc7a5ff 100644 (file)
@@ -340,7 +340,7 @@ static void hostapd_cleanup(struct hostapd_data *hapd)
 #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
 
        if (hapd->interface_added &&
-           hostapd_bss_remove(hapd, hapd->conf->iface)) {
+           hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
                wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
                           hapd->conf->iface);
        }
@@ -1048,8 +1048,8 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
                }
 
                hapd->interface_added = 1;
-               if (hostapd_bss_add(hapd->iface->bss[0], hapd->conf->iface,
-                                   hapd->own_addr)) {
+               if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
+                                  hapd->conf->iface, hapd->own_addr)) {
                        wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
                                   MACSTR ")", MAC2STR(hapd->own_addr));
                        return -1;
index c4f223b..ba23082 100644 (file)
@@ -680,8 +680,7 @@ static int vlan_dynamic_add(struct hostapd_data *hapd,
 {
        while (vlan) {
                if (vlan->vlan_id != VLAN_ID_WILDCARD &&
-                   hostapd_if_add(hapd, HOSTAPD_IF_VLAN, vlan->ifname, NULL))
-               {
+                   hostapd_if_add(hapd, WPA_IF_AP_VLAN, vlan->ifname, NULL)) {
                        if (errno != EEXIST) {
                                printf("Could not add VLAN iface: %s: %s\n",
                                       vlan->ifname, strerror(errno));
@@ -705,8 +704,7 @@ static void vlan_dynamic_remove(struct hostapd_data *hapd,
                next = vlan->next;
 
                if (vlan->vlan_id != VLAN_ID_WILDCARD &&
-                   hostapd_if_remove(hapd, HOSTAPD_IF_VLAN, vlan->ifname,
-                                     NULL)) {
+                   hostapd_if_remove(hapd, WPA_IF_AP_VLAN, vlan->ifname)) {
                        printf("Could not remove VLAN iface: %s: %s\n",
                               vlan->ifname, strerror(errno));
                }
@@ -777,7 +775,7 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd,
                    pos);
        os_free(ifname);
 
-       if (hostapd_if_add(hapd, HOSTAPD_IF_VLAN, n->ifname, NULL)) {
+       if (hostapd_if_add(hapd, WPA_IF_AP_VLAN, n->ifname, NULL)) {
                os_free(n);
                return NULL;
        }
@@ -809,7 +807,7 @@ int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id)
                return 1;
 
        if (vlan->dynamic_vlan == 0)
-               hostapd_if_remove(hapd, HOSTAPD_IF_VLAN, vlan->ifname, NULL);
+               hostapd_if_remove(hapd, WPA_IF_AP_VLAN, vlan->ifname);
 
        return 0;
 }
index a113064..32588d3 100644 (file)
@@ -458,8 +458,26 @@ struct hostapd_freq_params {
                                 * enabled, secondary channel above primary */
 };
 
-enum hostapd_driver_if_type {
-       HOSTAPD_IF_VLAN
+enum wpa_driver_if_type {
+       /**
+        * WPA_IF_STATION - Station mode interface
+        */
+       WPA_IF_STATION,
+
+       /**
+        * WPA_IF_AP_VLAN - AP mode VLAN interface
+        *
+        * This interface shares its address and Beacon frame with the main
+        * BSS.
+        */
+       WPA_IF_AP_VLAN,
+
+       /**
+        * WPA_IF_AP_BSS - AP mode BSS interface
+        *
+        * This interface has its own address and Beacon frame.
+        */
+       WPA_IF_AP_BSS,
 };
 
 struct wpa_init_params {
@@ -1117,14 +1135,31 @@ struct wpa_driver_ops {
        int (*set_short_slot_time)(void *priv, int value);
        int (*set_tx_queue_params)(void *priv, int queue, int aifs, int cw_min,
                                   int cw_max, int burst_time);
-       int (*bss_add)(void *priv, const char *ifname, const u8 *bssid);
-       int (*bss_remove)(void *priv, const char *ifname);
        int (*valid_bss_mask)(void *priv, const u8 *addr, const u8 *mask);
+
+       /**
+        * if_add - Add a virtual interface
+        * @priv: Private driver interface data
+        * @iface: Parent interface name
+        * @type: Interface type
+        * @ifname: Interface name for the new virtual interface
+        * @addr: Local address to use for the interface or %NULL to use the
+        *      parent interface address
+        * Returns: 0 on success, -1 on failure
+        */
        int (*if_add)(const char *iface, void *priv,
-                     enum hostapd_driver_if_type type, char *ifname,
+                     enum wpa_driver_if_type type, const char *ifname,
                      const u8 *addr);
-       int (*if_remove)(void *priv, enum hostapd_driver_if_type type,
-                        const char *ifname, const u8 *addr);
+
+       /**
+        * if_remove - Remove a virtual interface
+        * @priv: Private driver interface data
+        * @type: Interface type
+        * @ifname: Interface name of the virtual interface to be removed
+        * Returns: 0 on success, -1 on failure
+        */
+       int (*if_remove)(void *priv, enum wpa_driver_if_type type,
+                        const char *ifname);
        int (*set_sta_vlan)(void *priv, const u8 *addr, const char *ifname,
                            int vlan_id);
        /**
index 40d6259..f8663bc 100644 (file)
@@ -3235,8 +3235,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
        NULL /* set_preamble */,
        NULL /* set_short_slot_time */,
        NULL /* set_tx_queue_params */,
-       NULL /* bss_add */,
-       NULL /* bss_remove */,
        NULL /* valid_bss_mask */,
        NULL /* if_add */,
        NULL /* if_remove */,
index e03ee9f..b8651e2 100644 (file)
@@ -2743,6 +2743,8 @@ static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
        return -ENOBUFS;
 }
 
+#endif /* CONFIG_AP || HOSTAPD */
+
 
 static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
                                 int ifidx)
@@ -2832,6 +2834,8 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
 
        return ifidx;
 }
+
+
 static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
                                const char *ifname, enum nl80211_iftype iftype,
                                const u8 *addr)
@@ -2854,7 +2858,6 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
        return ret;
 }
 
-#endif /* CONFIG_AP || HOSTAPD */
 
 #ifdef CONFIG_AP
 
@@ -4257,54 +4260,6 @@ static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
 }
 
 
-static int i802_bss_add(void *priv, const char *ifname, const u8 *bssid)
-{
-       struct wpa_driver_nl80211_data *drv = priv;
-       int ifidx;
-       struct i802_bss *bss;
-
-       bss = os_zalloc(sizeof(*bss));
-       if (bss == NULL)
-               return -1;
-
-       ifidx = nl80211_create_iface(priv, ifname, NL80211_IFTYPE_AP, bssid);
-       if (ifidx < 0) {
-               os_free(bss);
-               return -1;
-       }
-       bss->ifindex = ifidx;
-       if (hostapd_set_iface_flags(priv, ifname, 1)) {
-               nl80211_remove_iface(priv, ifidx);
-               os_free(bss);
-               return -1;
-       }
-       bss->next = drv->bss.next;
-       drv->bss.next = bss;
-       return 0;
-}
-
-
-static int i802_bss_remove(void *priv, const char *ifname)
-{
-       struct wpa_driver_nl80211_data *drv = priv;
-       struct i802_bss *bss, *prev;
-       int ifindex = if_nametoindex(ifname);
-       nl80211_remove_iface(priv, ifindex);
-       prev = &drv->bss;
-       bss = drv->bss.next;
-       while (bss) {
-               if (ifindex == bss->ifindex) {
-                       prev->next = bss->next;
-                       os_free(bss);
-                       break;
-               }
-               prev = bss;
-               bss = bss->next;
-       }
-       return 0;
-}
-
-
 static int i802_set_bss(void *priv, int cts, int preamble, int slot)
 {
        struct wpa_driver_nl80211_data *drv = priv;
@@ -4351,34 +4306,6 @@ static int i802_set_short_slot_time(void *priv, int value)
 }
 
 
-static enum nl80211_iftype i802_if_type(enum hostapd_driver_if_type type)
-{
-       switch (type) {
-       case HOSTAPD_IF_VLAN:
-               return NL80211_IFTYPE_AP_VLAN;
-       }
-       return -1;
-}
-
-
-static int i802_if_add(const char *iface, void *priv,
-                      enum hostapd_driver_if_type type, char *ifname,
-                      const u8 *addr)
-{
-       if (nl80211_create_iface(priv, ifname, i802_if_type(type), addr) < 0)
-               return -1;
-       return 0;
-}
-
-
-static int i802_if_remove(void *priv, enum hostapd_driver_if_type type,
-                         const char *ifname, const u8 *addr)
-{
-       nl80211_remove_iface(priv, if_nametoindex(ifname));
-       return 0;
-}
-
-
 static int i802_set_sta_vlan(void *priv, const u8 *addr,
                             const char *ifname, int vlan_id)
 {
@@ -4568,6 +4495,93 @@ static void i802_deinit(void *priv)
 #endif /* HOSTAPD */
 
 
+static enum nl80211_iftype wpa_driver_nl80211_if_type(
+       enum wpa_driver_if_type type)
+{
+       switch (type) {
+       case WPA_IF_STATION:
+               return NL80211_IFTYPE_STATION;
+       case WPA_IF_AP_VLAN:
+               return NL80211_IFTYPE_AP_VLAN;
+       case WPA_IF_AP_BSS:
+               return NL80211_IFTYPE_AP;
+       }
+       return -1;
+}
+
+
+static int wpa_driver_nl80211_if_add(const char *iface, void *priv,
+                                    enum wpa_driver_if_type type,
+                                    const char *ifname, const u8 *addr)
+{
+       struct wpa_driver_nl80211_data *drv = priv;
+       int ifidx;
+#ifdef HOSTAPD
+       struct i802_bss *bss = NULL;
+
+       if (type == WPA_IF_AP_BSS) {
+               bss = os_zalloc(sizeof(*bss));
+               if (bss == NULL)
+                       return -1;
+       }
+#endif /* HOSTAPD */
+
+       ifidx = nl80211_create_iface(drv, ifname,
+                                    wpa_driver_nl80211_if_type(type), addr);
+       if (ifidx < 0) {
+#ifdef HOSTAPD
+               os_free(bss);
+#endif /* HOSTAPD */
+               return -1;
+       }
+
+#ifdef HOSTAPD
+       if (type == WPA_IF_AP_BSS) {
+               if (hostapd_set_iface_flags(priv, ifname, 1)) {
+                       nl80211_remove_iface(priv, ifidx);
+                       os_free(bss);
+                       return -1;
+               }
+               bss->ifindex = ifidx;
+               bss->next = drv->bss.next;
+               drv->bss.next = bss;
+       }
+#endif /* HOSTAPD */
+
+       return 0;
+}
+
+
+static int wpa_driver_nl80211_if_remove(void *priv,
+                                       enum wpa_driver_if_type type,
+                                       const char *ifname)
+{
+       struct wpa_driver_nl80211_data *drv = priv;
+       int ifindex = if_nametoindex(ifname);
+
+       nl80211_remove_iface(drv, ifindex);
+
+#ifdef HOSTAPD
+       if (type == WPA_IF_AP_BSS) {
+               struct i802_bss *bss, *prev;
+               prev = &drv->bss;
+               bss = drv->bss.next;
+               while (bss) {
+                       if (ifindex == bss->ifindex) {
+                               prev->next = bss->next;
+                               os_free(bss);
+                               break;
+                       }
+                       prev = bss;
+                       bss = bss->next;
+               }
+       }
+#endif /* HOSTAPD */
+
+       return 0;
+}
+
+
 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .name = "nl80211",
        .desc = "Linux nl80211/cfg80211",
@@ -4587,6 +4601,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .set_supp_port = wpa_driver_nl80211_set_supp_port,
        .set_country = wpa_driver_nl80211_set_country,
        .set_beacon = wpa_driver_nl80211_set_beacon,
+       .if_add = wpa_driver_nl80211_if_add,
+       .if_remove = wpa_driver_nl80211_if_remove,
 #if defined(CONFIG_AP) || defined(HOSTAPD)
        .send_mlme = wpa_driver_nl80211_send_mlme,
        .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
@@ -4613,10 +4629,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .set_preamble = i802_set_preamble,
        .set_short_slot_time = i802_set_short_slot_time,
        .set_tx_queue_params = i802_set_tx_queue_params,
-       .bss_add = i802_bss_add,
-       .bss_remove = i802_bss_remove,
-       .if_add = i802_if_add,
-       .if_remove = i802_if_remove,
        .set_sta_vlan = i802_set_sta_vlan,
 #endif /* HOSTAPD */
 };
index 5952421..a88e4ab 100644 (file)
@@ -1044,19 +1044,23 @@ static int test_driver_bss_remove(void *priv, const char *ifname)
 
 
 static int test_driver_if_add(const char *iface, void *priv,
-                             enum hostapd_driver_if_type type, char *ifname,
+                             enum wpa_driver_if_type type, const char *ifname,
                              const u8 *addr)
 {
        wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s)",
                   __func__, iface, type, ifname);
+       if (type == WPA_IF_AP_BSS)
+               return test_driver_bss_add(priv, ifname, addr);
        return 0;
 }
 
 
-static int test_driver_if_remove(void *priv, enum hostapd_driver_if_type type,
-                                const char *ifname, const u8 *addr)
+static int test_driver_if_remove(void *priv, enum wpa_driver_if_type type,
+                                const char *ifname)
 {
        wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
+       if (type == WPA_IF_AP_BSS)
+               return test_driver_bss_remove(priv, ifname);
        return 0;
 }
 
@@ -2473,8 +2477,6 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
        .sta_deauth = test_driver_sta_deauth,
        .sta_disassoc = test_driver_sta_disassoc,
        .get_hw_feature_data = wpa_driver_test_get_hw_feature_data,
-       .bss_add = test_driver_bss_add,
-       .bss_remove = test_driver_bss_remove,
        .if_add = test_driver_if_add,
        .if_remove = test_driver_if_remove,
        .valid_bss_mask = test_driver_valid_bss_mask,