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 | } |