2
0

vmnet-host.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * vmnet-host.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. #include "qemu/osdep.h"
  11. #include "qemu/uuid.h"
  12. #include "qapi/qapi-types-net.h"
  13. #include "qapi/error.h"
  14. #include "clients.h"
  15. #include "vmnet_int.h"
  16. #include <vmnet/vmnet.h>
  17. static bool validate_options(const Netdev *netdev, Error **errp)
  18. {
  19. const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
  20. #if defined(MAC_OS_VERSION_11_0) && \
  21. MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
  22. QemuUUID net_uuid;
  23. if (options->net_uuid &&
  24. qemu_uuid_parse(options->net_uuid, &net_uuid) < 0) {
  25. error_setg(errp, "Invalid UUID provided in 'net-uuid'");
  26. return false;
  27. }
  28. #else
  29. if (options->has_isolated) {
  30. error_setg(errp,
  31. "vmnet-host.isolated feature is "
  32. "unavailable: outdated vmnet.framework API");
  33. return false;
  34. }
  35. if (options->net_uuid) {
  36. error_setg(errp,
  37. "vmnet-host.net-uuid feature is "
  38. "unavailable: outdated vmnet.framework API");
  39. return false;
  40. }
  41. #endif
  42. if ((options->start_address ||
  43. options->end_address ||
  44. options->subnet_mask) &&
  45. !(options->start_address &&
  46. options->end_address &&
  47. options->subnet_mask)) {
  48. error_setg(errp,
  49. "'start-address', 'end-address', 'subnet-mask' "
  50. "should be provided together");
  51. return false;
  52. }
  53. return true;
  54. }
  55. static xpc_object_t build_if_desc(const Netdev *netdev)
  56. {
  57. const NetdevVmnetHostOptions *options = &(netdev->u.vmnet_host);
  58. xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
  59. xpc_dictionary_set_uint64(if_desc,
  60. vmnet_operation_mode_key,
  61. VMNET_HOST_MODE);
  62. #if defined(MAC_OS_VERSION_11_0) && \
  63. MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
  64. xpc_dictionary_set_bool(if_desc,
  65. vmnet_enable_isolation_key,
  66. options->isolated);
  67. QemuUUID net_uuid;
  68. if (options->net_uuid) {
  69. qemu_uuid_parse(options->net_uuid, &net_uuid);
  70. xpc_dictionary_set_uuid(if_desc,
  71. vmnet_network_identifier_key,
  72. net_uuid.data);
  73. }
  74. #endif
  75. if (options->start_address) {
  76. xpc_dictionary_set_string(if_desc,
  77. vmnet_start_address_key,
  78. options->start_address);
  79. xpc_dictionary_set_string(if_desc,
  80. vmnet_end_address_key,
  81. options->end_address);
  82. xpc_dictionary_set_string(if_desc,
  83. vmnet_subnet_mask_key,
  84. options->subnet_mask);
  85. }
  86. return if_desc;
  87. }
  88. static NetClientInfo net_vmnet_host_info = {
  89. .type = NET_CLIENT_DRIVER_VMNET_HOST,
  90. .size = sizeof(VmnetState),
  91. .receive = vmnet_receive_common,
  92. .cleanup = vmnet_cleanup_common,
  93. };
  94. int net_init_vmnet_host(const Netdev *netdev, const char *name,
  95. NetClientState *peer, Error **errp)
  96. {
  97. NetClientState *nc = qemu_new_net_client(&net_vmnet_host_info,
  98. peer, "vmnet-host", name);
  99. xpc_object_t if_desc;
  100. int result = -1;
  101. if (!validate_options(netdev, errp)) {
  102. return result;
  103. }
  104. if_desc = build_if_desc(netdev);
  105. result = vmnet_if_create(nc, if_desc, errp);
  106. xpc_release(if_desc);
  107. return result;
  108. }