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
validate_options(const Netdev * netdev,Error ** errp)20 static bool validate_options(const Netdev *netdev, Error **errp)
21 {
22 const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
23
24 if ((options->start_address ||
25 options->end_address ||
26 options->subnet_mask) &&
27 !(options->start_address &&
28 options->end_address &&
29 options->subnet_mask)) {
30 error_setg(errp,
31 "'start-address', 'end-address', 'subnet-mask' "
32 "should be provided together"
33 );
34 return false;
35 }
36
37 return true;
38 }
39
build_if_desc(const Netdev * netdev)40 static xpc_object_t build_if_desc(const Netdev *netdev)
41 {
42 const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared);
43 xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);
44
45 xpc_dictionary_set_uint64(
46 if_desc,
47 vmnet_operation_mode_key,
48 VMNET_SHARED_MODE
49 );
50
51 if (options->nat66_prefix) {
52 xpc_dictionary_set_string(if_desc,
53 vmnet_nat66_prefix_key,
54 options->nat66_prefix);
55 }
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
69 xpc_dictionary_set_bool(
70 if_desc,
71 vmnet_enable_isolation_key,
72 options->isolated
73 );
74
75 return if_desc;
76 }
77
78 static NetClientInfo net_vmnet_shared_info = {
79 .type = NET_CLIENT_DRIVER_VMNET_SHARED,
80 .size = sizeof(VmnetState),
81 .receive = vmnet_receive_common,
82 .cleanup = vmnet_cleanup_common,
83 };
84
net_init_vmnet_shared(const Netdev * netdev,const char * name,NetClientState * peer,Error ** errp)85 int net_init_vmnet_shared(const Netdev *netdev, const char *name,
86 NetClientState *peer, Error **errp)
87 {
88 NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info,
89 peer, "vmnet-shared", name);
90 xpc_object_t if_desc;
91 int result = -1;
92
93 if (!validate_options(netdev, errp)) {
94 return result;
95 }
96
97 if_desc = build_if_desc(netdev);
98 result = vmnet_if_create(nc, if_desc, errp);
99 xpc_release(if_desc);
100 return result;
101 }
102