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