xref: /xnu-8019.80.24/libsyscall/wrappers/skywalk/os_nexus.c (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
1 /*
2  * Copyright (c) 2015-2021 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #include <skywalk/os_skywalk_private.h>
36 
37 #ifndef LIBSYSCALL_INTERFACE
38 #error "LIBSYSCALL_INTERFACE not defined"
39 #endif /* !LIBSYSCALL_INTERFACE */
40 
41 nexus_attr_t
os_nexus_attr_create(void)42 os_nexus_attr_create(void)
43 {
44 	struct nexus_attr *nxa;
45 
46 	nxa = malloc(sizeof(*nxa));
47 	if (nxa != NULL) {
48 		bzero(nxa, sizeof(*nxa));
49 	}
50 	return nxa;
51 }
52 
53 nexus_attr_t
os_nexus_attr_clone(const nexus_attr_t nxa)54 os_nexus_attr_clone(const nexus_attr_t nxa)
55 {
56 	struct nexus_attr *nnxa = NULL;
57 
58 	nnxa = os_nexus_attr_create();
59 	if (nnxa != NULL && nxa != NULL) {
60 		bcopy(nxa, nnxa, sizeof(*nnxa));
61 	}
62 
63 	return nnxa;
64 }
65 
66 int
os_nexus_attr_set(const nexus_attr_t nxa,const nexus_attr_type_t type,const uint64_t value)67 os_nexus_attr_set(const nexus_attr_t nxa, const nexus_attr_type_t type,
68     const uint64_t value)
69 {
70 	return __nexus_attr_set(nxa, type, value);
71 }
72 
73 int
os_nexus_attr_get(const nexus_attr_t nxa,const nexus_attr_type_t type,uint64_t * value)74 os_nexus_attr_get(const nexus_attr_t nxa, const nexus_attr_type_t type,
75     uint64_t *value)
76 {
77 	return __nexus_attr_get(nxa, type, value);
78 }
79 
80 void
os_nexus_attr_destroy(nexus_attr_t nxa)81 os_nexus_attr_destroy(nexus_attr_t nxa)
82 {
83 	free(nxa);
84 }
85 
86 nexus_controller_t
os_nexus_controller_create(void)87 os_nexus_controller_create(void)
88 {
89 	struct nexus_controller *ncd = NULL;
90 	struct nxctl_init init;
91 	int fd;
92 
93 	bzero(&init, sizeof(init));
94 	init.ni_version = NEXUSCTL_INIT_CURRENT_VERSION;
95 
96 	fd = __nexus_open(&init, sizeof(init));
97 	if (fd == -1) {
98 		goto done;
99 	}
100 
101 	ncd = malloc(sizeof(*ncd));
102 	if (ncd == NULL) {
103 		(void) guarded_close_np(fd, &init.ni_guard);
104 		goto done;
105 	}
106 	bzero(ncd, sizeof(*ncd));
107 	ncd->ncd_fd = fd;
108 	ncd->ncd_guard = init.ni_guard;
109 done:
110 	return ncd;
111 }
112 
113 int
os_nexus_controller_get_fd(const nexus_controller_t ncd)114 os_nexus_controller_get_fd(const nexus_controller_t ncd)
115 {
116 	return ncd->ncd_fd;
117 }
118 
119 int
os_nexus_controller_register_provider(const nexus_controller_t ncd,const nexus_name_t name,const nexus_type_t type,const nexus_attr_t nxa,uuid_t * prov_uuid)120 os_nexus_controller_register_provider(const nexus_controller_t ncd,
121     const nexus_name_t name, const nexus_type_t type,
122     const nexus_attr_t nxa, uuid_t *prov_uuid)
123 {
124 	struct nxprov_reg reg;
125 	int err;
126 
127 	if ((err = __nexus_provider_reg_prepare(&reg, name, type, nxa)) == 0) {
128 		err = __nexus_register(ncd->ncd_fd, &reg, sizeof(reg),
129 		    prov_uuid, sizeof(uuid_t));
130 	}
131 	return err;
132 }
133 
134 int
os_nexus_controller_deregister_provider(const nexus_controller_t ncd,const uuid_t prov_uuid)135 os_nexus_controller_deregister_provider(const nexus_controller_t ncd,
136     const uuid_t prov_uuid)
137 {
138 	return __nexus_deregister(ncd->ncd_fd, prov_uuid, sizeof(uuid_t));
139 }
140 
141 int
os_nexus_controller_alloc_provider_instance(const nexus_controller_t ncd,const uuid_t prov_uuid,uuid_t * nx_uuid)142 os_nexus_controller_alloc_provider_instance(const nexus_controller_t ncd,
143     const uuid_t prov_uuid, uuid_t *nx_uuid)
144 {
145 	return __nexus_create(ncd->ncd_fd, prov_uuid, sizeof(uuid_t),
146 	           nx_uuid, sizeof(uuid_t));
147 }
148 
149 int
os_nexus_controller_free_provider_instance(const nexus_controller_t ncd,const uuid_t nx_uuid)150 os_nexus_controller_free_provider_instance(const nexus_controller_t ncd,
151     const uuid_t nx_uuid)
152 {
153 	return __nexus_destroy(ncd->ncd_fd, nx_uuid, sizeof(uuid_t));
154 }
155 
156 int
os_nexus_controller_bind_provider_instance(const nexus_controller_t ncd,const uuid_t nx_uuid,const nexus_port_t port,const pid_t pid,const uuid_t exec_uuid,const void * key,const uint32_t key_len,uint32_t bind_flags)157 os_nexus_controller_bind_provider_instance(const nexus_controller_t ncd,
158     const uuid_t nx_uuid, const nexus_port_t port, const pid_t pid,
159     const uuid_t exec_uuid, const void *key, const uint32_t key_len,
160     uint32_t bind_flags)
161 {
162 	struct nx_bind_req nbr;
163 
164 	__nexus_bind_req_prepare(&nbr, nx_uuid, port, pid, exec_uuid,
165 	    key, key_len, bind_flags);
166 
167 	return __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_BIND,
168 	           &nbr, sizeof(nbr));
169 }
170 
171 int
os_nexus_controller_unbind_provider_instance(const nexus_controller_t ncd,const uuid_t nx_uuid,const nexus_port_t port)172 os_nexus_controller_unbind_provider_instance(const nexus_controller_t ncd,
173     const uuid_t nx_uuid, const nexus_port_t port)
174 {
175 	struct nx_unbind_req nbu;
176 
177 	__nexus_unbind_req_prepare(&nbu, nx_uuid, port);
178 
179 	return __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_UNBIND,
180 	           &nbu, sizeof(nbu));
181 }
182 
183 int
os_nexus_controller_read_provider_attr(const nexus_controller_t ncd,const uuid_t prov_uuid,nexus_attr_t nxa)184 os_nexus_controller_read_provider_attr(const nexus_controller_t ncd,
185     const uuid_t prov_uuid, nexus_attr_t nxa)
186 {
187 	struct nxprov_reg_ent nre;
188 	uint32_t nre_len = sizeof(nre);
189 	struct nxprov_params *p = &nre.npre_prov_params;
190 	int ret = 0;
191 
192 	if (nxa == NULL) {
193 		return EINVAL;
194 	}
195 
196 	bzero(&nre, sizeof(nre));
197 	bcopy(prov_uuid, nre.npre_prov_uuid, sizeof(uuid_t));
198 	ret = __nexus_get_opt(ncd->ncd_fd, NXOPT_NEXUS_PROV_ENTRY,
199 	    &nre, &nre_len);
200 
201 	if (ret == 0) {
202 		__nexus_attr_from_params(nxa, p);
203 	}
204 
205 	return ret;
206 }
207 
208 void
os_nexus_controller_destroy(nexus_controller_t ncd)209 os_nexus_controller_destroy(nexus_controller_t ncd)
210 {
211 	if (ncd->ncd_fd != -1) {
212 		(void) guarded_close_np(ncd->ncd_fd, &ncd->ncd_guard);
213 	}
214 	free(ncd);
215 }
216 
217 int
__os_nexus_ifattach(const nexus_controller_t ncd,const uuid_t nx_uuid,const char * ifname,const uuid_t netif_uuid,boolean_t host,uuid_t * nx_if_uuid)218 __os_nexus_ifattach(const nexus_controller_t ncd,
219     const uuid_t nx_uuid, const char *ifname, const uuid_t netif_uuid,
220     boolean_t host, uuid_t *nx_if_uuid)
221 {
222 	struct nx_cfg_req ncr;
223 	struct nx_spec_req nsr;
224 	int ret;
225 
226 	bzero(&nsr, sizeof(nsr));
227 	if (ifname != NULL) {
228 		(void) strlcpy(nsr.nsr_name, ifname, sizeof(nsr.nsr_name));
229 	} else {
230 		bcopy(netif_uuid, nsr.nsr_uuid, sizeof(uuid_t));
231 		nsr.nsr_flags |= NXSPECREQ_UUID;
232 	}
233 
234 	if (host) {
235 		nsr.nsr_flags |= NXSPECREQ_HOST;
236 	}
237 
238 	__nexus_config_req_prepare(&ncr, nx_uuid, NXCFG_CMD_ATTACH,
239 	    &nsr, sizeof(nsr));
240 
241 	ret = __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_CONFIG,
242 	    &ncr, sizeof(ncr));
243 
244 	if (ret == 0) {
245 		bcopy(nsr.nsr_if_uuid, nx_if_uuid, sizeof(uuid_t));
246 	}
247 
248 	return ret;
249 }
250 
251 int
__os_nexus_ifdetach(const nexus_controller_t ncd,const uuid_t nx_uuid,const uuid_t nx_if_uuid)252 __os_nexus_ifdetach(const nexus_controller_t ncd, const uuid_t nx_uuid,
253     const uuid_t nx_if_uuid)
254 {
255 	struct nx_cfg_req ncr;
256 	struct nx_spec_req nsr;
257 
258 	bzero(&nsr, sizeof(nsr));
259 	bcopy(nx_if_uuid, nsr.nsr_if_uuid, sizeof(uuid_t));
260 
261 	__nexus_config_req_prepare(&ncr, nx_uuid, NXCFG_CMD_DETACH,
262 	    &nsr, sizeof(nsr));
263 
264 	return __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_CONFIG,
265 	           &ncr, sizeof(ncr));
266 }
267 
268 int
__os_nexus_flow_add(const nexus_controller_t ncd,const uuid_t nx_uuid,const struct nx_flow_req * nfr)269 __os_nexus_flow_add(const nexus_controller_t ncd, const uuid_t nx_uuid,
270     const struct nx_flow_req *nfr)
271 {
272 	struct nx_cfg_req ncr;
273 
274 	__nexus_config_req_prepare(&ncr, nx_uuid, NXCFG_CMD_FLOW_ADD,
275 	    nfr, sizeof(*nfr));
276 
277 	return __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_CONFIG,
278 	           &ncr, sizeof(ncr));
279 }
280 
281 int
__os_nexus_flow_del(const nexus_controller_t ncd,const uuid_t nx_uuid,const struct nx_flow_req * nfr)282 __os_nexus_flow_del(const nexus_controller_t ncd, const uuid_t nx_uuid,
283     const struct nx_flow_req *nfr)
284 {
285 	struct nx_cfg_req ncr;
286 
287 	__nexus_config_req_prepare(&ncr, nx_uuid, NXCFG_CMD_FLOW_DEL,
288 	    nfr, sizeof(*nfr));
289 
290 	return __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_CONFIG,
291 	           &ncr, sizeof(ncr));
292 }
293 
294 int
__os_nexus_get_llink_info(const nexus_controller_t ncd,const uuid_t nx_uuid,const struct nx_llink_info_req * nlir,size_t len)295 __os_nexus_get_llink_info(const nexus_controller_t ncd, const uuid_t nx_uuid,
296     const struct nx_llink_info_req *nlir, size_t len)
297 {
298 	struct nx_cfg_req ncr;
299 
300 	__nexus_config_req_prepare(&ncr, nx_uuid, NXCFG_CMD_GET_LLINK_INFO,
301 	    nlir, len);
302 
303 	return __nexus_set_opt(ncd->ncd_fd, NXOPT_NEXUS_CONFIG,
304 	           &ncr, sizeof(ncr));
305 }
306