xref: /openbmc/qemu/net/vmnet-shared.c (revision a0124e33)
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 
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 
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 
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