@@ -180,6 +180,7 @@ NetClientState *net_hub_port_find(int hub_id);
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
#define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR "/qemu-bridge-helper"
#define DEFAULT_BRIDGE_INTERFACE "br0"
+#define DEFAULT_BRIDGE_PREFIX "tap"
void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
@@ -419,7 +419,8 @@ static int recv_fd(int c)
return len;
}
-static int net_bridge_run_helper(const char *helper, const char *bridge)
+static int net_bridge_run_helper(const char *helper, const char *bridge,
+ const char *prefix)
{
sigset_t oldmask, mask;
int pid, status;
@@ -441,7 +442,8 @@ static int net_bridge_run_helper(const char *helper, const char *bridge)
int open_max = sysconf(_SC_OPEN_MAX), i;
char fd_buf[6+10];
char br_buf[6+IFNAMSIZ] = {0};
- char helper_cmd[PATH_MAX + sizeof(fd_buf) + sizeof(br_buf) + 15];
+ char pr_buf[6+IFNAMSIZ] = {0};
+ char helper_cmd[PATH_MAX + sizeof(fd_buf) + sizeof(br_buf) + sizeof(pr_buf) + 15];
for (i = 0; i < open_max; i++) {
if (i != STDIN_FILENO &&
@@ -453,6 +455,7 @@ static int net_bridge_run_helper(const char *helper, const char *bridge)
}
snprintf(fd_buf, sizeof(fd_buf), "%s%d", "--fd=", sv[1]);
+ snprintf(pr_buf, sizeof(br_buf), "%s%s", "--tap-prefix=", prefix);
if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
/* assume helper is a command */
@@ -481,6 +484,7 @@ static int net_bridge_run_helper(const char *helper, const char *bridge)
*parg++ = (char *)"--use-vnet";
*parg++ = fd_buf;
*parg++ = br_buf;
+ *parg++ = pr_buf;
*parg++ = NULL;
execv(helper, args);
@@ -519,7 +523,7 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,
NetClientState *peer)
{
const NetdevBridgeOptions *bridge;
- const char *helper, *br;
+ const char *helper, *br, *prefix;
TAPState *s;
int fd, vnet_hdr;
@@ -528,9 +532,10 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,
bridge = opts->bridge;
helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER;
+ prefix = bridge->has_prefix ? bridge->prefix : DEFAULT_BRIDGE_PREFIX;
br = bridge->has_br ? bridge->br : DEFAULT_BRIDGE_INTERFACE;
- fd = net_bridge_run_helper(helper, br);
+ fd = net_bridge_run_helper(helper, br, prefix);
if (fd == -1) {
return -1;
}
@@ -728,7 +733,7 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
tap->has_vhostfd) {
error_report("ifname=, script=, downscript=, vnet_hdr=, "
- "helper=, queues=, and vhostfd= "
+ "helper=, queues=, and vhostfd="
"are invalid with fds=");
return -1;
}
@@ -773,7 +778,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
return -1;
}
- fd = net_bridge_run_helper(tap->helper, DEFAULT_BRIDGE_INTERFACE);
+ fd = net_bridge_run_helper(tap->helper, DEFAULT_BRIDGE_INTERFACE,
+ DEFAULT_BRIDGE_PREFIX);
if (fd == -1) {
return -1;
}
@@ -3028,7 +3028,8 @@
{ 'type': 'NetdevBridgeOptions',
'data': {
'*br': 'str',
- '*helper': 'str' } }
+ '*helper': 'str',
+ '*prefix': 'str'} }
##
# @NetdevHubPortOptions
@@ -67,7 +67,8 @@ typedef QSIMPLEQ_HEAD(ACLList, ACLRule) ACLList;
static void usage(void)
{
fprintf(stderr,
- "Usage: qemu-bridge-helper [--use-vnet] --br=bridge --fd=unixfd\n");
+ "Usage: qemu-bridge-helper [--use-vnet] [--tap-prefix=prefix] " \
+ " --br=bridge --fd=unixfd\n");
}
static int parse_acl_file(const char *filename, ACLList *acl_list)
@@ -233,6 +234,7 @@ int main(int argc, char **argv)
int use_vnet = 0;
int mtu;
const char *bridge = NULL;
+ const char *tap_prefix = "tap";
char iface[IFNAMSIZ];
int index;
ACLRule *acl_rule;
@@ -255,6 +257,8 @@ int main(int argc, char **argv)
for (index = 1; index < argc; index++) {
if (strcmp(argv[index], "--use-vnet") == 0) {
use_vnet = 1;
+ } else if (strncmp(argv[index], "--tap-prefix=", 13) == 0) {
+ tap_prefix = &argv[index][13];
} else if (strncmp(argv[index], "--br=", 5) == 0) {
bridge = &argv[index][5];
} else if (strncmp(argv[index], "--fd=", 5) == 0) {
@@ -330,7 +334,8 @@ int main(int argc, char **argv)
/* request a tap device, disable PI, and add vnet header support if
* requested and it's available. */
- prep_ifreq(&ifr, "tap%d");
+ snprintf(iface, sizeof(iface), "%s%s", tap_prefix, "%d");
+ prep_ifreq(&ifr, iface);
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
if (use_vnet && has_vnet_hdr(fd)) {
ifr.ifr_flags |= IFF_VNET_HDR;
@@ -1388,10 +1388,11 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
" use 'vhostfd=h' to connect to an already opened vhost net device\n"
" use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices\n"
" use 'queues=n' to specify the number of queues to be created for multiqueue TAP\n"
- "-net bridge[,vlan=n][,name=str][,br=bridge][,helper=helper]\n"
+ "-net bridge[,vlan=n][,name=str][,br=bridge][,helper=helper][,prefix=prefix]\n"
" connects a host TAP network interface to a host bridge device 'br'\n"
" (default=" DEFAULT_BRIDGE_INTERFACE ") using the program 'helper'\n"
" (default=" DEFAULT_BRIDGE_HELPER ")\n"
+ " (default=" DEFAULT_BRIDGE_PREFIX ") using the interface prefix 'prefix'\n"
#endif
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
this will permit to specify an interface prefix to the tap instead of the default one ("tap") this functionnality is useful when you need an easy way to find the interfaces attached to a given virtual machine example: -net bridge,prefix=tapvmA. -net bridge,prefix=tapvmA. will create `tapvmA.0` and `tapvmA.1` `brctl show | grep vmA` will be an easy way to find the interfaces attached to the vmA Signed-off-by: <william@gandi.net> --- include/net/net.h | 1 + net/tap.c | 18 ++++++++++++------ qapi-schema.json | 3 ++- qemu-bridge-helper.c | 9 +++++++-- qemu-options.hx | 3 ++- 5 files changed, 24 insertions(+), 10 deletions(-)