bridge: Track inter-BSS usage

Currently, struct hostapd_vlan is a per-BSS data structure which
also contains informations about whether to remove the bridge
or clear wlan / tagged-vlan interface from the bridge.

In a multi-interface multi-BSS setup, this can lead to the following
race condition:
 1. wlan0 creates VLAN A, sets DVLAN_CLEAN_BR and DVLAN_CLEAN_VLAN_PORT
 2. wlan1 creates VLAN A, does not set DVLAN_CLEAN_BR and
    DVLAN_CLEAN_VLAN_PORT as already there
 3. wlan0 removes VLAN A, removes tagged-interface from the bridge
    but not the bridge.
    Now wlan1 VLAN A is unusable due to the missing uplink.
 4. wlan1 removes VLAN A, does not cleanup

Solution:
This requires an inter-BSS inter-interface data structure to track the
bridge / bridge port usage within hostapd. This data structure could
also be used to track any other device-has-been-created-by-hostapd
information or when regarding interface freeing.

Signed-hostap: Michael Braun <michael-dev@fami-braun.de>
This commit is contained in:
Michael Braun 2013-06-25 11:55:30 +03:00 committed by Jouni Malinen
parent 459eee923c
commit 4345fe963e
2 changed files with 154 additions and 8 deletions

View file

@ -25,6 +25,7 @@ enum wps_event;
union wps_event_data;
struct hostapd_iface;
struct hostapd_dynamic_iface;
struct hapd_interfaces {
int (*reload_config)(struct hostapd_iface *iface);
@ -37,11 +38,13 @@ struct hapd_interfaces {
int (*driver_init)(struct hostapd_iface *iface);
size_t count;
size_t count_dynamic;
int global_ctrl_sock;
char *global_iface_path;
char *global_iface_name;
gid_t ctrl_iface_group;
struct hostapd_iface **iface;
struct hostapd_dynamic_iface **dynamic_iface;
};
@ -275,6 +278,16 @@ struct hostapd_iface {
void (*scan_cb)(struct hostapd_iface *iface);
};
/**
* struct hostapd_dynamic_iface - hostapd per dynamically allocated
* or added interface data structure
*/
struct hostapd_dynamic_iface {
char parent[IFNAMSIZ + 1];
char iface[IFNAMSIZ + 1];
unsigned int usage;
};
/* hostapd.c */
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
int (*cb)(struct hostapd_iface *iface,