diff options
author | Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com> | 2022-03-17 20:28:35 +0300 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2022-05-17 16:48:23 +0800 |
commit | 73f99db534e36cdf7dd045b3fde2af29132c0a35 (patch) | |
tree | bfd6cf50e7a8d988292e6e57ffb332ebf52a8bc8 /net/vmnet-shared.c | |
parent | 81ad2964e93848fc0998145043c395dea67f00da (diff) |
net/vmnet: implement shared mode (vmnet-shared)
Interaction with vmnet.framework in different modes
differs only on configuration stage, so we can create
common `send`, `receive`, etc. procedures and reuse them.
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Signed-off-by: Phillip Tennen <phillip@axleos.com>
Signed-off-by: Vladislav Yaroshchuk <Vladislav.Yaroshchuk@jetbrains.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'net/vmnet-shared.c')
-rw-r--r-- | net/vmnet-shared.c | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/net/vmnet-shared.c b/net/vmnet-shared.c index 6dfb133a18..18cadc72bd 100644 --- a/net/vmnet-shared.c +++ b/net/vmnet-shared.c @@ -10,16 +10,105 @@ #include "qemu/osdep.h" #include "qapi/qapi-types-net.h" +#include "qapi/error.h" #include "vmnet_int.h" #include "clients.h" -#include "qemu/error-report.h" -#include "qapi/error.h" #include <vmnet/vmnet.h> + +static bool validate_options(const Netdev *netdev, Error **errp) +{ + const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared); + +#if !defined(MAC_OS_VERSION_11_0) || \ + MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_11_0 + if (options->has_isolated) { + error_setg(errp, + "vmnet-shared.isolated feature is " + "unavailable: outdated vmnet.framework API"); + return false; + } +#endif + + if ((options->has_start_address || + options->has_end_address || + options->has_subnet_mask) && + !(options->has_start_address && + options->has_end_address && + options->has_subnet_mask)) { + error_setg(errp, + "'start-address', 'end-address', 'subnet-mask' " + "should be provided together" + ); + return false; + } + + return true; +} + +static xpc_object_t build_if_desc(const Netdev *netdev) +{ + const NetdevVmnetSharedOptions *options = &(netdev->u.vmnet_shared); + xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0); + + xpc_dictionary_set_uint64( + if_desc, + vmnet_operation_mode_key, + VMNET_SHARED_MODE + ); + + if (options->has_nat66_prefix) { + xpc_dictionary_set_string(if_desc, + vmnet_nat66_prefix_key, + options->nat66_prefix); + } + + if (options->has_start_address) { + xpc_dictionary_set_string(if_desc, + vmnet_start_address_key, + options->start_address); + xpc_dictionary_set_string(if_desc, + vmnet_end_address_key, + options->end_address); + xpc_dictionary_set_string(if_desc, + vmnet_subnet_mask_key, + options->subnet_mask); + } + +#if defined(MAC_OS_VERSION_11_0) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0 + xpc_dictionary_set_bool( + if_desc, + vmnet_enable_isolation_key, + options->isolated + ); +#endif + + return if_desc; +} + +static NetClientInfo net_vmnet_shared_info = { + .type = NET_CLIENT_DRIVER_VMNET_SHARED, + .size = sizeof(VmnetState), + .receive = vmnet_receive_common, + .cleanup = vmnet_cleanup_common, +}; + int net_init_vmnet_shared(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp) { - error_setg(errp, "vmnet-shared is not implemented yet"); - return -1; + NetClientState *nc = qemu_new_net_client(&net_vmnet_shared_info, + peer, "vmnet-shared", name); + xpc_object_t if_desc; + int result = -1; + + if (!validate_options(netdev, errp)) { + return result; + } + + if_desc = build_if_desc(netdev); + result = vmnet_if_create(nc, if_desc, errp); + xpc_release(if_desc); + return result; } |