xref: /freebsd/sys/dev/hyperv/utilities/hv_kvp.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1d940bfecSPeter Grehan /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
47cd9b96bSSepherosa Ziehau  * Copyright (c) 2014,2016 Microsoft Corp.
5d940bfecSPeter Grehan  * All rights reserved.
6d940bfecSPeter Grehan  *
7d940bfecSPeter Grehan  * Redistribution and use in source and binary forms, with or without
8d940bfecSPeter Grehan  * modification, are permitted provided that the following conditions
9d940bfecSPeter Grehan  * are met:
10d940bfecSPeter Grehan  * 1. Redistributions of source code must retain the above copyright
11d940bfecSPeter Grehan  *    notice unmodified, this list of conditions, and the following
12d940bfecSPeter Grehan  *    disclaimer.
13d940bfecSPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
14d940bfecSPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
15d940bfecSPeter Grehan  *    documentation and/or other materials provided with the distribution.
16d940bfecSPeter Grehan  *
17d940bfecSPeter Grehan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18d940bfecSPeter Grehan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19d940bfecSPeter Grehan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20d940bfecSPeter Grehan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21d940bfecSPeter Grehan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22d940bfecSPeter Grehan  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23d940bfecSPeter Grehan  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24d940bfecSPeter Grehan  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25d940bfecSPeter Grehan  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26d940bfecSPeter Grehan  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27d940bfecSPeter Grehan  */
28d940bfecSPeter Grehan 
29d940bfecSPeter Grehan #ifndef _KVP_H
30d940bfecSPeter Grehan #define _KVP_H
31d940bfecSPeter Grehan /*
32d940bfecSPeter Grehan  * An implementation of HyperV key value pair (KVP) functionality for FreeBSD
33d940bfecSPeter Grehan  *
34d940bfecSPeter Grehan  */
35d940bfecSPeter Grehan 
36d940bfecSPeter Grehan /*
37d940bfecSPeter Grehan  * Maximum value size - used for both key names and value data, and includes
38d940bfecSPeter Grehan  * any applicable NULL terminators.
39d940bfecSPeter Grehan  *
40d940bfecSPeter Grehan  * Note:  This limit is somewhat arbitrary, but falls easily within what is
41d940bfecSPeter Grehan  * supported for all native guests (back to Win 2000) and what is reasonable
42d940bfecSPeter Grehan  * for the IC KVP exchange functionality.  Note that Windows Me/98/95 are
43d940bfecSPeter Grehan  * limited to 255 character key names.
44d940bfecSPeter Grehan  *
45d940bfecSPeter Grehan  * MSDN recommends not storing data values larger than 2048 bytes in the
46d940bfecSPeter Grehan  * registry.
47d940bfecSPeter Grehan  *
48d940bfecSPeter Grehan  * Note:  This value is used in defining the KVP exchange message - this value
49d940bfecSPeter Grehan  * cannot be modified without affecting the message size and compatibility.
50d940bfecSPeter Grehan  */
51d940bfecSPeter Grehan 
52d940bfecSPeter Grehan /*
53d940bfecSPeter Grehan  * bytes, including any null terminators
54d940bfecSPeter Grehan  */
55d940bfecSPeter Grehan #define HV_KVP_EXCHANGE_MAX_VALUE_SIZE    (2048)
56d940bfecSPeter Grehan 
57d940bfecSPeter Grehan 
58d940bfecSPeter Grehan /*
59d940bfecSPeter Grehan  * Maximum key size - the registry limit for the length of an entry name
60d940bfecSPeter Grehan  * is 256 characters, including the null terminator
61d940bfecSPeter Grehan  */
62d940bfecSPeter Grehan #define HV_KVP_EXCHANGE_MAX_KEY_SIZE    (512)
63d940bfecSPeter Grehan 
64e72055b7SXin LI 
65d940bfecSPeter Grehan /*
66d940bfecSPeter Grehan  * In FreeBSD, we implement the KVP functionality in two components:
67d940bfecSPeter Grehan  * 1) The kernel component which is packaged as part of the hv_utils driver
68d940bfecSPeter Grehan  * is responsible for communicating with the host and responsible for
69d940bfecSPeter Grehan  * implementing the host/guest protocol. 2) A user level daemon that is
70d940bfecSPeter Grehan  * responsible for data gathering.
71d940bfecSPeter Grehan  *
72d940bfecSPeter Grehan  * Host/Guest Protocol: The host iterates over an index and expects the guest
73d940bfecSPeter Grehan  * to assign a key name to the index and also return the value corresponding to
74d940bfecSPeter Grehan  * the key. The host will have atmost one KVP transaction outstanding at any
75d940bfecSPeter Grehan  * given point in time. The host side iteration stops when the guest returns
76d940bfecSPeter Grehan  * an error. Microsoft has specified the following mapping of key names to
77d940bfecSPeter Grehan  * host specified index:
78d940bfecSPeter Grehan  *
79d940bfecSPeter Grehan  *  Index		Key Name
80d940bfecSPeter Grehan  *	0		FullyQualifiedDomainName
81d940bfecSPeter Grehan  *	1		IntegrationServicesVersion
82d940bfecSPeter Grehan  *	2		NetworkAddressIPv4
83d940bfecSPeter Grehan  *	3		NetworkAddressIPv6
84d940bfecSPeter Grehan  *	4		OSBuildNumber
85d940bfecSPeter Grehan  *	5		OSName
86d940bfecSPeter Grehan  *	6		OSMajorVersion
87d940bfecSPeter Grehan  *	7		OSMinorVersion
88d940bfecSPeter Grehan  *	8		OSVersion
89d940bfecSPeter Grehan  *	9		ProcessorArchitecture
90d940bfecSPeter Grehan  *
91d940bfecSPeter Grehan  * The Windows host expects the Key Name and Key Value to be encoded in utf16.
92d940bfecSPeter Grehan  *
93d940bfecSPeter Grehan  * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the
94d940bfecSPeter Grehan  * data gathering functionality in a user mode daemon. The user level daemon
95d940bfecSPeter Grehan  * is also responsible for binding the key name to the index as well. The
96d940bfecSPeter Grehan  * kernel and user-level daemon communicate using a connector channel.
97d940bfecSPeter Grehan  *
98d940bfecSPeter Grehan  * The user mode component first registers with the
99d940bfecSPeter Grehan  * the kernel component. Subsequently, the kernel component requests, data
100d940bfecSPeter Grehan  * for the specified keys. In response to this message the user mode component
101d940bfecSPeter Grehan  * fills in the value corresponding to the specified key. We overload the
102d940bfecSPeter Grehan  * sequence field in the cn_msg header to define our KVP message types.
103d940bfecSPeter Grehan  *
104d940bfecSPeter Grehan  *
105d940bfecSPeter Grehan  * The kernel component simply acts as a conduit for communication between the
106d940bfecSPeter Grehan  * Windows host and the user-level daemon. The kernel component passes up the
107d940bfecSPeter Grehan  * index received from the Host to the user-level daemon. If the index is
108d940bfecSPeter Grehan  * valid (supported), the corresponding key as well as its
109d940bfecSPeter Grehan  * value (both are strings) is returned. If the index is invalid
110d940bfecSPeter Grehan  * (not supported), a NULL key string is returned.
111d940bfecSPeter Grehan  */
112d940bfecSPeter Grehan 
113d940bfecSPeter Grehan 
114d940bfecSPeter Grehan /*
115d940bfecSPeter Grehan  * Registry value types.
116d940bfecSPeter Grehan  */
117d940bfecSPeter Grehan #define HV_REG_SZ     1
118d940bfecSPeter Grehan #define HV_REG_U32    4
119d940bfecSPeter Grehan #define HV_REG_U64    8
120d940bfecSPeter Grehan 
121d940bfecSPeter Grehan 
122d940bfecSPeter Grehan /*
123e72055b7SXin LI  * Daemon code supporting IP injection.
124d940bfecSPeter Grehan  */
125d940bfecSPeter Grehan #define HV_KVP_OP_REGISTER    4
126d940bfecSPeter Grehan 
127d940bfecSPeter Grehan 
128d940bfecSPeter Grehan enum hv_kvp_exchg_op {
129d940bfecSPeter Grehan 	HV_KVP_OP_GET = 0,
130d940bfecSPeter Grehan 	HV_KVP_OP_SET,
131d940bfecSPeter Grehan 	HV_KVP_OP_DELETE,
132d940bfecSPeter Grehan 	HV_KVP_OP_ENUMERATE,
133d940bfecSPeter Grehan 	HV_KVP_OP_GET_IP_INFO,
134d940bfecSPeter Grehan 	HV_KVP_OP_SET_IP_INFO,
135d940bfecSPeter Grehan 	HV_KVP_OP_COUNT /* Number of operations, must be last. */
136d940bfecSPeter Grehan };
137d940bfecSPeter Grehan 
138d940bfecSPeter Grehan enum hv_kvp_exchg_pool {
139d940bfecSPeter Grehan 	HV_KVP_POOL_EXTERNAL = 0,
140d940bfecSPeter Grehan 	HV_KVP_POOL_GUEST,
141d940bfecSPeter Grehan 	HV_KVP_POOL_AUTO,
142d940bfecSPeter Grehan 	HV_KVP_POOL_AUTO_EXTERNAL,
143d940bfecSPeter Grehan 	HV_KVP_POOL_AUTO_INTERNAL,
144d940bfecSPeter Grehan 	HV_KVP_POOL_COUNT /* Number of pools, must be last. */
145d940bfecSPeter Grehan };
146d940bfecSPeter Grehan 
147d940bfecSPeter Grehan #define ADDR_FAMILY_NONE                 0x00
148d940bfecSPeter Grehan #define ADDR_FAMILY_IPV4                 0x01
149d940bfecSPeter Grehan #define ADDR_FAMILY_IPV6                 0x02
150d940bfecSPeter Grehan 
151d940bfecSPeter Grehan #define MAX_ADAPTER_ID_SIZE              128
152d940bfecSPeter Grehan #define MAX_IP_ADDR_SIZE                 1024
153d940bfecSPeter Grehan #define MAX_GATEWAY_SIZE                 512
154d940bfecSPeter Grehan 
155d940bfecSPeter Grehan 
156d940bfecSPeter Grehan struct hv_kvp_ipaddr_value {
157d940bfecSPeter Grehan 	uint16_t adapter_id[MAX_ADAPTER_ID_SIZE];
158d940bfecSPeter Grehan 	uint8_t  addr_family;
159d940bfecSPeter Grehan 	uint8_t  dhcp_enabled;
160d940bfecSPeter Grehan 	uint16_t ip_addr[MAX_IP_ADDR_SIZE];
161d940bfecSPeter Grehan 	uint16_t sub_net[MAX_IP_ADDR_SIZE];
162d940bfecSPeter Grehan 	uint16_t gate_way[MAX_GATEWAY_SIZE];
163d940bfecSPeter Grehan 	uint16_t dns_addr[MAX_IP_ADDR_SIZE];
164d940bfecSPeter Grehan }__attribute__((packed));
165d940bfecSPeter Grehan 
166d940bfecSPeter Grehan struct hv_kvp_hdr {
167d940bfecSPeter Grehan 	uint8_t                 operation;
168d940bfecSPeter Grehan 	uint8_t                 pool;
169d940bfecSPeter Grehan 	uint16_t                pad;
170d940bfecSPeter Grehan } __attribute__((packed));
171d940bfecSPeter Grehan 
172d940bfecSPeter Grehan struct hv_kvp_exchg_msg_value {
173d940bfecSPeter Grehan 	uint32_t value_type;
174d940bfecSPeter Grehan 	uint32_t key_size;
175d940bfecSPeter Grehan 	uint32_t value_size;
176d940bfecSPeter Grehan 	uint8_t  key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
177d940bfecSPeter Grehan 	union {
178d940bfecSPeter Grehan 		uint8_t  value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
179d940bfecSPeter Grehan 		uint32_t value_u32;
180d940bfecSPeter Grehan 		uint64_t value_u64;
181d940bfecSPeter Grehan 	} msg_value;
182d940bfecSPeter Grehan } __attribute__((packed));
183d940bfecSPeter Grehan 
184d940bfecSPeter Grehan struct hv_kvp_msg_enumerate {
185d940bfecSPeter Grehan 	uint32_t index;
186d940bfecSPeter Grehan 	struct hv_kvp_exchg_msg_value data;
187d940bfecSPeter Grehan } __attribute__((packed));
188d940bfecSPeter Grehan 
189d940bfecSPeter Grehan struct hv_kvp_msg_get {
190d940bfecSPeter Grehan 	struct hv_kvp_exchg_msg_value data;
191d940bfecSPeter Grehan } __attribute__((packed));
192d940bfecSPeter Grehan 
193d940bfecSPeter Grehan struct hv_kvp_msg_set {
194d940bfecSPeter Grehan 	struct hv_kvp_exchg_msg_value data;
195d940bfecSPeter Grehan } __attribute__((packed));
196d940bfecSPeter Grehan 
197d940bfecSPeter Grehan struct hv_kvp_msg_delete {
198d940bfecSPeter Grehan 	uint32_t key_size;
199d940bfecSPeter Grehan 	uint8_t key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
200d940bfecSPeter Grehan } __attribute__((packed));
201d940bfecSPeter Grehan 
202d940bfecSPeter Grehan struct hv_kvp_register {
203d940bfecSPeter Grehan 	uint8_t version[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
204d940bfecSPeter Grehan } __attribute__((packed));
205d940bfecSPeter Grehan 
206d940bfecSPeter Grehan struct hv_kvp_msg {
207d940bfecSPeter Grehan 	union {
208d940bfecSPeter Grehan 		struct hv_kvp_hdr kvp_hdr;
209e72055b7SXin LI 		uint32_t error;
210d940bfecSPeter Grehan 	} hdr;
211d940bfecSPeter Grehan 	union {
212d940bfecSPeter Grehan 		struct hv_kvp_msg_get		kvp_get;
213d940bfecSPeter Grehan 		struct hv_kvp_msg_set		kvp_set;
214d940bfecSPeter Grehan 		struct hv_kvp_msg_delete	kvp_delete;
215d940bfecSPeter Grehan 		struct hv_kvp_msg_enumerate	kvp_enum_data;
216d940bfecSPeter Grehan 		struct hv_kvp_ipaddr_value	kvp_ip_val;
217d940bfecSPeter Grehan 		struct hv_kvp_register		kvp_register;
218d940bfecSPeter Grehan 	} body;
219d940bfecSPeter Grehan } __attribute__((packed));
220d940bfecSPeter Grehan 
221d940bfecSPeter Grehan struct hv_kvp_ip_msg {
222d940bfecSPeter Grehan 	uint8_t operation;
223d940bfecSPeter Grehan 	uint8_t pool;
224d940bfecSPeter Grehan 	struct hv_kvp_ipaddr_value      kvp_ip_val;
225d940bfecSPeter Grehan } __attribute__((packed));
226d940bfecSPeter Grehan 
227d940bfecSPeter Grehan #endif /* _KVP_H */
228