Commit c1d6eed7e85f5cfae9c548e58971db657237050a
Committed by
Anthony Liguori
1 parent
7768e04c
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>
Showing
1 changed file
with
35 additions
and
7 deletions
net.c
... | ... | @@ -2410,6 +2410,23 @@ void qemu_check_nic_model_list(NICInfo *nd, const char * const *models, |
2410 | 2410 | exit(exit_status); |
2411 | 2411 | } |
2412 | 2412 | |
2413 | +static int net_handle_fd_param(Monitor *mon, const char *param) | |
2414 | +{ | |
2415 | + if (!qemu_isdigit(param[0])) { | |
2416 | + int fd; | |
2417 | + | |
2418 | + fd = monitor_get_fd(mon, param); | |
2419 | + if (fd == -1) { | |
2420 | + config_error(mon, "No file descriptor named %s found", param); | |
2421 | + return -1; | |
2422 | + } | |
2423 | + | |
2424 | + return fd; | |
2425 | + } else { | |
2426 | + return strtol(param, NULL, 0); | |
2427 | + } | |
2428 | +} | |
2429 | + | |
2413 | 2430 | int net_client_init(Monitor *mon, const char *device, const char *p) |
2414 | 2431 | { |
2415 | 2432 | char buf[1024]; |
... | ... | @@ -2650,14 +2667,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p) |
2650 | 2667 | static const char * const fd_params[] = { |
2651 | 2668 | "vlan", "name", "fd", "sndbuf", NULL |
2652 | 2669 | }; |
2670 | + ret = -1; | |
2653 | 2671 | if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) { |
2654 | 2672 | config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p); |
2655 | - ret = -1; | |
2656 | 2673 | goto out; |
2657 | 2674 | } |
2658 | - fd = strtol(buf, NULL, 0); | |
2675 | + fd = net_handle_fd_param(mon, buf); | |
2676 | + if (fd == -1) { | |
2677 | + goto out; | |
2678 | + } | |
2659 | 2679 | fcntl(fd, F_SETFL, O_NONBLOCK); |
2660 | 2680 | s = net_tap_fd_init(vlan, device, name, fd); |
2681 | + if (!s) { | |
2682 | + close(fd); | |
2683 | + } | |
2661 | 2684 | } else { |
2662 | 2685 | static const char * const tap_params[] = { |
2663 | 2686 | "vlan", "name", "ifname", "script", "downscript", "sndbuf", NULL |
... | ... | @@ -2697,15 +2720,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p) |
2697 | 2720 | "vlan", "name", "fd", NULL |
2698 | 2721 | }; |
2699 | 2722 | int fd; |
2723 | + ret = -1; | |
2700 | 2724 | if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) { |
2701 | 2725 | config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p); |
2702 | - ret = -1; | |
2703 | 2726 | goto out; |
2704 | 2727 | } |
2705 | - fd = strtol(buf, NULL, 0); | |
2706 | - ret = -1; | |
2707 | - if (net_socket_fd_init(vlan, device, name, fd, 1)) | |
2708 | - ret = 0; | |
2728 | + fd = net_handle_fd_param(mon, buf); | |
2729 | + if (fd == -1) { | |
2730 | + goto out; | |
2731 | + } | |
2732 | + if (!net_socket_fd_init(vlan, device, name, fd, 1)) { | |
2733 | + close(fd); | |
2734 | + goto out; | |
2735 | + } | |
2736 | + ret = 0; | |
2709 | 2737 | } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) { |
2710 | 2738 | static const char * const listen_params[] = { |
2711 | 2739 | "vlan", "name", "listen", NULL | ... | ... |