aboutsummaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
authorMark McLoughlin <markmc@redhat.com>2009-07-22 09:11:42 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-07-27 08:39:28 -0500
commitc1d6eed7e85f5cfae9c548e58971db657237050a (patch)
tree88ef980b95f0142d376e5d222df091a80dfb2eb4 /net.c
parentAdd monitor_get_fd() command for fetching named fds (diff)
downloadqemu-kvm-c1d6eed7e85f5cfae9c548e58971db657237050a.tar.gz
qemu-kvm-c1d6eed7e85f5cfae9c548e58971db657237050a.tar.bz2
qemu-kvm-c1d6eed7e85f5cfae9c548e58971db657237050a.zip
Add support for fd=name to tap and socket networking
This allows a program to initialize a host networking device using a file descriptor passed over a unix monitor socket. The program must first pass the file descriptor using SCM_RIGHTS ancillary data with the getfd monitor command. It then may do "host_net_add tap fd=name" to use the named file descriptor. Signed-off-by: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'net.c')
-rw-r--r--net.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/net.c b/net.c
index 90cf91237..1838692f0 100644
--- a/net.c
+++ b/net.c
@@ -2410,6 +2410,23 @@ void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
exit(exit_status);
}
+static int net_handle_fd_param(Monitor *mon, const char *param)
+{
+ if (!qemu_isdigit(param[0])) {
+ int fd;
+
+ fd = monitor_get_fd(mon, param);
+ if (fd == -1) {
+ config_error(mon, "No file descriptor named %s found", param);
+ return -1;
+ }
+
+ return fd;
+ } else {
+ return strtol(param, NULL, 0);
+ }
+}
+
int net_client_init(Monitor *mon, const char *device, const char *p)
{
char buf[1024];
@@ -2650,14 +2667,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
static const char * const fd_params[] = {
"vlan", "name", "fd", "sndbuf", NULL
};
+ ret = -1;
if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
- ret = -1;
goto out;
}
- fd = strtol(buf, NULL, 0);
+ fd = net_handle_fd_param(mon, buf);
+ if (fd == -1) {
+ goto out;
+ }
fcntl(fd, F_SETFL, O_NONBLOCK);
s = net_tap_fd_init(vlan, device, name, fd);
+ if (!s) {
+ close(fd);
+ }
} else {
static const char * const tap_params[] = {
"vlan", "name", "ifname", "script", "downscript", "sndbuf", NULL
@@ -2697,15 +2720,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
"vlan", "name", "fd", NULL
};
int fd;
+ ret = -1;
if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
- ret = -1;
goto out;
}
- fd = strtol(buf, NULL, 0);
- ret = -1;
- if (net_socket_fd_init(vlan, device, name, fd, 1))
- ret = 0;
+ fd = net_handle_fd_param(mon, buf);
+ if (fd == -1) {
+ goto out;
+ }
+ if (!net_socket_fd_init(vlan, device, name, fd, 1)) {
+ close(fd);
+ goto out;
+ }
+ ret = 0;
} else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
static const char * const listen_params[] = {
"vlan", "name", "listen", NULL