Commit c1d6eed7e85f5cfae9c548e58971db657237050a

Authored by Mark McLoughlin
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
... ... @@ -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
... ...