Support tap down script, by Wolfram Gloger.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3425 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2007-10-21 23:20:45 +00:00
parent fce62c4eb3
commit b46a8906b3

83
vl.c
View file

@ -117,6 +117,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
#include "exec-all.h" #include "exec-all.h"
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
#ifdef __sun__ #ifdef __sun__
#define SMBD_COMMAND "/usr/sfw/sbin/smbd" #define SMBD_COMMAND "/usr/sfw/sbin/smbd"
#else #else
@ -3789,6 +3790,7 @@ void net_slirp_smb(const char *exported_dir)
typedef struct TAPState { typedef struct TAPState {
VLANClientState *vc; VLANClientState *vc;
int fd; int fd;
char down_script[1024];
} TAPState; } TAPState;
static void tap_receive(void *opaque, const uint8_t *buf, int size) static void tap_receive(void *opaque, const uint8_t *buf, int size)
@ -4024,27 +4026,13 @@ static int tap_open(char *ifname, int ifname_size)
} }
#endif #endif
static int net_tap_init(VLANState *vlan, const char *ifname1, static int launch_script(const char *setup_script, const char *ifname, int fd)
const char *setup_script)
{ {
TAPState *s; int pid, status;
int pid, status, fd;
char *args[3]; char *args[3];
char **parg; char **parg;
char ifname[128];
if (ifname1 != NULL) /* try to launch network script */
pstrcpy(ifname, sizeof(ifname), ifname1);
else
ifname[0] = '\0';
TFR(fd = tap_open(ifname, sizeof(ifname)));
if (fd < 0)
return -1;
if (!setup_script || !strcmp(setup_script, "no"))
setup_script = "";
if (setup_script[0] != '\0') {
/* try to launch network init script */
pid = fork(); pid = fork();
if (pid >= 0) { if (pid >= 0) {
if (pid == 0) { if (pid == 0) {
@ -4058,7 +4046,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
parg = args; parg = args;
*parg++ = (char *)setup_script; *parg++ = (char *)setup_script;
*parg++ = ifname; *parg++ = (char *)ifname;
*parg++ = NULL; *parg++ = NULL;
execv(setup_script, args); execv(setup_script, args);
_exit(1); _exit(1);
@ -4071,12 +4059,37 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
return -1; return -1;
} }
} }
return 0;
}
static int net_tap_init(VLANState *vlan, const char *ifname1,
const char *setup_script, const char *down_script)
{
TAPState *s;
int fd;
char ifname[128];
if (ifname1 != NULL)
pstrcpy(ifname, sizeof(ifname), ifname1);
else
ifname[0] = '\0';
TFR(fd = tap_open(ifname, sizeof(ifname)));
if (fd < 0)
return -1;
if (!setup_script || !strcmp(setup_script, "no"))
setup_script = "";
if (setup_script[0] != '\0') {
if (launch_script(setup_script, ifname, fd))
return -1;
} }
s = net_tap_fd_init(vlan, fd); s = net_tap_fd_init(vlan, fd);
if (!s) if (!s)
return -1; return -1;
snprintf(s->vc->info_str, sizeof(s->vc->info_str), snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"tap: ifname=%s setup_script=%s", ifname, setup_script); "tap: ifname=%s setup_script=%s", ifname, setup_script);
if (down_script && strcmp(down_script, "no"))
snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
return 0; return 0;
} }
@ -4620,7 +4633,7 @@ static int net_client_init(const char *str)
#else #else
if (!strcmp(device, "tap")) { if (!strcmp(device, "tap")) {
char ifname[64]; char ifname[64];
char setup_script[1024]; char setup_script[1024], down_script[1024];
int fd; int fd;
vlan->nb_host_devs++; vlan->nb_host_devs++;
if (get_param_value(buf, sizeof(buf), "fd", p) > 0) { if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
@ -4635,7 +4648,10 @@ static int net_client_init(const char *str)
if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) { if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT); pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
} }
ret = net_tap_init(vlan, ifname, setup_script); if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
}
ret = net_tap_init(vlan, ifname, setup_script, down_script);
} }
} else } else
#endif #endif
@ -7022,10 +7038,11 @@ static void help(int exitcode)
"-net tap[,vlan=n],ifname=name\n" "-net tap[,vlan=n],ifname=name\n"
" connect the host TAP network interface to VLAN 'n'\n" " connect the host TAP network interface to VLAN 'n'\n"
#else #else
"-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n" "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
" connect the host TAP network interface to VLAN 'n' and use\n" " connect the host TAP network interface to VLAN 'n' and use the\n"
" the network script 'file' (default=%s);\n" " network scripts 'file' (default=%s)\n"
" use 'script=no' to disable script execution;\n" " and 'dfile' (default=%s);\n"
" use '[down]script=no' to disable script execution;\n"
" use 'fd=h' to connect to an already opened TAP interface\n" " use 'fd=h' to connect to an already opened TAP interface\n"
#endif #endif
"-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n" "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
@ -7098,6 +7115,7 @@ static void help(int exitcode)
DEFAULT_RAM_SIZE, DEFAULT_RAM_SIZE,
#ifndef _WIN32 #ifndef _WIN32
DEFAULT_NETWORK_SCRIPT, DEFAULT_NETWORK_SCRIPT,
DEFAULT_NETWORK_DOWN_SCRIPT,
#endif #endif
DEFAULT_GDBSTUB_PORT, DEFAULT_GDBSTUB_PORT,
"/tmp/qemu.log"); "/tmp/qemu.log");
@ -8459,5 +8477,22 @@ int main(int argc, char **argv)
main_loop(); main_loop();
quit_timers(); quit_timers();
/* close network clients */
for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
VLANClientState *vc;
for(vc = vlan->first_client; vc != NULL; vc = vc->next)
#if !defined(_WIN32)
if (vc->fd_read == tap_receive) {
char ifname[64];
TAPState *s = vc->opaque;
if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
s->down_script[0])
launch_script(s->down_script, ifname, s->fd);
}
#endif
}
return 0; return 0;
} }