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 | 117 | #include "exec-all.h" |
118 | 118 | |
119 | 119 | #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
120 | +#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" | |
120 | 121 | #ifdef __sun__ |
121 | 122 | #define SMBD_COMMAND "/usr/sfw/sbin/smbd" |
122 | 123 | #else |
... | ... | @@ -3789,6 +3790,7 @@ void net_slirp_smb(const char *exported_dir) |
3789 | 3790 | typedef struct TAPState { |
3790 | 3791 | VLANClientState *vc; |
3791 | 3792 | int fd; |
3793 | + char down_script[1024]; | |
3792 | 3794 | } TAPState; |
3793 | 3795 | |
3794 | 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 | 4026 | } |
4025 | 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 | 4032 | char *args[3]; |
4033 | 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 | 4036 | pid = fork(); |
4049 | 4037 | if (pid >= 0) { |
4050 | 4038 | if (pid == 0) { |
... | ... | @@ -4058,7 +4046,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, |
4058 | 4046 | |
4059 | 4047 | parg = args; |
4060 | 4048 | *parg++ = (char *)setup_script; |
4061 | - *parg++ = ifname; | |
4049 | + *parg++ = (char *)ifname; | |
4062 | 4050 | *parg++ = NULL; |
4063 | 4051 | execv(setup_script, args); |
4064 | 4052 | _exit(1); |
... | ... | @@ -4071,12 +4059,37 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, |
4071 | 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 | 4086 | s = net_tap_fd_init(vlan, fd); |
4076 | 4087 | if (!s) |
4077 | 4088 | return -1; |
4078 | 4089 | snprintf(s->vc->info_str, sizeof(s->vc->info_str), |
4079 | 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 | 4093 | return 0; |
4081 | 4094 | } |
4082 | 4095 | |
... | ... | @@ -4620,7 +4633,7 @@ static int net_client_init(const char *str) |
4620 | 4633 | #else |
4621 | 4634 | if (!strcmp(device, "tap")) { |
4622 | 4635 | char ifname[64]; |
4623 | - char setup_script[1024]; | |
4636 | + char setup_script[1024], down_script[1024]; | |
4624 | 4637 | int fd; |
4625 | 4638 | vlan->nb_host_devs++; |
4626 | 4639 | if (get_param_value(buf, sizeof(buf), "fd", p) > 0) { |
... | ... | @@ -4635,7 +4648,10 @@ static int net_client_init(const char *str) |
4635 | 4648 | if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) { |
4636 | 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 | 4656 | } else |
4641 | 4657 | #endif |
... | ... | @@ -7022,10 +7038,11 @@ static void help(int exitcode) |
7022 | 7038 | "-net tap[,vlan=n],ifname=name\n" |
7023 | 7039 | " connect the host TAP network interface to VLAN 'n'\n" |
7024 | 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 | 7046 | " use 'fd=h' to connect to an already opened TAP interface\n" |
7030 | 7047 | #endif |
7031 | 7048 | "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n" |
... | ... | @@ -7098,6 +7115,7 @@ static void help(int exitcode) |
7098 | 7115 | DEFAULT_RAM_SIZE, |
7099 | 7116 | #ifndef _WIN32 |
7100 | 7117 | DEFAULT_NETWORK_SCRIPT, |
7118 | + DEFAULT_NETWORK_DOWN_SCRIPT, | |
7101 | 7119 | #endif |
7102 | 7120 | DEFAULT_GDBSTUB_PORT, |
7103 | 7121 | "/tmp/qemu.log"); |
... | ... | @@ -8459,5 +8477,22 @@ int main(int argc, char **argv) |
8459 | 8477 | |
8460 | 8478 | main_loop(); |
8461 | 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 | 8497 | return 0; |
8463 | 8498 | } | ... | ... |