xref: /xnu-12377.81.4/tests/skywalk/skt_fswbinds.c (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2017-2024 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  * I discovered a couple of issues with __os_nexus_flow_add, so here's some tests
31  */
32 
33 #include <assert.h>
34 #include <errno.h>
35 #include <stdio.h>
36 #include <spawn.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <uuid/uuid.h>
40 #include <arpa/inet.h>
41 #include <darwintest.h>
42 #include "skywalk_test_driver.h"
43 #include "skywalk_test_utils.h"
44 #include "skywalk_test_common.h"
45 
46 int
skt_fswbind_common(nexus_port_t nx_port1,nexus_port_t nx_port2,bool use_port2)47 skt_fswbind_common(nexus_port_t nx_port1, nexus_port_t nx_port2, bool use_port2)
48 {
49 	struct nx_flow_req nfr;
50 	struct sktc_nexus_handles handles;
51 	uuid_t flow1, flow2;
52 	int error;
53 	char buf[31];
54 	uuid_string_t uuidstr;
55 
56 	sktc_create_flowswitch(&handles, 0);
57 
58 	uuid_generate_random(flow1);
59 
60 	memset(&nfr, 0, sizeof(nfr));
61 	nfr.nfr_ip_protocol = IPPROTO_TCP;
62 	nfr.nfr_nx_port = nx_port1;
63 	nfr.nfr_saddr.sa.sa_len = sizeof(struct sockaddr_in);
64 	nfr.nfr_saddr.sa.sa_family = AF_INET;
65 	nfr.nfr_saddr.sin.sin_port = htons(0);
66 	nfr.nfr_saddr.sin.sin_addr.s_addr = htonl(INADDR_ANY);
67 	uuid_copy(nfr.nfr_flow_uuid, flow1);
68 
69 	uuid_unparse(nfr.nfr_flow_uuid, uuidstr);
70 	inet_ntop(AF_INET, &nfr.nfr_saddr.sin.sin_addr.s_addr, buf, sizeof(buf));
71 	T_LOG("before: nx_port %3d Flow %s %s addr %s port %d\n",
72 	    nfr.nfr_nx_port, uuidstr, (nfr.nfr_ip_protocol == IPPROTO_TCP) ? "tcp" : "udp",
73 	    buf, ntohs(nfr.nfr_saddr.sin.sin_port));
74 
75 	error = __os_nexus_flow_add(handles.controller, handles.fsw_nx_uuid, &nfr);
76 	if (error) {
77 		return error;
78 	}
79 
80 	uuid_unparse(nfr.nfr_flow_uuid, uuidstr);
81 	inet_ntop(AF_INET, &nfr.nfr_saddr.sin.sin_addr.s_addr, buf, sizeof(buf));
82 	T_LOG("after:  nx_port %3d Flow %s %s addr %s port %d\n",
83 	    nfr.nfr_nx_port, uuidstr, (nfr.nfr_ip_protocol == IPPROTO_TCP) ? "tcp" : "udp",
84 	    buf, ntohs(nfr.nfr_saddr.sin.sin_port));
85 
86 	assert(nfr.nfr_nx_port == nx_port1 || nx_port1 == NEXUS_PORT_ANY);
87 	assert(!uuid_compare(nfr.nfr_flow_uuid, flow1));
88 
89 	if (use_port2) {
90 		uuid_generate_random(flow2);
91 
92 		memset(&nfr, 0, sizeof(nfr));
93 		nfr.nfr_ip_protocol = IPPROTO_TCP;
94 		nfr.nfr_nx_port = nx_port2;
95 		nfr.nfr_saddr.sa.sa_len = sizeof(struct sockaddr_in);
96 		nfr.nfr_saddr.sa.sa_family = AF_INET;
97 		nfr.nfr_saddr.sin.sin_port = htons(0);
98 		nfr.nfr_saddr.sin.sin_addr.s_addr = htonl(INADDR_ANY);
99 		uuid_copy(nfr.nfr_flow_uuid, flow2);
100 
101 		uuid_unparse(nfr.nfr_flow_uuid, uuidstr);
102 		inet_ntop(AF_INET, &nfr.nfr_saddr.sin.sin_addr.s_addr, buf, sizeof(buf));
103 		T_LOG("before: nx_port %3d Flow %s %s addr %s port %d\n",
104 		    nfr.nfr_nx_port, uuidstr, (nfr.nfr_ip_protocol == IPPROTO_TCP) ? "tcp" : "udp",
105 		    buf, ntohs(nfr.nfr_saddr.sin.sin_port));
106 
107 		error = __os_nexus_flow_add(handles.controller, handles.fsw_nx_uuid, &nfr);
108 		if (error) {
109 			return error;
110 		}
111 
112 		uuid_unparse(nfr.nfr_flow_uuid, uuidstr);
113 		inet_ntop(AF_INET, &nfr.nfr_saddr.sin.sin_addr.s_addr, buf, sizeof(buf));
114 		T_LOG("after:  nx_port %3d Flow %s %s addr %s port %d\n",
115 		    nfr.nfr_nx_port, uuidstr, (nfr.nfr_ip_protocol == IPPROTO_TCP) ? "tcp" : "udp",
116 		    buf, ntohs(nfr.nfr_saddr.sin.sin_port));
117 
118 		assert(nfr.nfr_nx_port == nx_port2);
119 		assert(!uuid_compare(nfr.nfr_flow_uuid, flow2));
120 	}
121 
122 	memset(&nfr, 0, sizeof(nfr));
123 	uuid_copy(nfr.nfr_flow_uuid, flow1);
124 
125 	error = __os_nexus_flow_del(handles.controller, handles.fsw_nx_uuid, &nfr);
126 	SKTC_ASSERT_ERR(!error);
127 
128 	if (use_port2) {
129 		memset(&nfr, 0, sizeof(nfr));
130 		uuid_copy(nfr.nfr_flow_uuid, flow2);
131 
132 		error = __os_nexus_flow_del(handles.controller, handles.fsw_nx_uuid, &nfr);
133 		SKTC_ASSERT_ERR(!error);
134 	}
135 
136 	sktc_cleanup_flowswitch(&handles);
137 
138 	return 0;
139 }
140 
141 int
skt_fswbindany_main(int argc,char * argv[])142 skt_fswbindany_main(int argc, char *argv[])
143 {
144 	int error = skt_fswbind_common(NEXUS_PORT_ANY, 0, false);
145 	SKTC_ASSERT_ERR(!error); /* Expected to pass */
146 	return 0;
147 }
148 
149 int
skt_fswbind0_main(int argc,char * argv[])150 skt_fswbind0_main(int argc, char *argv[])
151 {
152 	int error = skt_fswbind_common(0, 0, false);
153 	SKTC_ASSERT_ERR(error); /* Expected to fail */
154 	return 0;
155 }
156 
157 int
skt_fswbind1_main(int argc,char * argv[])158 skt_fswbind1_main(int argc, char *argv[])
159 {
160 	int error = skt_fswbind_common(1, 0, false);
161 	SKTC_ASSERT_ERR(error); /* Expected to fail */
162 	return 0;
163 }
164 
165 int
skt_fswbind512_main(int argc,char * argv[])166 skt_fswbind512_main(int argc, char *argv[])
167 {
168 	int error = skt_fswbind_common(512, 0, false);
169 	SKTC_ASSERT_ERR(error); /* Expected to fail */
170 	return 0;
171 }
172 
173 int
skt_fswbind2_main(int argc,char * argv[])174 skt_fswbind2_main(int argc, char *argv[])
175 {
176 	int error = skt_fswbind_common(2, 0, false);
177 	SKTC_ASSERT_ERR(!error);
178 	return 0;
179 }
180 
181 int
skt_fswbind5_main(int argc,char * argv[])182 skt_fswbind5_main(int argc, char *argv[])
183 {
184 	int error = skt_fswbind_common(5, 0, false);
185 	SKTC_ASSERT_ERR(!error);
186 	return 0;
187 }
188 
189 int
skt_fswbind25_main(int argc,char * argv[])190 skt_fswbind25_main(int argc, char *argv[])
191 {
192 	int error = skt_fswbind_common(2, 5, true);
193 	SKTC_ASSERT_ERR(!error);
194 	return 0;
195 }
196 
197 struct skywalk_test skt_fswbindany = {
198 	"fswbindany", "attempts to bind to port -1 of flow switch",
199 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH,
200 	skt_fswbindany_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
201 };
202 
203 struct skywalk_test skt_fswbind0 = {
204 	"fswbind0", "attempts to bind to port 0 of flow switch",
205 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH,
206 	skt_fswbind0_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
207 };
208 
209 struct skywalk_test skt_fswbind1 = {
210 	"fswbind1", "attempts to bind to port 1 of flow switch",
211 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH,
212 	skt_fswbind1_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
213 };
214 
215 struct skywalk_test skt_fswbind512 = {
216 	"fswbind512", "attempts to bind to port 512 of flow switch",
217 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH,
218 	skt_fswbind512_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
219 };
220 
221 struct skywalk_test skt_fswbind2 = {
222 	"fswbind2", "attempts to bind to port 2 of flow switch",
223 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH | SK_FEATURE_NETNS,
224 	skt_fswbind2_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
225 };
226 
227 struct skywalk_test skt_fswbind5 = {
228 	"fswbind5", "attempts to bind to port 5 of flow switch",
229 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH | SK_FEATURE_NETNS,
230 	skt_fswbind5_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
231 };
232 
233 struct skywalk_test skt_fswbind25 = {
234 	"fswbind25", "attempts to bind to port 2 and 5 of flow switch",
235 	SK_FEATURE_SKYWALK | SK_FEATURE_NEXUS_NETIF | SK_FEATURE_NEXUS_FLOWSWITCH | SK_FEATURE_NETNS,
236 	skt_fswbind25_main, { NULL }, sktc_ifnet_feth0_create, sktc_ifnet_feth0_destroy,
237 };
238