vmnet-host.c 3.7 KB

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