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.
This commit is contained in:
parent
b5996353e7
commit
22a7c9d735
7 changed files with 154 additions and 125 deletions
|
@ -371,22 +371,6 @@ hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
|
|||
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
|
||||
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 *
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
/**
|
||||
|
|
|
@ -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 */,
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue