vmnet-shared.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #include "qemu/osdep.h"
  11. #include "qapi/qapi-types-net.h"
  12. #include "qapi/error.h"
  13. #include "vmnet_int.h"
  14. #include "clients.h"
  15. #include <vmnet/vmnet.h>
  16. static bool validate_options(const Netdev *netdev, Error **errp)
  17. {
  18. const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
  19. if (__builtin_available(macOS 11, *)) {
  20. // clang requires a true branch
  21. } else {
  22. if (options->has_isolated) {
  23. error_setg(errp,
  24. "vmnet-shared.isolated feature is "
  25. "unavailable: outdated vmnet.framework API");
  26. return false;
  27. }
  28. }
  29. if ((options->start_address ||
  30. options->end_address ||
  31. options->subnet_mask) &&
  32. !(options->start_address &&
  33. options->end_address &&
  34. options->subnet_mask)) {
  35. error_setg(errp,
  36. "'start-address', 'end-address', 'subnet-mask' "
  37. "should be provided together"
  38. );
  39. return false;
  40. }
  41. return true;
  42. }
  43. static xpc_object_t build_if_desc(const Netdev *netdev)
  44. {
  45. const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
  46. xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
  47. xpc_dictionary_set_uint64(
  48. if_desc,
  49. vmnet_operation_mode_key,
  50. VMNET_SHARED_MODE
  51. );
  52. if (options->nat66_prefix) {
  53. xpc_dictionary_set_string(if_desc,
  54. vmnet_nat66_prefix_key,
  55. options->nat66_prefix);
  56. }
  57. if (options->start_address) {
  58. xpc_dictionary_set_string(if_desc,
  59. vmnet_start_address_key,
  60. options->start_address);
  61. xpc_dictionary_set_string(if_desc,
  62. vmnet_end_address_key,
  63. options->end_address);
  64. xpc_dictionary_set_string(if_desc,
  65. vmnet_subnet_mask_key,
  66. options->subnet_mask);
  67. }
  68. if (__builtin_available(macOS 11, *)) {
  69. xpc_dictionary_set_bool(
  70. if_desc,
  71. vmnet_enable_isolation_key,
  72. options->isolated
  73. );
  74. }
  75. return if_desc;
  76. }
  77. static NetClientInfo net_vmnet_shared_info = {
  78. .type = NET_CLIENT_DRIVER_VMNET_SHARED,
  79. .size = sizeof(VmnetState),
  80. .receive = vmnet_receive_common,
  81. .cleanup = vmnet_cleanup_common,
  82. };
  83. int net_init_vmnet_shared(const Netdev *netdev, const char *name,
  84. NetClientState *peer, Error **errp)
  85. {
  86. NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
  87. peer, "vmnet-shared", name);
  88. xpc_object_t if_desc;
  89. int result = -1;
  90. if (!validate_options(netdev, errp)) {
  91. return result;
  92. }
  93. if_desc = build_if_desc(netdev);
  94. result = vmnet_if_create(nc, if_desc, errp);
  95. xpc_release(if_desc);
  96. return result;
  97. }