qemu/net/vmnet-shared.c
<<
>>
Prefs
   1/*
   2 * vmnet-shared.c
   3 *
   4 * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   7 * See the COPYING file in the top-level directory.
   8 *
   9 */
  10
  11#include "qemu/osdep.h"
  12#include "qapi/qapi-types-net.h"
  13#include "qapi/error.h"
  14#include "vmnet_int.h"
  15#include "clients.h"
  16
  17#include <vmnet/vmnet.h>
  18
  19
  20static bool validate_options(const Netdev *netdev, Error **errp)
  21{
  22    const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
  23
  24#if !defined(MAC_OS_VERSION_11_0) || \
  25    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_11_0
  26    if (options->has_isolated) {
  27        error_setg(errp,
  28                   "vmnet-shared.isolated feature is "
  29                   "unavailable: outdated vmnet.framework API");
  30        return false;
  31    }
  32#endif
  33
  34    if ((options->start_address ||
  35         options->end_address ||
  36         options->subnet_mask) &&
  37        !(options->start_address &&
  38          options->end_address &&
  39          options->subnet_mask)) {
  40        error_setg(errp,
  41                   "'start-address', 'end-address', 'subnet-mask' "
  42                   "should be provided together"
  43        );
  44        return false;
  45    }
  46
  47    return true;
  48}
  49
  50static xpc_object_t build_if_desc(const Netdev *netdev)
  51{
  52    const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
  53    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
  54
  55    xpc_dictionary_set_uint64(
  56        if_desc,
  57        vmnet_operation_mode_key,
  58        VMNET_SHARED_MODE
  59    );
  60
  61    if (options->nat66_prefix) {
  62        xpc_dictionary_set_string(if_desc,
  63                                  vmnet_nat66_prefix_key,
  64                                  options->nat66_prefix);
  65    }
  66
  67    if (options->start_address) {
  68        xpc_dictionary_set_string(if_desc,
  69                                  vmnet_start_address_key,
  70                                  options->start_address);
  71        xpc_dictionary_set_string(if_desc,
  72                                  vmnet_end_address_key,
  73                                  options->end_address);
  74        xpc_dictionary_set_string(if_desc,
  75                                  vmnet_subnet_mask_key,
  76                                  options->subnet_mask);
  77    }
  78
  79#if defined(MAC_OS_VERSION_11_0) && \
  80    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
  81    xpc_dictionary_set_bool(
  82        if_desc,
  83        vmnet_enable_isolation_key,
  84        options->isolated
  85    );
  86#endif
  87
  88    return if_desc;
  89}
  90
  91static NetClientInfo net_vmnet_shared_info = {
  92    .type = NET_CLIENT_DRIVER_VMNET_SHARED,
  93    .size = sizeof(VmnetState),
  94    .receive = vmnet_receive_common,
  95    .cleanup = vmnet_cleanup_common,
  96};
  97
  98int net_init_vmnet_shared(const Netdev *netdev, const char *name,
  99                          NetClientState *peer, Error **errp)
 100{
 101    NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
 102                                             peer, "vmnet-shared", name);
 103    xpc_object_t if_desc;
 104    int result = -1;
 105
 106    if (!validate_options(netdev, errp)) {
 107        return result;
 108    }
 109
 110    if_desc = build_if_desc(netdev);
 111    result = vmnet_if_create(nc, if_desc, errp);
 112    xpc_release(if_desc);
 113    return result;
 114}
 115