Browse Source

Merge bss_add/bss_remove drivers ops into if_add/if_remove

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.
Jouni Malinen 15 years ago
parent
commit
22a7c9d735

+ 5 - 21
hostapd/driver_i.h

@@ -371,22 +371,6 @@ hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
 						 cw_min, cw_max, burst_time);
 						 cw_min, cw_max, burst_time);
 }
 }
 
 
-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
 static inline int
 hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
 hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
 		       const u8 *mask)
 		       const u8 *mask)
@@ -397,8 +381,8 @@ hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr,
 }
 }
 
 
 static inline int
 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)
 	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
 		return -1;
 		return -1;
@@ -407,12 +391,12 @@ hostapd_if_add(struct hostapd_data *hapd, enum hostapd_driver_if_type type,
 }
 }
 
 
 static inline int
 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)
 	if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
 		return -1;
 		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 *
 static inline struct hostapd_hw_modes *

+ 3 - 3
hostapd/hostapd.c

@@ -340,7 +340,7 @@ static void hostapd_cleanup(struct hostapd_data *hapd)
 #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
 #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
 
 
 	if (hapd->interface_added &&
 	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",
 		wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
 			   hapd->conf->iface);
 			   hapd->conf->iface);
 	}
 	}
@@ -1048,8 +1048,8 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
 		}
 		}
 
 
 		hapd->interface_added = 1;
 		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="
 			wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
 				   MACSTR ")", MAC2STR(hapd->own_addr));
 				   MACSTR ")", MAC2STR(hapd->own_addr));
 			return -1;
 			return -1;

+ 4 - 6
hostapd/vlan_init.c

@@ -680,8 +680,7 @@ static int vlan_dynamic_add(struct hostapd_data *hapd,
 {
 {
 	while (vlan) {
 	while (vlan) {
 		if (vlan->vlan_id != VLAN_ID_WILDCARD &&
 		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) {
 			if (errno != EEXIST) {
 				printf("Could not add VLAN iface: %s: %s\n",
 				printf("Could not add VLAN iface: %s: %s\n",
 				       vlan->ifname, strerror(errno));
 				       vlan->ifname, strerror(errno));
@@ -705,8 +704,7 @@ static void vlan_dynamic_remove(struct hostapd_data *hapd,
 		next = vlan->next;
 		next = vlan->next;
 
 
 		if (vlan->vlan_id != VLAN_ID_WILDCARD &&
 		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",
 			printf("Could not remove VLAN iface: %s: %s\n",
 			       vlan->ifname, strerror(errno));
 			       vlan->ifname, strerror(errno));
 		}
 		}
@@ -777,7 +775,7 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd,
 		    pos);
 		    pos);
 	os_free(ifname);
 	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);
 		os_free(n);
 		return NULL;
 		return NULL;
 	}
 	}
@@ -809,7 +807,7 @@ int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id)
 		return 1;
 		return 1;
 
 
 	if (vlan->dynamic_vlan == 0)
 	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;
 	return 0;
 }
 }

+ 42 - 7
src/drivers/driver.h

@@ -458,8 +458,26 @@ struct hostapd_freq_params {
 				 * enabled, secondary channel above primary */
 				 * 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 {
 struct wpa_init_params {
@@ -1117,14 +1135,31 @@ struct wpa_driver_ops {
 	int (*set_short_slot_time)(void *priv, int value);
 	int (*set_short_slot_time)(void *priv, int value);
 	int (*set_tx_queue_params)(void *priv, int queue, int aifs, int cw_min,
 	int (*set_tx_queue_params)(void *priv, int queue, int aifs, int cw_min,
 				   int cw_max, int burst_time);
 				   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);
 	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,
 	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);
 		      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 (*set_sta_vlan)(void *priv, const u8 *addr, const char *ifname,
 			    int vlan_id);
 			    int vlan_id);
 	/**
 	/**

+ 0 - 2
src/drivers/driver_ndis.c

@@ -3235,8 +3235,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
 	NULL /* set_preamble */,
 	NULL /* set_preamble */,
 	NULL /* set_short_slot_time */,
 	NULL /* set_short_slot_time */,
 	NULL /* set_tx_queue_params */,
 	NULL /* set_tx_queue_params */,
-	NULL /* bss_add */,
-	NULL /* bss_remove */,
 	NULL /* valid_bss_mask */,
 	NULL /* valid_bss_mask */,
 	NULL /* if_add */,
 	NULL /* if_add */,
 	NULL /* if_remove */,
 	NULL /* if_remove */,

+ 93 - 81
src/drivers/driver_nl80211.c

@@ -2743,6 +2743,8 @@ static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
 	return -ENOBUFS;
 	return -ENOBUFS;
 }
 }
 
 
+#endif /* CONFIG_AP || HOSTAPD */
+
 
 
 static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
 static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
 				 int ifidx)
 				 int ifidx)
@@ -2832,6 +2834,8 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
 
 
 	return ifidx;
 	return ifidx;
 }
 }
+
+
 static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
 static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
 				const char *ifname, enum nl80211_iftype iftype,
 				const char *ifname, enum nl80211_iftype iftype,
 				const u8 *addr)
 				const u8 *addr)
@@ -2854,7 +2858,6 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
 	return ret;
 	return ret;
 }
 }
 
 
-#endif /* CONFIG_AP || HOSTAPD */
 
 
 #ifdef CONFIG_AP
 #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)
 static int i802_set_bss(void *priv, int cts, int preamble, int slot)
 {
 {
 	struct wpa_driver_nl80211_data *drv = priv;
 	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,
 static int i802_set_sta_vlan(void *priv, const u8 *addr,
 			     const char *ifname, int vlan_id)
 			     const char *ifname, int vlan_id)
 {
 {
@@ -4568,6 +4495,93 @@ static void i802_deinit(void *priv)
 #endif /* HOSTAPD */
 #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 = {
 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.name = "nl80211",
 	.name = "nl80211",
 	.desc = "Linux nl80211/cfg80211",
 	.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_supp_port = wpa_driver_nl80211_set_supp_port,
 	.set_country = wpa_driver_nl80211_set_country,
 	.set_country = wpa_driver_nl80211_set_country,
 	.set_beacon = wpa_driver_nl80211_set_beacon,
 	.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)
 #if defined(CONFIG_AP) || defined(HOSTAPD)
 	.send_mlme = wpa_driver_nl80211_send_mlme,
 	.send_mlme = wpa_driver_nl80211_send_mlme,
 	.get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
 	.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_preamble = i802_set_preamble,
 	.set_short_slot_time = i802_set_short_slot_time,
 	.set_short_slot_time = i802_set_short_slot_time,
 	.set_tx_queue_params = i802_set_tx_queue_params,
 	.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,
 	.set_sta_vlan = i802_set_sta_vlan,
 #endif /* HOSTAPD */
 #endif /* HOSTAPD */
 };
 };

+ 7 - 5
src/drivers/driver_test.c

@@ -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,
 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)
 			      const u8 *addr)
 {
 {
 	wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s)",
 	wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s)",
 		   __func__, iface, type, ifname);
 		   __func__, iface, type, ifname);
+	if (type == WPA_IF_AP_BSS)
+		return test_driver_bss_add(priv, ifname, addr);
 	return 0;
 	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);
 	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;
 	return 0;
 }
 }
 
 
@@ -2473,8 +2477,6 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
 	.sta_deauth = test_driver_sta_deauth,
 	.sta_deauth = test_driver_sta_deauth,
 	.sta_disassoc = test_driver_sta_disassoc,
 	.sta_disassoc = test_driver_sta_disassoc,
 	.get_hw_feature_data = wpa_driver_test_get_hw_feature_data,
 	.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_add = test_driver_if_add,
 	.if_remove = test_driver_if_remove,
 	.if_remove = test_driver_if_remove,
 	.valid_bss_mask = test_driver_valid_bss_mask,
 	.valid_bss_mask = test_driver_valid_bss_mask,