@ -9,9 +9,9 @@
*/
# include "utils/includes.h"
# ifdef CONFIG_FULL_DYNAMIC_VLAN
# include <net/if.h>
# include <sys/ioctl.h>
# ifdef CONFIG_FULL_DYNAMIC_VLAN
# include <linux/sockios.h>
# include <linux/if_vlan.h>
# include <linux/if_bridge.h>
@ -21,6 +21,7 @@
# include "hostapd.h"
# include "ap_config.h"
# include "ap_drv_ops.h"
# include "wpa_auth.h"
# include "vlan_init.h"
# include "vlan_util.h"
@ -119,6 +120,8 @@ static int dyn_iface_put(struct hostapd_data *hapd, const char *ifname)
return clean ;
}
# endif /* CONFIG_FULL_DYNAMIC_VLAN */
static int ifconfig_helper ( const char * if_name , int up )
{
@ -167,6 +170,58 @@ static int ifconfig_up(const char *if_name)
}
static int vlan_if_add ( struct hostapd_data * hapd , struct hostapd_vlan * vlan ,
int existsok )
{
int ret ;
if ( ! if_nametoindex ( vlan - > ifname ) )
ret = hostapd_vlan_if_add ( hapd , vlan - > ifname ) ;
else if ( ! existsok )
return - 1 ;
else
ret = 0 ;
if ( ret )
return ret ;
ifconfig_up ( vlan - > ifname ) ; /* else wpa group will fail fatal */
if ( hapd - > wpa_auth )
ret = wpa_auth_ensure_group ( hapd - > wpa_auth , vlan - > vlan_id ) ;
if ( ret = = 0 )
return ret ;
wpa_printf ( MSG_ERROR , " WPA initialization for VLAN %d failed (%d) " ,
vlan - > vlan_id , ret ) ;
if ( wpa_auth_release_group ( hapd - > wpa_auth , vlan - > vlan_id ) )
wpa_printf ( MSG_ERROR , " WPA deinit of %s failed " , vlan - > ifname ) ;
/* group state machine setup failed */
if ( hostapd_vlan_if_remove ( hapd , vlan - > ifname ) )
wpa_printf ( MSG_ERROR , " Removal of %s failed " , vlan - > ifname ) ;
return ret ;
}
static int vlan_if_remove ( struct hostapd_data * hapd , struct hostapd_vlan * vlan )
{
int ret ;
ret = wpa_auth_release_group ( hapd - > wpa_auth , vlan - > vlan_id ) ;
if ( ret )
wpa_printf ( MSG_ERROR ,
" WPA deinitialization for VLAN %d failed (%d) " ,
vlan - > vlan_id , ret ) ;
return hostapd_vlan_if_remove ( hapd , vlan - > ifname ) ;
}
# ifdef CONFIG_FULL_DYNAMIC_VLAN
static int ifconfig_down ( const char * if_name )
{
wpa_printf ( MSG_DEBUG , " VLAN: Set interface %s down " , if_name ) ;
@ -913,17 +968,14 @@ static int vlan_dynamic_add(struct hostapd_data *hapd,
{
while ( vlan ) {
if ( vlan - > vlan_id ! = VLAN_ID_WILDCARD ) {
if ( hostapd_vlan_if_add ( hapd , vlan - > ifname ) ) {
if ( errno ! = EEXIST ) {
wpa_printf ( MSG_ERROR , " VLAN: Could "
" not add VLAN %s: %s " ,
vlan - > ifname ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( vlan_if_add ( hapd , vlan , 1 ) ) {
wpa_printf ( MSG_ERROR ,
" VLAN: Could not add VLAN %s: %s " ,
vlan - > ifname , strerror ( errno ) ) ;
return - 1 ;
}
# ifdef CONFIG_FULL_DYNAMIC_VLAN
ifconfig_up ( vlan - > ifname ) ;
vlan_newlink ( vlan - > ifname , hapd ) ;
# endif /* CONFIG_FULL_DYNAMIC_VLAN */
}
@ -943,7 +995,7 @@ static void vlan_dynamic_remove(struct hostapd_data *hapd,
next = vlan - > next ;
if ( vlan - > vlan_id ! = VLAN_ID_WILDCARD & &
hostapd_ vlan_if_remove( hapd , vlan - > ifname ) ) {
vlan_if_remove( hapd , vlan ) ) {
wpa_printf ( MSG_ERROR , " VLAN: Could not remove VLAN "
" iface: %s: %s " ,
vlan - > ifname , strerror ( errno ) ) ;
@ -1031,19 +1083,17 @@ struct hostapd_vlan * vlan_add_dynamic(struct hostapd_data *hapd,
os_snprintf ( n - > ifname , sizeof ( n - > ifname ) , " %s%d%s " , ifname , vlan_id ,
pos ) ;
if ( hostapd_vlan_if_add ( hapd , n - > ifname ) ) {
n - > next = hapd - > conf - > vlan ;
hapd - > conf - > vlan = n ;
/* hapd->conf->vlan needs this new VLAN here for WPA setup */
if ( vlan_if_add ( hapd , n , 0 ) ) {
hapd - > conf - > vlan = n - > next ;
os_free ( n ) ;
n = NULL ;
goto free_ifname ;
}
n - > next = hapd - > conf - > vlan ;
hapd - > conf - > vlan = n ;
# ifdef CONFIG_FULL_DYNAMIC_VLAN
ifconfig_up ( n - > ifname ) ;
# endif /* CONFIG_FULL_DYNAMIC_VLAN */
free_ifname :
os_free ( ifname ) ;
return n ;
@ -1073,7 +1123,7 @@ int vlan_remove_dynamic(struct hostapd_data *hapd, int vlan_id)
return 1 ;
if ( vlan - > dynamic_vlan = = 0 ) {
hostapd_ vlan_if_remove( hapd , vlan - > ifname ) ;
vlan_if_remove( hapd , vlan ) ;
# ifdef CONFIG_FULL_DYNAMIC_VLAN
vlan_dellink ( vlan - > ifname , hapd ) ;
# endif /* CONFIG_FULL_DYNAMIC_VLAN */