VLANClientState *vc;
int fd;
char down_script[1024];
- char script_arg[1024];
+ char net_args[2048];
} TAPState;
static void tap_receive(void *opaque, const uint8_t *buf, int size)
}
#endif
+static const char *get_opt_name(char *buf, int buf_size, const char *p);
+static const char *get_opt_value(char *buf, int buf_size, const char *p);
+
static int launch_script(const char *setup_script, const char *ifname,
- const char *script_arg, int fd)
+ const char *net_args, int fd)
{
- int pid, status;
- char *args[4];
+ static const char option_env_prefix[] = "QEMU_IF_";
+#define OPTION_ENV_PREFIX_LEN (sizeof(option_env_prefix)-1)
+ int pid, status, ret;
+ char *args[3];
char **parg;
+ const char *p;
+ char envvar[128 + OPTION_ENV_PREFIX_LEN], value[1024];
/* try to launch network script */
pid = fork();
i != fd)
close(i);
+ p = net_args;
+ memcpy(envvar, option_env_prefix, OPTION_ENV_PREFIX_LEN);
+ for (;;) {
+ p = get_opt_name(envvar + OPTION_ENV_PREFIX_LEN,
+ sizeof(envvar) - OPTION_ENV_PREFIX_LEN,
+ p);
+ if (*p != '=')
+ break;
+ p++;
+ p = get_opt_value(value, sizeof(value), p);
+ ret = setenv(envvar, value, 1);
+ if (ret != 0) {
+ perror("cannot set option env var");
+ _exit(-1);
+ }
+ if (*p != ',')
+ break;
+ p++;
+ }
+
parg = args;
*parg++ = (char *)setup_script;
*parg++ = (char *)ifname;
- if (script_arg && script_arg[0])
- *parg++ = (char *)script_arg;
*parg++ = NULL;
execv(setup_script, args);
_exit(1);
static int net_tap_init(VLANState *vlan, const char *ifname1,
const char *setup_script, const char *down_script,
- const char *script_arg)
+ const char *net_args)
{
TAPState *s;
int fd;
if (!setup_script || !strcmp(setup_script, "no"))
setup_script = "";
if (setup_script[0] != '\0') {
- if (launch_script(setup_script, ifname, script_arg, fd))
+ if (launch_script(setup_script, ifname, net_args, fd))
return -1;
}
s = net_tap_fd_init(vlan, fd);
"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);
- if (script_arg && script_arg[0])
- snprintf(s->script_arg, sizeof(s->script_arg), "%s", script_arg);
+ snprintf(s->net_args, sizeof(s->net_args), "%s", net_args);
return 0;
}
#else
if (!strcmp(device, "tap")) {
char ifname[64];
- char setup_script[1024], down_script[1024], script_arg[1024];
+ char setup_script[1024], down_script[1024];
int fd;
memset(ifname, 0, sizeof(ifname));
if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
}
- if (get_param_value(script_arg, sizeof(script_arg), "scriptarg", p) == 0) {
- pstrcpy(script_arg, sizeof(script_arg), "");
- }
- ret = net_tap_init(vlan, ifname, setup_script, down_script, script_arg);
+ ret = net_tap_init(vlan, ifname, setup_script, down_script, p);
}
} else
#endif
"-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][,downscript=dfile][,scriptarg=extraargument]\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 'scriptarg=...' to pass an additional (nonempty) argument;\n"
+ " script will have QEMU_IF_vlan=... and so on in its environment;\ 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"
if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
s->down_script[0])
- launch_script(s->down_script, ifname, s->script_arg, s->fd);
+ launch_script(s->down_script, ifname, s->net_args, s->fd);
}
}
}