aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c83
1 files changed, 59 insertions, 24 deletions
diff --git a/vl.c b/vl.c
index 6d8fe35428..2f3d8d04ed 100644
--- a/vl.c
+++ b/vl.c
@@ -117,6 +117,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
#include "exec-all.h"
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
+#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
#ifdef __sun__
#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
#else
@@ -3789,6 +3790,7 @@ void net_slirp_smb(const char *exported_dir)
typedef struct TAPState {
VLANClientState *vc;
int fd;
+ char down_script[1024];
} TAPState;
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
-static int net_tap_init(VLANState *vlan, const char *ifname1,
- const char *setup_script)
+static int launch_script(const char *setup_script, const char *ifname, int fd)
{
- TAPState *s;
- int pid, status, fd;
+ int pid, status;
char *args[3];
char **parg;
- 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') {
- /* try to launch network init script */
+ /* try to launch network script */
pid = fork();
if (pid >= 0) {
if (pid == 0) {
@@ -4058,7 +4046,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
parg = args;
*parg++ = (char *)setup_script;
- *parg++ = ifname;
+ *parg++ = (char *)ifname;
*parg++ = NULL;
execv(setup_script, args);
_exit(1);
@@ -4071,12 +4059,37 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
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);
if (!s)
return -1;
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"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;
}
@@ -4620,7 +4633,7 @@ static int net_client_init(const char *str)
#else
if (!strcmp(device, "tap")) {
char ifname[64];
- char setup_script[1024];
+ char setup_script[1024], down_script[1024];
int fd;
vlan->nb_host_devs++;
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) {
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
#endif
@@ -7022,10 +7038,11 @@ static void help(int exitcode)
"-net tap[,vlan=n],ifname=name\n"
" connect the host TAP network interface to VLAN 'n'\n"
#else
- "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
- " connect the host TAP network interface to VLAN 'n' and use\n"
- " the network script 'file' (default=%s);\n"
- " use 'script=no' to disable script execution;\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 the\n"
+ " network scripts 'file' (default=%s)\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"
#endif
"-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,
#ifndef _WIN32
DEFAULT_NETWORK_SCRIPT,
+ DEFAULT_NETWORK_DOWN_SCRIPT,
#endif
DEFAULT_GDBSTUB_PORT,
"/tmp/qemu.log");
@@ -8459,5 +8477,22 @@ int main(int argc, char **argv)
main_loop();
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;
}