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