Commit b46a8906b34828adec2702f1e918fc9f553f2ad3
1 parent
fce62c4e
Support tap down script, by Wolfram Gloger.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3425 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
59 additions
and
24 deletions
vl.c
@@ -117,6 +117,7 @@ int inet_aton(const char *cp, struct in_addr *ia); | @@ -117,6 +117,7 @@ int inet_aton(const char *cp, struct in_addr *ia); | ||
117 | #include "exec-all.h" | 117 | #include "exec-all.h" |
118 | 118 | ||
119 | #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" | 119 | #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
120 | +#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" | ||
120 | #ifdef __sun__ | 121 | #ifdef __sun__ |
121 | #define SMBD_COMMAND "/usr/sfw/sbin/smbd" | 122 | #define SMBD_COMMAND "/usr/sfw/sbin/smbd" |
122 | #else | 123 | #else |
@@ -3789,6 +3790,7 @@ void net_slirp_smb(const char *exported_dir) | @@ -3789,6 +3790,7 @@ void net_slirp_smb(const char *exported_dir) | ||
3789 | typedef struct TAPState { | 3790 | typedef struct TAPState { |
3790 | VLANClientState *vc; | 3791 | VLANClientState *vc; |
3791 | int fd; | 3792 | int fd; |
3793 | + char down_script[1024]; | ||
3792 | } TAPState; | 3794 | } TAPState; |
3793 | 3795 | ||
3794 | static void tap_receive(void *opaque, const uint8_t *buf, int size) | 3796 | 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) | @@ -4024,27 +4026,13 @@ static int tap_open(char *ifname, int ifname_size) | ||
4024 | } | 4026 | } |
4025 | #endif | 4027 | #endif |
4026 | 4028 | ||
4027 | -static int net_tap_init(VLANState *vlan, const char *ifname1, | ||
4028 | - const char *setup_script) | 4029 | +static int launch_script(const char *setup_script, const char *ifname, int fd) |
4029 | { | 4030 | { |
4030 | - TAPState *s; | ||
4031 | - int pid, status, fd; | 4031 | + int pid, status; |
4032 | char *args[3]; | 4032 | char *args[3]; |
4033 | char **parg; | 4033 | char **parg; |
4034 | - char ifname[128]; | ||
4035 | - | ||
4036 | - if (ifname1 != NULL) | ||
4037 | - pstrcpy(ifname, sizeof(ifname), ifname1); | ||
4038 | - else | ||
4039 | - ifname[0] = '\0'; | ||
4040 | - TFR(fd = tap_open(ifname, sizeof(ifname))); | ||
4041 | - if (fd < 0) | ||
4042 | - return -1; | ||
4043 | 4034 | ||
4044 | - if (!setup_script || !strcmp(setup_script, "no")) | ||
4045 | - setup_script = ""; | ||
4046 | - if (setup_script[0] != '\0') { | ||
4047 | - /* try to launch network init script */ | 4035 | + /* try to launch network script */ |
4048 | pid = fork(); | 4036 | pid = fork(); |
4049 | if (pid >= 0) { | 4037 | if (pid >= 0) { |
4050 | if (pid == 0) { | 4038 | if (pid == 0) { |
@@ -4058,7 +4046,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, | @@ -4058,7 +4046,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, | ||
4058 | 4046 | ||
4059 | parg = args; | 4047 | parg = args; |
4060 | *parg++ = (char *)setup_script; | 4048 | *parg++ = (char *)setup_script; |
4061 | - *parg++ = ifname; | 4049 | + *parg++ = (char *)ifname; |
4062 | *parg++ = NULL; | 4050 | *parg++ = NULL; |
4063 | execv(setup_script, args); | 4051 | execv(setup_script, args); |
4064 | _exit(1); | 4052 | _exit(1); |
@@ -4071,12 +4059,37 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, | @@ -4071,12 +4059,37 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, | ||
4071 | return -1; | 4059 | return -1; |
4072 | } | 4060 | } |
4073 | } | 4061 | } |
4062 | + return 0; | ||
4063 | +} | ||
4064 | + | ||
4065 | +static int net_tap_init(VLANState *vlan, const char *ifname1, | ||
4066 | + const char *setup_script, const char *down_script) | ||
4067 | +{ | ||
4068 | + TAPState *s; | ||
4069 | + int fd; | ||
4070 | + char ifname[128]; | ||
4071 | + | ||
4072 | + if (ifname1 != NULL) | ||
4073 | + pstrcpy(ifname, sizeof(ifname), ifname1); | ||
4074 | + else | ||
4075 | + ifname[0] = '\0'; | ||
4076 | + TFR(fd = tap_open(ifname, sizeof(ifname))); | ||
4077 | + if (fd < 0) | ||
4078 | + return -1; | ||
4079 | + | ||
4080 | + if (!setup_script || !strcmp(setup_script, "no")) | ||
4081 | + setup_script = ""; | ||
4082 | + if (setup_script[0] != '\0') { | ||
4083 | + if (launch_script(setup_script, ifname, fd)) | ||
4084 | + return -1; | ||
4074 | } | 4085 | } |
4075 | s = net_tap_fd_init(vlan, fd); | 4086 | s = net_tap_fd_init(vlan, fd); |
4076 | if (!s) | 4087 | if (!s) |
4077 | return -1; | 4088 | return -1; |
4078 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), | 4089 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), |
4079 | "tap: ifname=%s setup_script=%s", ifname, setup_script); | 4090 | "tap: ifname=%s setup_script=%s", ifname, setup_script); |
4091 | + if (down_script && strcmp(down_script, "no")) | ||
4092 | + snprintf(s->down_script, sizeof(s->down_script), "%s", down_script); | ||
4080 | return 0; | 4093 | return 0; |
4081 | } | 4094 | } |
4082 | 4095 | ||
@@ -4620,7 +4633,7 @@ static int net_client_init(const char *str) | @@ -4620,7 +4633,7 @@ static int net_client_init(const char *str) | ||
4620 | #else | 4633 | #else |
4621 | if (!strcmp(device, "tap")) { | 4634 | if (!strcmp(device, "tap")) { |
4622 | char ifname[64]; | 4635 | char ifname[64]; |
4623 | - char setup_script[1024]; | 4636 | + char setup_script[1024], down_script[1024]; |
4624 | int fd; | 4637 | int fd; |
4625 | vlan->nb_host_devs++; | 4638 | vlan->nb_host_devs++; |
4626 | if (get_param_value(buf, sizeof(buf), "fd", p) > 0) { | 4639 | if (get_param_value(buf, sizeof(buf), "fd", p) > 0) { |
@@ -4635,7 +4648,10 @@ static int net_client_init(const char *str) | @@ -4635,7 +4648,10 @@ static int net_client_init(const char *str) | ||
4635 | if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) { | 4648 | if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) { |
4636 | pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT); | 4649 | pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT); |
4637 | } | 4650 | } |
4638 | - ret = net_tap_init(vlan, ifname, setup_script); | 4651 | + if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) { |
4652 | + pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT); | ||
4653 | + } | ||
4654 | + ret = net_tap_init(vlan, ifname, setup_script, down_script); | ||
4639 | } | 4655 | } |
4640 | } else | 4656 | } else |
4641 | #endif | 4657 | #endif |
@@ -7022,10 +7038,11 @@ static void help(int exitcode) | @@ -7022,10 +7038,11 @@ static void help(int exitcode) | ||
7022 | "-net tap[,vlan=n],ifname=name\n" | 7038 | "-net tap[,vlan=n],ifname=name\n" |
7023 | " connect the host TAP network interface to VLAN 'n'\n" | 7039 | " connect the host TAP network interface to VLAN 'n'\n" |
7024 | #else | 7040 | #else |
7025 | - "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n" | ||
7026 | - " connect the host TAP network interface to VLAN 'n' and use\n" | ||
7027 | - " the network script 'file' (default=%s);\n" | ||
7028 | - " use 'script=no' to disable script execution;\n" | 7041 | + "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n" |
7042 | + " connect the host TAP network interface to VLAN 'n' and use the\n" | ||
7043 | + " network scripts 'file' (default=%s)\n" | ||
7044 | + " and 'dfile' (default=%s);\n" | ||
7045 | + " use '[down]script=no' to disable script execution;\n" | ||
7029 | " use 'fd=h' to connect to an already opened TAP interface\n" | 7046 | " use 'fd=h' to connect to an already opened TAP interface\n" |
7030 | #endif | 7047 | #endif |
7031 | "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n" | 7048 | "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n" |
@@ -7098,6 +7115,7 @@ static void help(int exitcode) | @@ -7098,6 +7115,7 @@ static void help(int exitcode) | ||
7098 | DEFAULT_RAM_SIZE, | 7115 | DEFAULT_RAM_SIZE, |
7099 | #ifndef _WIN32 | 7116 | #ifndef _WIN32 |
7100 | DEFAULT_NETWORK_SCRIPT, | 7117 | DEFAULT_NETWORK_SCRIPT, |
7118 | + DEFAULT_NETWORK_DOWN_SCRIPT, | ||
7101 | #endif | 7119 | #endif |
7102 | DEFAULT_GDBSTUB_PORT, | 7120 | DEFAULT_GDBSTUB_PORT, |
7103 | "/tmp/qemu.log"); | 7121 | "/tmp/qemu.log"); |
@@ -8459,5 +8477,22 @@ int main(int argc, char **argv) | @@ -8459,5 +8477,22 @@ int main(int argc, char **argv) | ||
8459 | 8477 | ||
8460 | main_loop(); | 8478 | main_loop(); |
8461 | quit_timers(); | 8479 | quit_timers(); |
8480 | + | ||
8481 | + /* close network clients */ | ||
8482 | + for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) { | ||
8483 | + VLANClientState *vc; | ||
8484 | + | ||
8485 | + for(vc = vlan->first_client; vc != NULL; vc = vc->next) | ||
8486 | +#if !defined(_WIN32) | ||
8487 | + if (vc->fd_read == tap_receive) { | ||
8488 | + char ifname[64]; | ||
8489 | + TAPState *s = vc->opaque; | ||
8490 | + | ||
8491 | + if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 && | ||
8492 | + s->down_script[0]) | ||
8493 | + launch_script(s->down_script, ifname, s->fd); | ||
8494 | + } | ||
8495 | +#endif | ||
8496 | + } | ||
8462 | return 0; | 8497 | return 0; |
8463 | } | 8498 | } |