@ -333,6 +333,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
const char * name ,
IOReadHandler * fd_read ,
IOCanRWHandler * fd_can_read ,
NetCleanup * cleanup ,
void * opaque )
{
VLANClientState * vc , * * pvc ;
@ -344,6 +345,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
vc - > name = assign_name ( vc , model ) ;
vc - > fd_read = fd_read ;
vc - > fd_can_read = fd_can_read ;
vc - > cleanup = cleanup ;
vc - > opaque = opaque ;
vc - > vlan = vlan ;
@ -362,6 +364,9 @@ void qemu_del_vlan_client(VLANClientState *vc)
while ( * pvc ! = NULL )
if ( * pvc = = vc ) {
* pvc = vc - > next ;
if ( vc - > cleanup ) {
vc - > cleanup ( vc ) ;
}
free ( vc - > name ) ;
free ( vc - > model ) ;
free ( vc ) ;
@ -521,7 +526,7 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
slirp_init ( slirp_restrict , slirp_ip ) ;
}
slirp_vc = qemu_new_vlan_client ( vlan , model , name ,
slirp_receive , NULL , NULL ) ;
slirp_receive , NULL , NULL , NULL ) ;
slirp_vc - > info_str [ 0 ] = ' \0 ' ;
return 0 ;
}
@ -702,6 +707,8 @@ typedef struct TAPState {
char down_script_arg [ 128 ] ;
} TAPState ;
static int launch_script ( const char * setup_script , const char * ifname , int fd ) ;
static ssize_t tap_receive_iov ( void * opaque , const struct iovec * iov ,
int iovcnt )
{
@ -748,6 +755,18 @@ static void tap_send(void *opaque)
}
}
static void tap_cleanup ( VLANClientState * vc )
{
TAPState * s = vc - > opaque ;
if ( s - > down_script [ 0 ] )
launch_script ( s - > down_script , s - > down_script_arg , s - > fd ) ;
qemu_set_fd_handler ( s - > fd , NULL , NULL , NULL ) ;
close ( s - > fd ) ;
qemu_free ( s ) ;
}
/* fd support */
static TAPState * net_tap_fd_init ( VLANState * vlan ,
@ -759,7 +778,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s = qemu_mallocz ( sizeof ( TAPState ) ) ;
s - > fd = fd ;
s - > vc = qemu_new_vlan_client ( vlan , model , name , tap_receive , NULL , s ) ;
s - > vc = qemu_new_vlan_client ( vlan , model , name , tap_receive ,
NULL , tap_cleanup , s ) ;
s - > vc - > fd_readv = tap_receive_iov ;
qemu_set_fd_handler ( s - > fd , tap_send , NULL , s ) ;
snprintf ( s - > vc - > info_str , sizeof ( s - > vc - > info_str ) , " fd=%d " , fd ) ;
@ -1058,6 +1078,14 @@ static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
}
}
static void vde_cleanup ( VLANClientState * vc )
{
VDEState * s = vc - > opaque ;
qemu_set_fd_handler ( vde_datafd ( s - > vde ) , NULL , NULL , NULL ) ;
vde_close ( s - > vde ) ;
qemu_free ( s ) ;
}
static int net_vde_init ( VLANState * vlan , const char * model ,
const char * name , const char * sock ,
int port , const char * group , int mode )
@ -1078,7 +1106,8 @@ static int net_vde_init(VLANState *vlan, const char *model,
free ( s ) ;
return - 1 ;
}
s - > vc = qemu_new_vlan_client ( vlan , model , name , vde_from_qemu , NULL , s ) ;
s - > vc = qemu_new_vlan_client ( vlan , model , name , vde_from_qemu ,
NULL , vde_cleanup , s ) ;
qemu_set_fd_handler ( vde_datafd ( s - > vde ) , vde_to_qemu , NULL , s ) ;
snprintf ( s - > vc - > info_str , sizeof ( s - > vc - > info_str ) , " sock=%s,fd=%d " ,
sock , vde_datafd ( s - > vde ) ) ;
@ -1263,6 +1292,14 @@ fail:
return - 1 ;
}
static void net_socket_cleanup ( VLANClientState * vc )
{
NetSocketState * s = vc - > opaque ;
qemu_set_fd_handler ( s - > fd , NULL , NULL , NULL ) ;
close ( s - > fd ) ;
qemu_free ( s ) ;
}
static NetSocketState * net_socket_fd_init_dgram ( VLANState * vlan ,
const char * model ,
const char * name ,
@ -1307,7 +1344,8 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
s = qemu_mallocz ( sizeof ( NetSocketState ) ) ;
s - > fd = fd ;
s - > vc = qemu_new_vlan_client ( vlan , model , name , net_socket_receive_dgram , NULL , s ) ;
s - > vc = qemu_new_vlan_client ( vlan , model , name , net_socket_receive_dgram ,
NULL , net_socket_cleanup , s ) ;
qemu_set_fd_handler ( s - > fd , net_socket_send_dgram , NULL , s ) ;
/* mcast: save bound address as dst */
@ -1334,8 +1372,8 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
NetSocketState * s ;
s = qemu_mallocz ( sizeof ( NetSocketState ) ) ;
s - > fd = fd ;
s - > vc = qemu_new_vlan_client ( vlan , model , name ,
net_socket_receive , NULL , s ) ;
s - > vc = qemu_new_vlan_client ( vlan , model , name , net_socket_receive ,
NULL , net_socket_cleanup , s ) ;
snprintf ( s - > vc - > info_str , sizeof ( s - > vc - > info_str ) ,
" socket: fd=%d " , fd ) ;
if ( is_connected ) {
@ -1895,29 +1933,20 @@ done:
void net_cleanup ( void )
{
# if !defined(_WIN32)
VLANState * vlan ;
/* close network clients */
for ( vlan = first_vlan ; vlan ! = NULL ; vlan = vlan - > next ) {
VLANClientState * vc ;
VLANClientState * vc = vlan - > first_client ;
for ( vc = vlan - > first_client ; vc ! = NULL ; vc = vc - > next ) {
if ( vc - > fd_read = = tap_receive ) {
TAPState * s = vc - > opaque ;
while ( vc ) {
VLANClientState * next = vc - > next ;
if ( s - > down_script [ 0 ] )
launch_script ( s - > down_script , s - > down_script_arg , s - > fd ) ;
}
# if defined(CONFIG_VDE)
if ( vc - > fd_read = = vde_from_qemu ) {
VDEState * s = vc - > opaque ;
vde_close ( s - > vde ) ;
}
# endif
qemu_del_vlan_client ( vc ) ;
vc = next ;
}
}
# endif
}
void net_client_check ( void )