1*a1e26a70SApple OSS Distributions /* -*- compile-command: "xcrun --sdk iphoneos.internal make net_tuntests" -*- */
2*a1e26a70SApple OSS Distributions
3*a1e26a70SApple OSS Distributions #include <inttypes.h>
4*a1e26a70SApple OSS Distributions #include <stdbool.h>
5*a1e26a70SApple OSS Distributions #include <stdio.h>
6*a1e26a70SApple OSS Distributions #include <stdlib.h>
7*a1e26a70SApple OSS Distributions #include <time.h>
8*a1e26a70SApple OSS Distributions #include <string.h>
9*a1e26a70SApple OSS Distributions #include <unistd.h>
10*a1e26a70SApple OSS Distributions #include <poll.h>
11*a1e26a70SApple OSS Distributions #include <sys/types.h>
12*a1e26a70SApple OSS Distributions #include <sys/event.h>
13*a1e26a70SApple OSS Distributions #include <sys/time.h>
14*a1e26a70SApple OSS Distributions #include <uuid/uuid.h>
15*a1e26a70SApple OSS Distributions #include <arpa/inet.h>
16*a1e26a70SApple OSS Distributions #include <sys/sysctl.h>
17*a1e26a70SApple OSS Distributions #include <sys/kern_control.h>
18*a1e26a70SApple OSS Distributions #include <sys/ioctl.h>
19*a1e26a70SApple OSS Distributions #include <sys/socket.h>
20*a1e26a70SApple OSS Distributions #include <sys/kern_control.h>
21*a1e26a70SApple OSS Distributions #include <sys/sys_domain.h>
22*a1e26a70SApple OSS Distributions
23*a1e26a70SApple OSS Distributions #include <net/if.h>
24*a1e26a70SApple OSS Distributions #include <net/if_ipsec.h>
25*a1e26a70SApple OSS Distributions #include <net/if_utun.h>
26*a1e26a70SApple OSS Distributions #include <netinet/in.h>
27*a1e26a70SApple OSS Distributions #include <netinet/in_var.h>
28*a1e26a70SApple OSS Distributions #include <net/pfkeyv2.h>
29*a1e26a70SApple OSS Distributions #include <netinet6/ipsec.h>
30*a1e26a70SApple OSS Distributions
31*a1e26a70SApple OSS Distributions #include <darwintest.h>
32*a1e26a70SApple OSS Distributions #include <darwintest_utils.h>
33*a1e26a70SApple OSS Distributions
34*a1e26a70SApple OSS Distributions #include <skywalk/os_skywalk_private.h> // for SK_FEATURE_*
35*a1e26a70SApple OSS Distributions
36*a1e26a70SApple OSS Distributions T_GLOBAL_META(T_META_NAMESPACE("xnu.net.tun"));
37*a1e26a70SApple OSS Distributions
38*a1e26a70SApple OSS Distributions /* Disable all these test until <rdar://problem/49124468> is fixed */
39*a1e26a70SApple OSS Distributions T_GLOBAL_META(T_META_ENABLED(false));
40*a1e26a70SApple OSS Distributions
41*a1e26a70SApple OSS Distributions #if 0
42*a1e26a70SApple OSS Distributions #undef T_QUIET
43*a1e26a70SApple OSS Distributions #define T_QUIET
44*a1e26a70SApple OSS Distributions #endif
45*a1e26a70SApple OSS Distributions
46*a1e26a70SApple OSS Distributions #if 0
47*a1e26a70SApple OSS Distributions static void
48*a1e26a70SApple OSS Distributions log_hexdump(const void *inp, size_t len)
49*a1e26a70SApple OSS Distributions {
50*a1e26a70SApple OSS Distributions unsigned i, off = 0;
51*a1e26a70SApple OSS Distributions char buf[9 + 16 * 3 + 1];
52*a1e26a70SApple OSS Distributions for (i = 0; i < len; i++) {
53*a1e26a70SApple OSS Distributions if (i % 16 == 0) {
54*a1e26a70SApple OSS Distributions off = (unsigned)snprintf(buf, sizeof(buf), "%08x:", i);
55*a1e26a70SApple OSS Distributions }
56*a1e26a70SApple OSS Distributions off += (unsigned)snprintf(buf + off, sizeof(buf) - off, " %02x", (((const uint8_t *)inp)[i]) & 0xff);
57*a1e26a70SApple OSS Distributions if (i % 16 == 15) {
58*a1e26a70SApple OSS Distributions T_LOG("%s", buf);
59*a1e26a70SApple OSS Distributions }
60*a1e26a70SApple OSS Distributions }
61*a1e26a70SApple OSS Distributions if (len % 16) {
62*a1e26a70SApple OSS Distributions T_LOG("%s", buf);
63*a1e26a70SApple OSS Distributions }
64*a1e26a70SApple OSS Distributions }
65*a1e26a70SApple OSS Distributions #else
66*a1e26a70SApple OSS Distributions static void
log_hexdump(const void * inp,size_t len)67*a1e26a70SApple OSS Distributions log_hexdump(const void *inp, size_t len)
68*a1e26a70SApple OSS Distributions {
69*a1e26a70SApple OSS Distributions #pragma unused(inp, len)
70*a1e26a70SApple OSS Distributions }
71*a1e26a70SApple OSS Distributions #endif
72*a1e26a70SApple OSS Distributions
73*a1e26a70SApple OSS Distributions static bool
is_netagent_enabled(void)74*a1e26a70SApple OSS Distributions is_netagent_enabled(void)
75*a1e26a70SApple OSS Distributions {
76*a1e26a70SApple OSS Distributions int enabled = 0;
77*a1e26a70SApple OSS Distributions size_t len = sizeof(enabled);
78*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(sysctlbyname("net.link.generic.system.enable_netagent", &enabled, &len, NULL, 0), NULL);
79*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_EQ(len, sizeof(enabled), NULL);
80*a1e26a70SApple OSS Distributions return enabled == 1;
81*a1e26a70SApple OSS Distributions }
82*a1e26a70SApple OSS Distributions
83*a1e26a70SApple OSS Distributions static bool g_is_ipsec_test;
84*a1e26a70SApple OSS Distributions static bool g_is_utun_test;
85*a1e26a70SApple OSS Distributions static int g_OPT_ENABLE_NETIF = -1;
86*a1e26a70SApple OSS Distributions static int g_OPT_ENABLE_FLOWSWITCH = -1;
87*a1e26a70SApple OSS Distributions static int g_OPT_ENABLE_CHANNEL = -1;
88*a1e26a70SApple OSS Distributions static int g_OPT_GET_CHANNEL_UUID = -1;
89*a1e26a70SApple OSS Distributions static int g_OPT_IFNAME = -1;
90*a1e26a70SApple OSS Distributions static char *g_CONTROL_NAME = NULL;
91*a1e26a70SApple OSS Distributions
92*a1e26a70SApple OSS Distributions static int create_tunsock_old(int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[]);
93*a1e26a70SApple OSS Distributions static int create_tunsock_new(int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[]);
94*a1e26a70SApple OSS Distributions static int (*create_tunsock)(int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[]);
95*a1e26a70SApple OSS Distributions
96*a1e26a70SApple OSS Distributions static void
setup_ipsec_test(void)97*a1e26a70SApple OSS Distributions setup_ipsec_test(void)
98*a1e26a70SApple OSS Distributions {
99*a1e26a70SApple OSS Distributions T_LOG("Configuring for ipsec tests");
100*a1e26a70SApple OSS Distributions g_OPT_ENABLE_NETIF = IPSEC_OPT_ENABLE_NETIF;
101*a1e26a70SApple OSS Distributions g_OPT_ENABLE_FLOWSWITCH = IPSEC_OPT_ENABLE_FLOWSWITCH;
102*a1e26a70SApple OSS Distributions g_OPT_ENABLE_CHANNEL = IPSEC_OPT_ENABLE_CHANNEL;
103*a1e26a70SApple OSS Distributions g_OPT_GET_CHANNEL_UUID = IPSEC_OPT_GET_CHANNEL_UUID;
104*a1e26a70SApple OSS Distributions g_OPT_IFNAME = IPSEC_OPT_IFNAME;
105*a1e26a70SApple OSS Distributions g_CONTROL_NAME = IPSEC_CONTROL_NAME;
106*a1e26a70SApple OSS Distributions create_tunsock = create_tunsock_new;
107*a1e26a70SApple OSS Distributions g_is_ipsec_test = true;
108*a1e26a70SApple OSS Distributions }
109*a1e26a70SApple OSS Distributions
110*a1e26a70SApple OSS Distributions static void
setup_utun_test(void)111*a1e26a70SApple OSS Distributions setup_utun_test(void)
112*a1e26a70SApple OSS Distributions {
113*a1e26a70SApple OSS Distributions T_LOG("Configuring for utun tests");
114*a1e26a70SApple OSS Distributions g_OPT_ENABLE_NETIF = UTUN_OPT_ENABLE_NETIF;
115*a1e26a70SApple OSS Distributions g_OPT_ENABLE_FLOWSWITCH = UTUN_OPT_ENABLE_FLOWSWITCH;
116*a1e26a70SApple OSS Distributions g_OPT_ENABLE_CHANNEL = UTUN_OPT_ENABLE_CHANNEL;
117*a1e26a70SApple OSS Distributions g_OPT_GET_CHANNEL_UUID = UTUN_OPT_GET_CHANNEL_UUID;
118*a1e26a70SApple OSS Distributions g_OPT_IFNAME = UTUN_OPT_IFNAME;
119*a1e26a70SApple OSS Distributions g_CONTROL_NAME = UTUN_CONTROL_NAME;
120*a1e26a70SApple OSS Distributions create_tunsock = create_tunsock_old;
121*a1e26a70SApple OSS Distributions g_is_utun_test = true;
122*a1e26a70SApple OSS Distributions }
123*a1e26a70SApple OSS Distributions
124*a1e26a70SApple OSS Distributions static bool
setblocking(int s,bool blocking)125*a1e26a70SApple OSS Distributions setblocking(int s, bool blocking)
126*a1e26a70SApple OSS Distributions {
127*a1e26a70SApple OSS Distributions int flags;
128*a1e26a70SApple OSS Distributions bool ret;
129*a1e26a70SApple OSS Distributions
130*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(flags = fcntl(s, F_GETFL, 0), NULL);
131*a1e26a70SApple OSS Distributions
132*a1e26a70SApple OSS Distributions ret = !(flags & O_NONBLOCK);
133*a1e26a70SApple OSS Distributions
134*a1e26a70SApple OSS Distributions if (blocking) {
135*a1e26a70SApple OSS Distributions flags &= ~O_NONBLOCK;
136*a1e26a70SApple OSS Distributions } else {
137*a1e26a70SApple OSS Distributions flags |= O_NONBLOCK;
138*a1e26a70SApple OSS Distributions }
139*a1e26a70SApple OSS Distributions
140*a1e26a70SApple OSS Distributions #if 0
141*a1e26a70SApple OSS Distributions T_LOG("Setting fd %d from %s to %s\n",
142*a1e26a70SApple OSS Distributions s, ret ? "blocking" : "nonblocking",
143*a1e26a70SApple OSS Distributions blocking ? "blocking" : "nonblocking");
144*a1e26a70SApple OSS Distributions #endif
145*a1e26a70SApple OSS Distributions
146*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(flags = fcntl(s, F_SETFL, flags), NULL);
147*a1e26a70SApple OSS Distributions
148*a1e26a70SApple OSS Distributions return ret;
149*a1e26a70SApple OSS Distributions }
150*a1e26a70SApple OSS Distributions
151*a1e26a70SApple OSS Distributions
152*a1e26a70SApple OSS Distributions static void
check_enables(int tunsock,int enable_netif,int enable_flowswitch,int channel_count,uuid_t uuid[])153*a1e26a70SApple OSS Distributions check_enables(int tunsock, int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[])
154*a1e26a70SApple OSS Distributions {
155*a1e26a70SApple OSS Distributions int scratch;
156*a1e26a70SApple OSS Distributions socklen_t scratchlen, uuidlen;
157*a1e26a70SApple OSS Distributions uuid_t scratchuuid[channel_count];
158*a1e26a70SApple OSS Distributions if (!uuid) {
159*a1e26a70SApple OSS Distributions uuid = scratchuuid;
160*a1e26a70SApple OSS Distributions }
161*a1e26a70SApple OSS Distributions
162*a1e26a70SApple OSS Distributions //T_LOG("checking tunsock %d", tunsock);
163*a1e26a70SApple OSS Distributions
164*a1e26a70SApple OSS Distributions if (g_is_ipsec_test && channel_count && !enable_netif) {
165*a1e26a70SApple OSS Distributions /* Unfortunately, the connect incorrectly unwinds the bind if it get an error.
166*a1e26a70SApple OSS Distributions * until that is fixed, expect EINVAL here
167*a1e26a70SApple OSS Distributions */
168*a1e26a70SApple OSS Distributions scratchlen = sizeof(scratch);
169*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
170*a1e26a70SApple OSS Distributions &scratch, &scratchlen), EINVAL, NULL);
171*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
172*a1e26a70SApple OSS Distributions &scratch, &scratchlen), EINVAL, NULL);
173*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
174*a1e26a70SApple OSS Distributions &scratch, &scratchlen), EINVAL, NULL);
175*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
176*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
177*a1e26a70SApple OSS Distributions }
178*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
179*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
180*a1e26a70SApple OSS Distributions uuid, &uuidlen), EINVAL, NULL);
181*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
182*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
183*a1e26a70SApple OSS Distributions }
184*a1e26a70SApple OSS Distributions return;
185*a1e26a70SApple OSS Distributions }
186*a1e26a70SApple OSS Distributions
187*a1e26a70SApple OSS Distributions
188*a1e26a70SApple OSS Distributions scratchlen = sizeof(scratch);
189*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
190*a1e26a70SApple OSS Distributions &scratch, &scratchlen), NULL);
191*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)scratchlen, sizeof(scratch), NULL);
192*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(scratch, enable_netif, NULL);
193*a1e26a70SApple OSS Distributions
194*a1e26a70SApple OSS Distributions scratchlen = sizeof(scratch);
195*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
196*a1e26a70SApple OSS Distributions &scratch, &scratchlen), NULL);
197*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)scratchlen, sizeof(scratch), NULL);
198*a1e26a70SApple OSS Distributions if (is_netagent_enabled()) {
199*a1e26a70SApple OSS Distributions if (enable_netif) {
200*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(scratch, enable_flowswitch, NULL);
201*a1e26a70SApple OSS Distributions } else {
202*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
203*a1e26a70SApple OSS Distributions }
204*a1e26a70SApple OSS Distributions } else {
205*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
206*a1e26a70SApple OSS Distributions }
207*a1e26a70SApple OSS Distributions
208*a1e26a70SApple OSS Distributions scratchlen = sizeof(scratch);
209*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
210*a1e26a70SApple OSS Distributions &scratch, &scratchlen), NULL);
211*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)scratchlen, sizeof(scratch), NULL);
212*a1e26a70SApple OSS Distributions if (g_is_ipsec_test && !enable_netif) {
213*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(scratch, 0, NULL);
214*a1e26a70SApple OSS Distributions } else {
215*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(scratch, (int)channel_count, NULL);
216*a1e26a70SApple OSS Distributions }
217*a1e26a70SApple OSS Distributions
218*a1e26a70SApple OSS Distributions if (scratch) {
219*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
220*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
221*a1e26a70SApple OSS Distributions }
222*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
223*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
224*a1e26a70SApple OSS Distributions uuid, &uuidlen), NULL);
225*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
226*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
227*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid[i]), NULL);
228*a1e26a70SApple OSS Distributions }
229*a1e26a70SApple OSS Distributions } else {
230*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
231*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
232*a1e26a70SApple OSS Distributions }
233*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
234*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
235*a1e26a70SApple OSS Distributions uuid, &uuidlen), ENXIO, NULL);
236*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
237*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
238*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
239*a1e26a70SApple OSS Distributions }
240*a1e26a70SApple OSS Distributions }
241*a1e26a70SApple OSS Distributions }
242*a1e26a70SApple OSS Distributions
243*a1e26a70SApple OSS Distributions static void
tunsock_get_ifname(int s,char ifname[IFXNAMSIZ])244*a1e26a70SApple OSS Distributions tunsock_get_ifname(int s, char ifname[IFXNAMSIZ])
245*a1e26a70SApple OSS Distributions {
246*a1e26a70SApple OSS Distributions socklen_t optlen = IFXNAMSIZ;
247*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_ASSERT_POSIX_ZERO(getsockopt(s, SYSPROTO_CONTROL, g_OPT_IFNAME, ifname, &optlen), NULL);
248*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_TRUE(optlen > 0, NULL);
249*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_TRUE(ifname[optlen - 1] == '\0', NULL);
250*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_TRUE(strlen(ifname) + 1 == optlen, "got ifname \"%s\" len %zd expected %u", ifname, strlen(ifname), optlen);
251*a1e26a70SApple OSS Distributions }
252*a1e26a70SApple OSS Distributions
253*a1e26a70SApple OSS Distributions static short
ifnet_get_flags(int s,const char ifname[IFNAMSIZ])254*a1e26a70SApple OSS Distributions ifnet_get_flags(int s, const char ifname[IFNAMSIZ])
255*a1e26a70SApple OSS Distributions {
256*a1e26a70SApple OSS Distributions struct ifreq ifr;
257*a1e26a70SApple OSS Distributions memset(&ifr, 0, sizeof(ifr));
258*a1e26a70SApple OSS Distributions strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
259*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr), NULL);
260*a1e26a70SApple OSS Distributions return ifr.ifr_flags;
261*a1e26a70SApple OSS Distributions }
262*a1e26a70SApple OSS Distributions
263*a1e26a70SApple OSS Distributions static void
ifnet_add_addr4(const char ifname[IFNAMSIZ],struct in_addr * addr,struct in_addr * mask,struct in_addr * broadaddr)264*a1e26a70SApple OSS Distributions ifnet_add_addr4(const char ifname[IFNAMSIZ], struct in_addr *addr, struct in_addr *mask, struct in_addr *broadaddr)
265*a1e26a70SApple OSS Distributions {
266*a1e26a70SApple OSS Distributions struct sockaddr_in *sin;
267*a1e26a70SApple OSS Distributions struct in_aliasreq ifra;
268*a1e26a70SApple OSS Distributions int s;
269*a1e26a70SApple OSS Distributions
270*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(s = socket(AF_INET, SOCK_DGRAM, 0), NULL);
271*a1e26a70SApple OSS Distributions
272*a1e26a70SApple OSS Distributions memset(&ifra, 0, sizeof(ifra));
273*a1e26a70SApple OSS Distributions strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));
274*a1e26a70SApple OSS Distributions
275*a1e26a70SApple OSS Distributions if (addr != NULL) {
276*a1e26a70SApple OSS Distributions sin = &ifra.ifra_addr;
277*a1e26a70SApple OSS Distributions sin->sin_len = sizeof(*sin);
278*a1e26a70SApple OSS Distributions sin->sin_family = AF_INET;
279*a1e26a70SApple OSS Distributions sin->sin_addr = *addr;
280*a1e26a70SApple OSS Distributions }
281*a1e26a70SApple OSS Distributions
282*a1e26a70SApple OSS Distributions if (mask != NULL) {
283*a1e26a70SApple OSS Distributions sin = &ifra.ifra_mask;
284*a1e26a70SApple OSS Distributions sin->sin_len = sizeof(*sin);
285*a1e26a70SApple OSS Distributions sin->sin_family = AF_INET;
286*a1e26a70SApple OSS Distributions sin->sin_addr = *mask;
287*a1e26a70SApple OSS Distributions }
288*a1e26a70SApple OSS Distributions
289*a1e26a70SApple OSS Distributions if (broadaddr != NULL || (addr != NULL &&
290*a1e26a70SApple OSS Distributions (ifnet_get_flags(s, ifname) & IFF_POINTOPOINT) != 0)) {
291*a1e26a70SApple OSS Distributions sin = &ifra.ifra_broadaddr;
292*a1e26a70SApple OSS Distributions sin->sin_len = sizeof(*sin);
293*a1e26a70SApple OSS Distributions sin->sin_family = AF_INET;
294*a1e26a70SApple OSS Distributions sin->sin_addr = (broadaddr != NULL) ? *broadaddr : *addr;
295*a1e26a70SApple OSS Distributions }
296*a1e26a70SApple OSS Distributions
297*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(s, SIOCAIFADDR, &ifra), NULL);
298*a1e26a70SApple OSS Distributions
299*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(s), NULL);
300*a1e26a70SApple OSS Distributions }
301*a1e26a70SApple OSS Distributions
302*a1e26a70SApple OSS Distributions static int g_pfkeyso = -1;
303*a1e26a70SApple OSS Distributions static struct in_addr g_addr1, g_addr2;
304*a1e26a70SApple OSS Distributions
305*a1e26a70SApple OSS Distributions static void
create_sa(const char ifname[IFXNAMSIZ],uint8_t type,uint32_t spi,struct in_addr * src,struct in_addr * dst)306*a1e26a70SApple OSS Distributions create_sa(const char ifname[IFXNAMSIZ], uint8_t type, uint32_t spi, struct in_addr *src, struct in_addr *dst)
307*a1e26a70SApple OSS Distributions {
308*a1e26a70SApple OSS Distributions if (g_pfkeyso == -1) {
309*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(g_pfkeyso = socket(PF_KEY, SOCK_RAW, PF_KEY_V2), NULL);
310*a1e26a70SApple OSS Distributions }
311*a1e26a70SApple OSS Distributions
312*a1e26a70SApple OSS Distributions /*
313*a1e26a70SApple OSS Distributions * <base, SA, (lifetime(HS),) address(SD), (address(P),)
314*a1e26a70SApple OSS Distributions * key(AE), (identity(SD),) (sensitivity)>
315*a1e26a70SApple OSS Distributions */
316*a1e26a70SApple OSS Distributions
317*a1e26a70SApple OSS Distributions struct {
318*a1e26a70SApple OSS Distributions struct sadb_msg msg __attribute((aligned(sizeof(uint64_t))));
319*a1e26a70SApple OSS Distributions struct sadb_key key __attribute((aligned(sizeof(uint64_t))));
320*a1e26a70SApple OSS Distributions struct sadb_sa sa __attribute((aligned(sizeof(uint64_t))));
321*a1e26a70SApple OSS Distributions struct sadb_x_sa2 sa2 __attribute((aligned(sizeof(uint64_t))));
322*a1e26a70SApple OSS Distributions struct sadb_x_ipsecif ipsecif __attribute((aligned(sizeof(uint64_t))));
323*a1e26a70SApple OSS Distributions struct {
324*a1e26a70SApple OSS Distributions struct sadb_address addr __attribute((aligned(sizeof(uint64_t))));
325*a1e26a70SApple OSS Distributions struct sockaddr_in saddr __attribute((aligned(sizeof(uint64_t))));
326*a1e26a70SApple OSS Distributions } src;
327*a1e26a70SApple OSS Distributions struct {
328*a1e26a70SApple OSS Distributions struct sadb_address addr __attribute((aligned(sizeof(uint64_t))));
329*a1e26a70SApple OSS Distributions struct sockaddr_in saddr __attribute((aligned(sizeof(uint64_t))));
330*a1e26a70SApple OSS Distributions } dst;
331*a1e26a70SApple OSS Distributions } addcmd;
332*a1e26a70SApple OSS Distributions
333*a1e26a70SApple OSS Distributions memset(&addcmd, 0, sizeof(addcmd));
334*a1e26a70SApple OSS Distributions
335*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_version = PF_KEY_V2;
336*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_type = type;
337*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_errno = 0;
338*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_satype = SADB_SATYPE_ESP;
339*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_len = PFKEY_UNIT64(sizeof(addcmd));
340*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_reserved = 0;
341*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_seq = 0;
342*a1e26a70SApple OSS Distributions addcmd.msg.sadb_msg_pid = (unsigned)getpid();
343*a1e26a70SApple OSS Distributions
344*a1e26a70SApple OSS Distributions addcmd.key.sadb_key_len = PFKEY_UNIT64(sizeof(addcmd.key));
345*a1e26a70SApple OSS Distributions addcmd.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
346*a1e26a70SApple OSS Distributions addcmd.key.sadb_key_bits = 0;
347*a1e26a70SApple OSS Distributions addcmd.key.sadb_key_reserved = 0;
348*a1e26a70SApple OSS Distributions
349*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_len = PFKEY_UNIT64(sizeof(addcmd.sa));
350*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_exttype = SADB_EXT_SA;
351*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_spi = htonl(spi);
352*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_replay = 0;
353*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_state = 0;
354*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_auth = SADB_AALG_NONE;
355*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_encrypt = SADB_EALG_NULL;
356*a1e26a70SApple OSS Distributions addcmd.sa.sadb_sa_flags = SADB_X_EXT_CYCSEQ;
357*a1e26a70SApple OSS Distributions
358*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_len = PFKEY_UNIT64(sizeof(addcmd.sa2));
359*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
360*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_mode = IPSEC_MODE_ANY;
361*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_alwaysexpire = 1;
362*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_flags = SADB_X_EXT_SA2_DELETE_ON_DETACH;
363*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_sequence = 0;
364*a1e26a70SApple OSS Distributions addcmd.sa2.sadb_x_sa2_reqid = 0;
365*a1e26a70SApple OSS Distributions
366*a1e26a70SApple OSS Distributions addcmd.ipsecif.sadb_x_ipsecif_len = PFKEY_UNIT64(sizeof(addcmd.ipsecif));
367*a1e26a70SApple OSS Distributions addcmd.ipsecif.sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF;
368*a1e26a70SApple OSS Distributions memset(addcmd.ipsecif.sadb_x_ipsecif_internal_if, 0, sizeof(addcmd.ipsecif.sadb_x_ipsecif_internal_if));
369*a1e26a70SApple OSS Distributions memset(addcmd.ipsecif.sadb_x_ipsecif_outgoing_if, 0, sizeof(addcmd.ipsecif.sadb_x_ipsecif_outgoing_if));
370*a1e26a70SApple OSS Distributions strlcpy(addcmd.ipsecif.sadb_x_ipsecif_ipsec_if, ifname, sizeof(addcmd.ipsecif.sadb_x_ipsecif_ipsec_if));
371*a1e26a70SApple OSS Distributions addcmd.ipsecif.sadb_x_ipsecif_init_disabled = 0;
372*a1e26a70SApple OSS Distributions addcmd.ipsecif.reserved = 0;
373*a1e26a70SApple OSS Distributions
374*a1e26a70SApple OSS Distributions addcmd.src.addr.sadb_address_len = PFKEY_UNIT64(sizeof(addcmd.src));
375*a1e26a70SApple OSS Distributions addcmd.src.addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
376*a1e26a70SApple OSS Distributions addcmd.src.addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
377*a1e26a70SApple OSS Distributions addcmd.src.addr.sadb_address_prefixlen = sizeof(struct in_addr) << 3; //XXX Why?
378*a1e26a70SApple OSS Distributions addcmd.src.addr.sadb_address_reserved = 0;
379*a1e26a70SApple OSS Distributions addcmd.src.saddr.sin_len = sizeof(addcmd.src.saddr);
380*a1e26a70SApple OSS Distributions addcmd.src.saddr.sin_family = AF_INET;
381*a1e26a70SApple OSS Distributions addcmd.src.saddr.sin_port = htons(0);
382*a1e26a70SApple OSS Distributions addcmd.src.saddr.sin_addr = *src;
383*a1e26a70SApple OSS Distributions
384*a1e26a70SApple OSS Distributions addcmd.dst.addr.sadb_address_len = PFKEY_UNIT64(sizeof(addcmd.dst));
385*a1e26a70SApple OSS Distributions addcmd.dst.addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
386*a1e26a70SApple OSS Distributions addcmd.dst.addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
387*a1e26a70SApple OSS Distributions addcmd.dst.addr.sadb_address_prefixlen = sizeof(struct in_addr) << 3; //XXX Why?
388*a1e26a70SApple OSS Distributions addcmd.dst.addr.sadb_address_reserved = 0;
389*a1e26a70SApple OSS Distributions addcmd.dst.saddr.sin_len = sizeof(addcmd.dst.saddr);
390*a1e26a70SApple OSS Distributions addcmd.dst.saddr.sin_family = AF_INET;
391*a1e26a70SApple OSS Distributions addcmd.dst.saddr.sin_port = htons(0);
392*a1e26a70SApple OSS Distributions addcmd.dst.saddr.sin_addr = *dst;
393*a1e26a70SApple OSS Distributions
394*a1e26a70SApple OSS Distributions log_hexdump(&addcmd, sizeof(addcmd));
395*a1e26a70SApple OSS Distributions
396*a1e26a70SApple OSS Distributions ssize_t slen;
397*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(slen = send(g_pfkeyso, &addcmd, sizeof(addcmd), 0), NULL);
398*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ(slen, (ssize_t)sizeof(addcmd), NULL);
399*a1e26a70SApple OSS Distributions }
400*a1e26a70SApple OSS Distributions
401*a1e26a70SApple OSS Distributions /* This version of the test expects channels to be enabled after connect.
402*a1e26a70SApple OSS Distributions * Once the utun driver is converted, switch to create_tunsock_new
403*a1e26a70SApple OSS Distributions */
404*a1e26a70SApple OSS Distributions static int
create_tunsock_old(int enable_netif,int enable_flowswitch,int channel_count,uuid_t uuid[])405*a1e26a70SApple OSS Distributions create_tunsock_old(int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[])
406*a1e26a70SApple OSS Distributions {
407*a1e26a70SApple OSS Distributions int tunsock;
408*a1e26a70SApple OSS Distributions struct ctl_info kernctl_info;
409*a1e26a70SApple OSS Distributions struct sockaddr_ctl kernctl_addr;
410*a1e26a70SApple OSS Distributions uuid_t scratchuuid[channel_count];
411*a1e26a70SApple OSS Distributions if (!uuid) {
412*a1e26a70SApple OSS Distributions uuid = scratchuuid;
413*a1e26a70SApple OSS Distributions }
414*a1e26a70SApple OSS Distributions socklen_t uuidlen;
415*a1e26a70SApple OSS Distributions
416*a1e26a70SApple OSS Distributions startover:
417*a1e26a70SApple OSS Distributions
418*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(tunsock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), NULL);
419*a1e26a70SApple OSS Distributions
420*a1e26a70SApple OSS Distributions memset(&kernctl_info, 0, sizeof(kernctl_info));
421*a1e26a70SApple OSS Distributions strlcpy(kernctl_info.ctl_name, g_CONTROL_NAME, sizeof(kernctl_info.ctl_name));
422*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(tunsock, CTLIOCGINFO, &kernctl_info), NULL);
423*a1e26a70SApple OSS Distributions
424*a1e26a70SApple OSS Distributions memset(&kernctl_addr, 0, sizeof(kernctl_addr));
425*a1e26a70SApple OSS Distributions kernctl_addr.sc_len = sizeof(kernctl_addr);
426*a1e26a70SApple OSS Distributions kernctl_addr.sc_family = AF_SYSTEM;
427*a1e26a70SApple OSS Distributions kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
428*a1e26a70SApple OSS Distributions kernctl_addr.sc_id = kernctl_info.ctl_id;
429*a1e26a70SApple OSS Distributions kernctl_addr.sc_unit = 0;
430*a1e26a70SApple OSS Distributions
431*a1e26a70SApple OSS Distributions T_LOG("%s: enable_netif = %d, enable_flowswitch = %d, channel_count = %d",
432*a1e26a70SApple OSS Distributions __func__, enable_netif, enable_flowswitch, channel_count);
433*a1e26a70SApple OSS Distributions
434*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
435*a1e26a70SApple OSS Distributions &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
436*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
437*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
438*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
439*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), EINVAL, NULL);
440*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
441*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
442*a1e26a70SApple OSS Distributions }
443*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
444*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
445*a1e26a70SApple OSS Distributions uuid, &uuidlen), EINVAL, NULL);
446*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
447*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
448*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
449*a1e26a70SApple OSS Distributions }
450*a1e26a70SApple OSS Distributions
451*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(bind(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
452*a1e26a70SApple OSS Distributions
453*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
454*a1e26a70SApple OSS Distributions &enable_netif, sizeof(enable_netif)), NULL);
455*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
456*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
457*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
458*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), EINVAL, NULL);
459*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
460*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
461*a1e26a70SApple OSS Distributions }
462*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
463*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
464*a1e26a70SApple OSS Distributions uuid, &uuidlen), ENXIO, NULL);
465*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
466*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
467*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
468*a1e26a70SApple OSS Distributions }
469*a1e26a70SApple OSS Distributions
470*a1e26a70SApple OSS Distributions int error = connect(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr));
471*a1e26a70SApple OSS Distributions if (error == -1 && errno == EBUSY) {
472*a1e26a70SApple OSS Distributions /* XXX remove this retry nonsense when this is fixed:
473*a1e26a70SApple OSS Distributions * <rdar://problem/37340313> creating an interface without specifying specific interface name should not return EBUSY
474*a1e26a70SApple OSS Distributions */
475*a1e26a70SApple OSS Distributions close(tunsock);
476*a1e26a70SApple OSS Distributions T_LOG("connect got EBUSY, sleeping 1 second before retry");
477*a1e26a70SApple OSS Distributions sleep(1);
478*a1e26a70SApple OSS Distributions goto startover;
479*a1e26a70SApple OSS Distributions }
480*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(error, "connect()");
481*a1e26a70SApple OSS Distributions
482*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
483*a1e26a70SApple OSS Distributions &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
484*a1e26a70SApple OSS Distributions
485*a1e26a70SApple OSS Distributions if (is_netagent_enabled()) {
486*a1e26a70SApple OSS Distributions if (enable_netif) {
487*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
488*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), NULL);
489*a1e26a70SApple OSS Distributions } else {
490*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
491*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), ENOENT, NULL);
492*a1e26a70SApple OSS Distributions }
493*a1e26a70SApple OSS Distributions } else {
494*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
495*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), ENOTSUP, NULL);
496*a1e26a70SApple OSS Distributions }
497*a1e26a70SApple OSS Distributions
498*a1e26a70SApple OSS Distributions if (channel_count) {
499*a1e26a70SApple OSS Distributions if (g_is_ipsec_test && !enable_netif) {
500*a1e26a70SApple OSS Distributions /* ipsec doesn't support channels without a netif */
501*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
502*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), EOPNOTSUPP, NULL);
503*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
504*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
505*a1e26a70SApple OSS Distributions }
506*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
507*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
508*a1e26a70SApple OSS Distributions uuid, &uuidlen), ENXIO, NULL);
509*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
510*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
511*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
512*a1e26a70SApple OSS Distributions }
513*a1e26a70SApple OSS Distributions } else {
514*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
515*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), NULL);
516*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
517*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
518*a1e26a70SApple OSS Distributions }
519*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
520*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
521*a1e26a70SApple OSS Distributions uuid, &uuidlen), NULL);
522*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
523*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
524*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid[i]), NULL);
525*a1e26a70SApple OSS Distributions }
526*a1e26a70SApple OSS Distributions }
527*a1e26a70SApple OSS Distributions } else {
528*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
529*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), ENXIO, NULL);
530*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
531*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
532*a1e26a70SApple OSS Distributions }
533*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
534*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
535*a1e26a70SApple OSS Distributions uuid, &uuidlen), ENXIO, NULL);
536*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
537*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
538*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
539*a1e26a70SApple OSS Distributions }
540*a1e26a70SApple OSS Distributions }
541*a1e26a70SApple OSS Distributions
542*a1e26a70SApple OSS Distributions check_enables(tunsock, enable_netif, enable_flowswitch, channel_count, uuid);
543*a1e26a70SApple OSS Distributions
544*a1e26a70SApple OSS Distributions //T_LOG("Returning tunsock %d", tunsock);
545*a1e26a70SApple OSS Distributions
546*a1e26a70SApple OSS Distributions return tunsock;
547*a1e26a70SApple OSS Distributions }
548*a1e26a70SApple OSS Distributions
549*a1e26a70SApple OSS Distributions /* This version of the test expects channels to be enabled before connect
550*a1e26a70SApple OSS Distributions * Once the utun driver is converted, rename this to just create_tunsock
551*a1e26a70SApple OSS Distributions */
552*a1e26a70SApple OSS Distributions static int
create_tunsock_new(int enable_netif,int enable_flowswitch,int channel_count,uuid_t uuid[])553*a1e26a70SApple OSS Distributions create_tunsock_new(int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[])
554*a1e26a70SApple OSS Distributions {
555*a1e26a70SApple OSS Distributions int tunsock;
556*a1e26a70SApple OSS Distributions struct ctl_info kernctl_info;
557*a1e26a70SApple OSS Distributions struct sockaddr_ctl kernctl_addr;
558*a1e26a70SApple OSS Distributions uuid_t scratchuuid[channel_count];
559*a1e26a70SApple OSS Distributions if (!uuid) {
560*a1e26a70SApple OSS Distributions uuid = scratchuuid;
561*a1e26a70SApple OSS Distributions }
562*a1e26a70SApple OSS Distributions socklen_t uuidlen;
563*a1e26a70SApple OSS Distributions
564*a1e26a70SApple OSS Distributions startover:
565*a1e26a70SApple OSS Distributions
566*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(tunsock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL), NULL);
567*a1e26a70SApple OSS Distributions
568*a1e26a70SApple OSS Distributions memset(&kernctl_info, 0, sizeof(kernctl_info));
569*a1e26a70SApple OSS Distributions strlcpy(kernctl_info.ctl_name, g_CONTROL_NAME, sizeof(kernctl_info.ctl_name));
570*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(ioctl(tunsock, CTLIOCGINFO, &kernctl_info), NULL);
571*a1e26a70SApple OSS Distributions
572*a1e26a70SApple OSS Distributions memset(&kernctl_addr, 0, sizeof(kernctl_addr));
573*a1e26a70SApple OSS Distributions kernctl_addr.sc_len = sizeof(kernctl_addr);
574*a1e26a70SApple OSS Distributions kernctl_addr.sc_family = AF_SYSTEM;
575*a1e26a70SApple OSS Distributions kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
576*a1e26a70SApple OSS Distributions kernctl_addr.sc_id = kernctl_info.ctl_id;
577*a1e26a70SApple OSS Distributions kernctl_addr.sc_unit = 0;
578*a1e26a70SApple OSS Distributions
579*a1e26a70SApple OSS Distributions T_LOG("%s: enable_netif = %d, enable_flowswitch = %d, channel_count = %d",
580*a1e26a70SApple OSS Distributions __func__, enable_netif, enable_flowswitch, channel_count);
581*a1e26a70SApple OSS Distributions
582*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
583*a1e26a70SApple OSS Distributions &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
584*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
585*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
586*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
587*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), EINVAL, NULL);
588*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
589*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
590*a1e26a70SApple OSS Distributions }
591*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
592*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
593*a1e26a70SApple OSS Distributions uuid, &uuidlen), EINVAL, NULL);
594*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
595*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
596*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
597*a1e26a70SApple OSS Distributions }
598*a1e26a70SApple OSS Distributions
599*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(bind(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr)), NULL);
600*a1e26a70SApple OSS Distributions
601*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
602*a1e26a70SApple OSS Distributions &enable_netif, sizeof(enable_netif)), NULL);
603*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
604*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
605*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
606*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), NULL);
607*a1e26a70SApple OSS Distributions
608*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
609*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
610*a1e26a70SApple OSS Distributions }
611*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
612*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
613*a1e26a70SApple OSS Distributions uuid, &uuidlen), ENXIO, NULL);
614*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
615*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
616*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
617*a1e26a70SApple OSS Distributions }
618*a1e26a70SApple OSS Distributions
619*a1e26a70SApple OSS Distributions int error = connect(tunsock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr));
620*a1e26a70SApple OSS Distributions if (error == -1 && errno == EBUSY) {
621*a1e26a70SApple OSS Distributions /* XXX remove this retry nonsense when this is fixed:
622*a1e26a70SApple OSS Distributions * <rdar://problem/37340313> creating an interface without specifying specific interface name should not return EBUSY
623*a1e26a70SApple OSS Distributions */
624*a1e26a70SApple OSS Distributions close(tunsock);
625*a1e26a70SApple OSS Distributions T_LOG("connect got EBUSY, sleeping 1 second before retry");
626*a1e26a70SApple OSS Distributions sleep(1);
627*a1e26a70SApple OSS Distributions goto startover;
628*a1e26a70SApple OSS Distributions }
629*a1e26a70SApple OSS Distributions if (g_is_ipsec_test && channel_count && !enable_netif) {
630*a1e26a70SApple OSS Distributions /* ipsec doesn't support channels without a netif */
631*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(error, ENOTSUP, "connect() == -1 && errno == ENOTSUP");
632*a1e26a70SApple OSS Distributions } else {
633*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(error, "connect() == 0");
634*a1e26a70SApple OSS Distributions }
635*a1e26a70SApple OSS Distributions
636*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_NETIF,
637*a1e26a70SApple OSS Distributions &enable_netif, sizeof(enable_netif)), EINVAL, NULL);
638*a1e26a70SApple OSS Distributions
639*a1e26a70SApple OSS Distributions if (g_is_ipsec_test && channel_count && !enable_netif) {
640*a1e26a70SApple OSS Distributions /* Connect failed above, so we get EINVAL */
641*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
642*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), EINVAL, NULL);
643*a1e26a70SApple OSS Distributions } else {
644*a1e26a70SApple OSS Distributions if (is_netagent_enabled()) {
645*a1e26a70SApple OSS Distributions if (enable_netif) {
646*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
647*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), NULL);
648*a1e26a70SApple OSS Distributions } else {
649*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
650*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), ENOENT, NULL);
651*a1e26a70SApple OSS Distributions }
652*a1e26a70SApple OSS Distributions } else {
653*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_FLOWSWITCH,
654*a1e26a70SApple OSS Distributions &enable_flowswitch, sizeof(enable_flowswitch)), ENOTSUP, NULL);
655*a1e26a70SApple OSS Distributions }
656*a1e26a70SApple OSS Distributions }
657*a1e26a70SApple OSS Distributions
658*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(setsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_ENABLE_CHANNEL,
659*a1e26a70SApple OSS Distributions &channel_count, sizeof(channel_count)), EINVAL, NULL);
660*a1e26a70SApple OSS Distributions
661*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
662*a1e26a70SApple OSS Distributions uuid_clear(uuid[i]);
663*a1e26a70SApple OSS Distributions }
664*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
665*a1e26a70SApple OSS Distributions if (!channel_count || (g_is_ipsec_test && channel_count && !enable_netif)) {
666*a1e26a70SApple OSS Distributions /* ipsec doesn't support channels without a netif */
667*a1e26a70SApple OSS Distributions if (g_is_ipsec_test && channel_count && !enable_netif) {
668*a1e26a70SApple OSS Distributions /* Unfortunately, the connect incorrectly unwinds the bind if it get an error.
669*a1e26a70SApple OSS Distributions * until that is fixed, expect EINVAL here
670*a1e26a70SApple OSS Distributions */
671*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
672*a1e26a70SApple OSS Distributions uuid, &uuidlen), EINVAL, NULL);
673*a1e26a70SApple OSS Distributions } else {
674*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
675*a1e26a70SApple OSS Distributions uuid, &uuidlen), ENXIO, NULL);
676*a1e26a70SApple OSS Distributions }
677*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
678*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
679*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(uuid_is_null(uuid[i]), NULL);
680*a1e26a70SApple OSS Distributions }
681*a1e26a70SApple OSS Distributions } else {
682*a1e26a70SApple OSS Distributions uuidlen = sizeof(uuid_t) * (unsigned int)channel_count;
683*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(getsockopt(tunsock, SYSPROTO_CONTROL, g_OPT_GET_CHANNEL_UUID,
684*a1e26a70SApple OSS Distributions uuid, &uuidlen), NULL);
685*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG((unsigned long)uuidlen, sizeof(uuid_t) * (unsigned long)channel_count, NULL);
686*a1e26a70SApple OSS Distributions for (int i = 0; i < channel_count; i++) {
687*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(uuid_is_null(uuid[i]), NULL);
688*a1e26a70SApple OSS Distributions }
689*a1e26a70SApple OSS Distributions }
690*a1e26a70SApple OSS Distributions
691*a1e26a70SApple OSS Distributions check_enables(tunsock, enable_netif, enable_flowswitch, channel_count, uuid);
692*a1e26a70SApple OSS Distributions
693*a1e26a70SApple OSS Distributions //T_LOG("Returning tunsock %d", tunsock);
694*a1e26a70SApple OSS Distributions
695*a1e26a70SApple OSS Distributions return tunsock;
696*a1e26a70SApple OSS Distributions }
697*a1e26a70SApple OSS Distributions
698*a1e26a70SApple OSS Distributions static int (*create_tunsock)(int enable_netif, int enable_flowswitch, int channel_count, uuid_t uuid[]) = create_tunsock_new;
699*a1e26a70SApple OSS Distributions
700*a1e26a70SApple OSS Distributions #if 0
701*a1e26a70SApple OSS Distributions static void
702*a1e26a70SApple OSS Distributions ipsec_stats(void)
703*a1e26a70SApple OSS Distributions {
704*a1e26a70SApple OSS Distributions struct ifmibdata ifmd;
705*a1e26a70SApple OSS Distributions
706*a1e26a70SApple OSS Distributions len = sizeof(struct ifmibdata);
707*a1e26a70SApple OSS Distributions name[3] = IFMIB_IFDATA;
708*a1e26a70SApple OSS Distributions name[4] = interesting_row;
709*a1e26a70SApple OSS Distributions name[5] = IpFDATA_GENERAL;
710*a1e26a70SApple OSS Distributions if (sysctl(name, 6, &ifmd, &len, (void *)0, 0) == -1) {
711*a1e26a70SApple OSS Distributions err(1, "sysctl IFDATA_GENERAL %d", interesting_row);
712*a1e26a70SApple OSS Distributions }
713*a1e26a70SApple OSS Distributions }
714*a1e26a70SApple OSS Distributions #endif
715*a1e26a70SApple OSS Distributions
716*a1e26a70SApple OSS Distributions static void
permute_enables(void)717*a1e26a70SApple OSS Distributions permute_enables(void)
718*a1e26a70SApple OSS Distributions {
719*a1e26a70SApple OSS Distributions int tunsock;
720*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(false, false, false, NULL), 0, NULL);
721*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
722*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(false, false, true, NULL), 0, NULL);
723*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
724*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(false, true, false, NULL), 0, NULL);
725*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
726*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(false, true, true, NULL), 0, NULL);
727*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
728*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(true, false, false, NULL), 0, NULL);
729*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
730*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(true, false, true, NULL), 0, NULL);
731*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
732*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(true, true, false, NULL), 0, NULL);
733*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
734*a1e26a70SApple OSS Distributions T_EXPECT_GE(tunsock = create_tunsock(true, true, true, NULL), 0, NULL);
735*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(tunsock), NULL);
736*a1e26a70SApple OSS Distributions }
737*a1e26a70SApple OSS Distributions
738*a1e26a70SApple OSS Distributions T_DECL(ipsec_enables, "This test checks combinations of netif/channel/flowswitch on ipsec", T_META_TAG_VM_PREFERRED)
739*a1e26a70SApple OSS Distributions {
740*a1e26a70SApple OSS Distributions setup_ipsec_test();
741*a1e26a70SApple OSS Distributions permute_enables();
742*a1e26a70SApple OSS Distributions }
743*a1e26a70SApple OSS Distributions
744*a1e26a70SApple OSS Distributions T_DECL(utun_enables, "This test checks combinations of netif/channel/flowswitch on utun", T_META_TAG_VM_PREFERRED)
745*a1e26a70SApple OSS Distributions {
746*a1e26a70SApple OSS Distributions setup_utun_test();
747*a1e26a70SApple OSS Distributions permute_enables();
748*a1e26a70SApple OSS Distributions }
749*a1e26a70SApple OSS Distributions
750*a1e26a70SApple OSS Distributions static int g_tunsock = -1;
751*a1e26a70SApple OSS Distributions
752*a1e26a70SApple OSS Distributions static void
cleanup_tunsock(void)753*a1e26a70SApple OSS Distributions cleanup_tunsock(void)
754*a1e26a70SApple OSS Distributions {
755*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(g_tunsock), NULL);
756*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(close(g_tunsock), EBADF, NULL);
757*a1e26a70SApple OSS Distributions if (g_is_ipsec_test) {
758*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(g_pfkeyso), NULL);
759*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(close(g_pfkeyso), EBADF, NULL);
760*a1e26a70SApple OSS Distributions }
761*a1e26a70SApple OSS Distributions }
762*a1e26a70SApple OSS Distributions
763*a1e26a70SApple OSS Distributions static void
setup_tunsock(int channel_count,uuid_t uuids[])764*a1e26a70SApple OSS Distributions setup_tunsock(int channel_count, uuid_t uuids[])
765*a1e26a70SApple OSS Distributions {
766*a1e26a70SApple OSS Distributions T_ASSERT_GE(g_tunsock = create_tunsock(true, false, channel_count, uuids), 0, NULL);
767*a1e26a70SApple OSS Distributions T_ATEND(cleanup_tunsock);
768*a1e26a70SApple OSS Distributions
769*a1e26a70SApple OSS Distributions char ifname[IFXNAMSIZ];
770*a1e26a70SApple OSS Distributions tunsock_get_ifname(g_tunsock, ifname);
771*a1e26a70SApple OSS Distributions
772*a1e26a70SApple OSS Distributions T_LOG("Created interface %s", ifname);
773*a1e26a70SApple OSS Distributions
774*a1e26a70SApple OSS Distributions uint32_t ifaddr = (10 << 24) | ((unsigned)getpid() & 0xffff) << 8 | 160;
775*a1e26a70SApple OSS Distributions struct in_addr mask;
776*a1e26a70SApple OSS Distributions g_addr1.s_addr = htonl(ifaddr);
777*a1e26a70SApple OSS Distributions g_addr2.s_addr = htonl(ifaddr + 1);
778*a1e26a70SApple OSS Distributions mask.s_addr = htonl(0xffffffff);
779*a1e26a70SApple OSS Distributions
780*a1e26a70SApple OSS Distributions ifnet_add_addr4(ifname, &g_addr1, &mask, &g_addr2);
781*a1e26a70SApple OSS Distributions
782*a1e26a70SApple OSS Distributions if (g_is_ipsec_test) {
783*a1e26a70SApple OSS Distributions create_sa(ifname, SADB_ADD, 12345, &g_addr1, &g_addr2);
784*a1e26a70SApple OSS Distributions create_sa(ifname, SADB_ADD, 12346, &g_addr2, &g_addr1);
785*a1e26a70SApple OSS Distributions }
786*a1e26a70SApple OSS Distributions }
787*a1e26a70SApple OSS Distributions
788*a1e26a70SApple OSS Distributions T_DECL(setup_ipsec, "This test sets up an ipsec interface", T_META_TAG_VM_PREFERRED)
789*a1e26a70SApple OSS Distributions {
790*a1e26a70SApple OSS Distributions setup_ipsec_test();
791*a1e26a70SApple OSS Distributions setup_tunsock(1, NULL);
792*a1e26a70SApple OSS Distributions }
793*a1e26a70SApple OSS Distributions
794*a1e26a70SApple OSS Distributions T_DECL(setup_utun, "This test sets up a utun interface", T_META_TAG_VM_PREFERRED)
795*a1e26a70SApple OSS Distributions {
796*a1e26a70SApple OSS Distributions setup_utun_test();
797*a1e26a70SApple OSS Distributions setup_tunsock(1, NULL);
798*a1e26a70SApple OSS Distributions }
799*a1e26a70SApple OSS Distributions
800*a1e26a70SApple OSS Distributions static const int SOCKET_TRAFFIC_CLASSES[] = {
801*a1e26a70SApple OSS Distributions SO_TC_BK_SYS, // BK
802*a1e26a70SApple OSS Distributions SO_TC_BK, // BK
803*a1e26a70SApple OSS Distributions SO_TC_BE, // BE
804*a1e26a70SApple OSS Distributions SO_TC_RD, // BE
805*a1e26a70SApple OSS Distributions SO_TC_OAM, // BE
806*a1e26a70SApple OSS Distributions SO_TC_AV, // VI
807*a1e26a70SApple OSS Distributions SO_TC_RV, // VI
808*a1e26a70SApple OSS Distributions SO_TC_VI, // VI
809*a1e26a70SApple OSS Distributions SO_TC_VO, // VO
810*a1e26a70SApple OSS Distributions SO_TC_CTL, // VO
811*a1e26a70SApple OSS Distributions };
812*a1e26a70SApple OSS Distributions
813*a1e26a70SApple OSS Distributions // this should match ipsec_find_tx_ring_by_svc in ipsec driver
814*a1e26a70SApple OSS Distributions static const int SOCKET_TC_TO_RING[] = {
815*a1e26a70SApple OSS Distributions 3,
816*a1e26a70SApple OSS Distributions 3,
817*a1e26a70SApple OSS Distributions 2,
818*a1e26a70SApple OSS Distributions 2,
819*a1e26a70SApple OSS Distributions 2,
820*a1e26a70SApple OSS Distributions 1,
821*a1e26a70SApple OSS Distributions 1,
822*a1e26a70SApple OSS Distributions 1,
823*a1e26a70SApple OSS Distributions 0,
824*a1e26a70SApple OSS Distributions 0,
825*a1e26a70SApple OSS Distributions };
826*a1e26a70SApple OSS Distributions
827*a1e26a70SApple OSS Distributions /* How many sockets map to this ring */
828*a1e26a70SApple OSS Distributions static const int RING_TO_TC_COUNT[] = {
829*a1e26a70SApple OSS Distributions 2, 3, 3, 2,
830*a1e26a70SApple OSS Distributions };
831*a1e26a70SApple OSS Distributions
832*a1e26a70SApple OSS Distributions static void
setup_channels_and_rings(int kq,int channel_count,channel_t channels[],channel_ring_t rxrings[],channel_ring_t txrings[],uuid_t uuids[],int cfds[])833*a1e26a70SApple OSS Distributions setup_channels_and_rings(int kq, int channel_count, channel_t channels[], channel_ring_t rxrings[], channel_ring_t txrings[], uuid_t uuids[], int cfds[])
834*a1e26a70SApple OSS Distributions {
835*a1e26a70SApple OSS Distributions setup_tunsock(channel_count, uuids);
836*a1e26a70SApple OSS Distributions
837*a1e26a70SApple OSS Distributions #if 0
838*a1e26a70SApple OSS Distributions // give time to enable a tcpdump if desired
839*a1e26a70SApple OSS Distributions T_LOG("Sleeping 10");
840*a1e26a70SApple OSS Distributions sleep(10);
841*a1e26a70SApple OSS Distributions T_LOG("Done");
842*a1e26a70SApple OSS Distributions #endif
843*a1e26a70SApple OSS Distributions
844*a1e26a70SApple OSS Distributions for (int ri = 0; ri < channel_count; ri++) {
845*a1e26a70SApple OSS Distributions if (rxrings) {
846*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(channels[ri] = os_channel_create(uuids[ri], 0), NULL);
847*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(rxrings[ri] = os_channel_rx_ring(channels[ri],
848*a1e26a70SApple OSS Distributions os_channel_ring_id(channels[ri], CHANNEL_FIRST_RX_RING)), NULL);
849*a1e26a70SApple OSS Distributions }
850*a1e26a70SApple OSS Distributions if (txrings) {
851*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(channels[ri] = os_channel_create(uuids[ri], 0), NULL);
852*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_ASSERT_NOTNULL(rxrings[ri] = os_channel_rx_ring(channels[ri],
853*a1e26a70SApple OSS Distributions os_channel_ring_id(channels[ri], CHANNEL_FIRST_TX_RING)), NULL);
854*a1e26a70SApple OSS Distributions }
855*a1e26a70SApple OSS Distributions
856*a1e26a70SApple OSS Distributions struct kevent kev;
857*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(cfds[ri] = os_channel_get_fd(channels[ri]), NULL);
858*a1e26a70SApple OSS Distributions EV_SET(&kev, cfds[ri], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, (void *)(uintptr_t)ri);
859*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(kevent(kq, &kev, 1, NULL, 0, NULL), NULL);
860*a1e26a70SApple OSS Distributions }
861*a1e26a70SApple OSS Distributions }
862*a1e26a70SApple OSS Distributions
863*a1e26a70SApple OSS Distributions static void
cleanup_channels_and_rings(int channel_count,channel_t channels[],channel_ring_t rxrings[],channel_ring_t txrings[],uuid_t uuids[])864*a1e26a70SApple OSS Distributions cleanup_channels_and_rings(int channel_count, channel_t channels[], channel_ring_t rxrings[], channel_ring_t txrings[], uuid_t uuids[])
865*a1e26a70SApple OSS Distributions {
866*a1e26a70SApple OSS Distributions for (int ri = 0; ri < channel_count; ri++) {
867*a1e26a70SApple OSS Distributions if (rxrings) {
868*a1e26a70SApple OSS Distributions rxrings[ri] = NULL;
869*a1e26a70SApple OSS Distributions }
870*a1e26a70SApple OSS Distributions if (txrings) {
871*a1e26a70SApple OSS Distributions rxrings[ri] = NULL;
872*a1e26a70SApple OSS Distributions }
873*a1e26a70SApple OSS Distributions os_channel_destroy(channels[ri]);
874*a1e26a70SApple OSS Distributions channels[ri] = NULL;
875*a1e26a70SApple OSS Distributions uuid_clear(uuids[ri]);
876*a1e26a70SApple OSS Distributions }
877*a1e26a70SApple OSS Distributions }
878*a1e26a70SApple OSS Distributions
879*a1e26a70SApple OSS Distributions static void
setup_sockets(int sockets[SO_TC_MAX],int type)880*a1e26a70SApple OSS Distributions setup_sockets(int sockets[SO_TC_MAX], int type)
881*a1e26a70SApple OSS Distributions {
882*a1e26a70SApple OSS Distributions for (int si = 0; si < SO_TC_MAX; si++) {
883*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(sockets[si] = socket(PF_INET, type, 0), NULL);
884*a1e26a70SApple OSS Distributions
885*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(setsockopt(sockets[si], SOL_SOCKET,
886*a1e26a70SApple OSS Distributions SO_TRAFFIC_CLASS, &SOCKET_TRAFFIC_CLASSES[si], sizeof(SOCKET_TRAFFIC_CLASSES[si])), NULL);
887*a1e26a70SApple OSS Distributions
888*a1e26a70SApple OSS Distributions // XXX setsockopt(IP_BOUND_IF) here?
889*a1e26a70SApple OSS Distributions
890*a1e26a70SApple OSS Distributions struct sockaddr_in sin;
891*a1e26a70SApple OSS Distributions memset(&sin, 0, sizeof(sin));
892*a1e26a70SApple OSS Distributions sin.sin_len = sizeof(sin);
893*a1e26a70SApple OSS Distributions sin.sin_family = AF_INET;
894*a1e26a70SApple OSS Distributions sin.sin_addr = g_addr1;
895*a1e26a70SApple OSS Distributions
896*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(bind(sockets[si], (struct sockaddr *)&sin, sizeof(sin)), NULL);
897*a1e26a70SApple OSS Distributions
898*a1e26a70SApple OSS Distributions char sbuf[INET6_ADDRSTRLEN];
899*a1e26a70SApple OSS Distributions inet_ntop(sin.sin_family, &sin.sin_addr.s_addr, sbuf, sizeof(sbuf));
900*a1e26a70SApple OSS Distributions #if 0
901*a1e26a70SApple OSS Distributions T_LOG("%s socket %d bound to %s port %d",
902*a1e26a70SApple OSS Distributions type == SOCK_DGRAM ? "udp" : type == SOCK_STREAM ? "tcp" : "???",
903*a1e26a70SApple OSS Distributions sockets[si], sbuf, ntohs(sin.sin_port));
904*a1e26a70SApple OSS Distributions #endif
905*a1e26a70SApple OSS Distributions setblocking(sockets[si], false);
906*a1e26a70SApple OSS Distributions }
907*a1e26a70SApple OSS Distributions }
908*a1e26a70SApple OSS Distributions
909*a1e26a70SApple OSS Distributions static void
cleanup_sockets(int sockets[SO_TC_MAX])910*a1e26a70SApple OSS Distributions cleanup_sockets(int sockets[SO_TC_MAX])
911*a1e26a70SApple OSS Distributions {
912*a1e26a70SApple OSS Distributions for (int si = 0; si < SO_TC_MAX; si++) {
913*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(sockets[si]), NULL);
914*a1e26a70SApple OSS Distributions sockets[si] = -1;
915*a1e26a70SApple OSS Distributions }
916*a1e26a70SApple OSS Distributions }
917*a1e26a70SApple OSS Distributions
918*a1e26a70SApple OSS Distributions static void
drain_ring(channel_ring_t rxring)919*a1e26a70SApple OSS Distributions drain_ring(channel_ring_t rxring)
920*a1e26a70SApple OSS Distributions {
921*a1e26a70SApple OSS Distributions uint32_t i, sc = os_channel_available_slot_count(rxring);
922*a1e26a70SApple OSS Distributions channel_slot_t rxprev = NULL;
923*a1e26a70SApple OSS Distributions for (i = 0; i < sc; i++) {
924*a1e26a70SApple OSS Distributions slot_prop_t rxprop;
925*a1e26a70SApple OSS Distributions channel_slot_t rxslot;
926*a1e26a70SApple OSS Distributions
927*a1e26a70SApple OSS Distributions memset(&rxprop, 0, sizeof(rxprop));
928*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_NOTNULL(rxslot = os_channel_get_next_slot(rxring, rxprev, &rxprop), NULL);
929*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_NE_UINT(0, rxprop.sp_len, NULL);
930*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL((void *)rxprop.sp_buf_ptr, NULL);
931*a1e26a70SApple OSS Distributions
932*a1e26a70SApple OSS Distributions log_hexdump((void *)rxprop.sp_buf_ptr, rxprop.sp_len);
933*a1e26a70SApple OSS Distributions
934*a1e26a70SApple OSS Distributions rxprev = rxslot;
935*a1e26a70SApple OSS Distributions }
936*a1e26a70SApple OSS Distributions if (sc) {
937*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_ZERO(os_channel_advance_slot(rxring, rxprev), NULL);
938*a1e26a70SApple OSS Distributions }
939*a1e26a70SApple OSS Distributions }
940*a1e26a70SApple OSS Distributions
941*a1e26a70SApple OSS Distributions static void
send_one_packet(int s,int type)942*a1e26a70SApple OSS Distributions send_one_packet(int s, int type)
943*a1e26a70SApple OSS Distributions {
944*a1e26a70SApple OSS Distributions struct sockaddr_in sin;
945*a1e26a70SApple OSS Distributions memset(&sin, 0, sizeof(sin));
946*a1e26a70SApple OSS Distributions sin.sin_len = sizeof(sin);
947*a1e26a70SApple OSS Distributions sin.sin_family = AF_INET;
948*a1e26a70SApple OSS Distributions sin.sin_addr = g_addr2;
949*a1e26a70SApple OSS Distributions sin.sin_port = ntohs(12345);
950*a1e26a70SApple OSS Distributions
951*a1e26a70SApple OSS Distributions if (type == SOCK_STREAM) {
952*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_FAILURE(connect(s, (struct sockaddr *)&sin, sizeof(sin)), EINPROGRESS, NULL);
953*a1e26a70SApple OSS Distributions }
954*a1e26a70SApple OSS Distributions if (type == SOCK_DGRAM) {
955*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_EQ_LONG((long)sizeof(s), sendto(s, &s, sizeof(s), 0,
956*a1e26a70SApple OSS Distributions (struct sockaddr *)&sin, sizeof(sin)), NULL);
957*a1e26a70SApple OSS Distributions }
958*a1e26a70SApple OSS Distributions }
959*a1e26a70SApple OSS Distributions
960*a1e26a70SApple OSS Distributions static void
expect_empty_rings(int channel_count,channel_ring_t rings[])961*a1e26a70SApple OSS Distributions expect_empty_rings(int channel_count, channel_ring_t rings[])
962*a1e26a70SApple OSS Distributions {
963*a1e26a70SApple OSS Distributions /* Check all the rings and make sure there are no packets */
964*a1e26a70SApple OSS Distributions for (int ri = 0; ri < channel_count; ri++) {
965*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_UINT(0U, os_channel_available_slot_count(rings[ri]), NULL);
966*a1e26a70SApple OSS Distributions }
967*a1e26a70SApple OSS Distributions }
968*a1e26a70SApple OSS Distributions
969*a1e26a70SApple OSS Distributions static void
xfer_1_packet_singly(int channel_count,int type)970*a1e26a70SApple OSS Distributions xfer_1_packet_singly(int channel_count, int type)
971*a1e26a70SApple OSS Distributions {
972*a1e26a70SApple OSS Distributions uuid_t uuids[channel_count];
973*a1e26a70SApple OSS Distributions channel_t channels[channel_count];
974*a1e26a70SApple OSS Distributions int sockets[SO_TC_MAX];
975*a1e26a70SApple OSS Distributions channel_ring_t rxrings[channel_count];
976*a1e26a70SApple OSS Distributions int cfds[channel_count];
977*a1e26a70SApple OSS Distributions int kq;
978*a1e26a70SApple OSS Distributions
979*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(kq = kqueue(), NULL);
980*a1e26a70SApple OSS Distributions
981*a1e26a70SApple OSS Distributions setup_channels_and_rings(kq, channel_count, channels, rxrings, NULL, uuids, cfds);
982*a1e26a70SApple OSS Distributions
983*a1e26a70SApple OSS Distributions setup_sockets(sockets, type);
984*a1e26a70SApple OSS Distributions
985*a1e26a70SApple OSS Distributions for (int si = 0; si < SO_TC_MAX; si++) {
986*a1e26a70SApple OSS Distributions expect_empty_rings(channel_count, rxrings);
987*a1e26a70SApple OSS Distributions
988*a1e26a70SApple OSS Distributions send_one_packet(sockets[si], type);
989*a1e26a70SApple OSS Distributions
990*a1e26a70SApple OSS Distributions int expected_ring = channel_count == 1 ? 0 : SOCKET_TC_TO_RING[si];
991*a1e26a70SApple OSS Distributions
992*a1e26a70SApple OSS Distributions /* Wait for the packet delivery and check that it's only one packet and on the correct ring */
993*a1e26a70SApple OSS Distributions struct kevent kev[channel_count + 1];
994*a1e26a70SApple OSS Distributions int nev;
995*a1e26a70SApple OSS Distributions memset(kev, 0, sizeof(kev));
996*a1e26a70SApple OSS Distributions struct timespec to = { 0, 100 * NSEC_PER_MSEC }; // 100 ms
997*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(nev = kevent(kq, NULL, 0, kev, channel_count + 1, &to), NULL);
998*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_INT(nev, 1, NULL);
999*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_PTR((void *)kev[0].ident, (void *)(uintptr_t)cfds[expected_ring], NULL);
1000*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_PTR(kev[0].udata, (void *)(uintptr_t)expected_ring, NULL);
1001*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_SHORT(kev[0].filter, (short)EVFILT_READ, NULL);
1002*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(kev[0].flags & EV_ERROR, NULL);
1003*a1e26a70SApple OSS Distributions
1004*a1e26a70SApple OSS Distributions /* Make sure it comes out the expected interface */
1005*a1e26a70SApple OSS Distributions for (int ri = 0; ri < channel_count; ri++) {
1006*a1e26a70SApple OSS Distributions errno = 0;
1007*a1e26a70SApple OSS Distributions
1008*a1e26a70SApple OSS Distributions uint32_t sc = os_channel_available_slot_count(rxrings[ri]);
1009*a1e26a70SApple OSS Distributions
1010*a1e26a70SApple OSS Distributions /* Check that the packet appears only on the expected ring and
1011*a1e26a70SApple OSS Distributions * is the only packet on the expected ring.
1012*a1e26a70SApple OSS Distributions */
1013*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_UINT(ri == expected_ring, sc, NULL);
1014*a1e26a70SApple OSS Distributions
1015*a1e26a70SApple OSS Distributions if ((ri == expected_ring) == sc) {
1016*a1e26a70SApple OSS Distributions T_PASS("tc index %d ring %d expected ring %d slot count %u", si, ri, expected_ring, sc);
1017*a1e26a70SApple OSS Distributions } else {
1018*a1e26a70SApple OSS Distributions T_FAIL("tc index %d ring %d expected ring %d slot count %u", si, ri, expected_ring, sc);
1019*a1e26a70SApple OSS Distributions }
1020*a1e26a70SApple OSS Distributions
1021*a1e26a70SApple OSS Distributions drain_ring(rxrings[ri]);
1022*a1e26a70SApple OSS Distributions }
1023*a1e26a70SApple OSS Distributions }
1024*a1e26a70SApple OSS Distributions
1025*a1e26a70SApple OSS Distributions cleanup_sockets(sockets);
1026*a1e26a70SApple OSS Distributions
1027*a1e26a70SApple OSS Distributions cleanup_channels_and_rings(channel_count, channels, rxrings, NULL, uuids);
1028*a1e26a70SApple OSS Distributions
1029*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(kq), NULL);
1030*a1e26a70SApple OSS Distributions }
1031*a1e26a70SApple OSS Distributions
1032*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979u1s, "transfers 1 packet at a time of each sevice class over udp to a single ring", T_META_TAG_VM_PREFERRED)
1033*a1e26a70SApple OSS Distributions {
1034*a1e26a70SApple OSS Distributions setup_ipsec_test();
1035*a1e26a70SApple OSS Distributions xfer_1_packet_singly(1, SOCK_DGRAM);
1036*a1e26a70SApple OSS Distributions }
1037*a1e26a70SApple OSS Distributions
1038*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979u4s, "transfers 1 packet at a time of each sevice class over udp to 4 rings", T_META_TAG_VM_PREFERRED)
1039*a1e26a70SApple OSS Distributions {
1040*a1e26a70SApple OSS Distributions setup_ipsec_test();
1041*a1e26a70SApple OSS Distributions xfer_1_packet_singly(4, SOCK_DGRAM);
1042*a1e26a70SApple OSS Distributions }
1043*a1e26a70SApple OSS Distributions
1044*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979t1s, "transfers 1 packet at a time of each sevice class over tcp to a single ring", T_META_TAG_VM_PREFERRED)
1045*a1e26a70SApple OSS Distributions {
1046*a1e26a70SApple OSS Distributions setup_ipsec_test();
1047*a1e26a70SApple OSS Distributions xfer_1_packet_singly(1, SOCK_STREAM);
1048*a1e26a70SApple OSS Distributions }
1049*a1e26a70SApple OSS Distributions
1050*a1e26a70SApple OSS Distributions
1051*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979t4s, "transfers 1 packet at a time of each sevice class over tcp to 4 rings",
1052*a1e26a70SApple OSS Distributions /* This test will fail because tcp syn packets get elevated
1053*a1e26a70SApple OSS Distributions * due to ack prioritization
1054*a1e26a70SApple OSS Distributions */
1055*a1e26a70SApple OSS Distributions T_META_ENABLED(false), T_META_TAG_VM_PREFERRED)
1056*a1e26a70SApple OSS Distributions {
1057*a1e26a70SApple OSS Distributions setup_ipsec_test();
1058*a1e26a70SApple OSS Distributions xfer_1_packet_singly(4, SOCK_STREAM);
1059*a1e26a70SApple OSS Distributions }
1060*a1e26a70SApple OSS Distributions
1061*a1e26a70SApple OSS Distributions static void
xfer_1_packet_together(int channel_count,int type)1062*a1e26a70SApple OSS Distributions xfer_1_packet_together(int channel_count, int type)
1063*a1e26a70SApple OSS Distributions {
1064*a1e26a70SApple OSS Distributions uuid_t uuids[channel_count];
1065*a1e26a70SApple OSS Distributions channel_t channels[channel_count];
1066*a1e26a70SApple OSS Distributions int sockets[SO_TC_MAX];
1067*a1e26a70SApple OSS Distributions channel_ring_t rxrings[channel_count];
1068*a1e26a70SApple OSS Distributions int cfds[channel_count];
1069*a1e26a70SApple OSS Distributions int kq;
1070*a1e26a70SApple OSS Distributions
1071*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(kq = kqueue(), NULL);
1072*a1e26a70SApple OSS Distributions
1073*a1e26a70SApple OSS Distributions setup_channels_and_rings(kq, channel_count, channels, rxrings, NULL, uuids, cfds);
1074*a1e26a70SApple OSS Distributions
1075*a1e26a70SApple OSS Distributions setup_sockets(sockets, type);
1076*a1e26a70SApple OSS Distributions
1077*a1e26a70SApple OSS Distributions for (int si = 0; si < SO_TC_MAX; si++) {
1078*a1e26a70SApple OSS Distributions expect_empty_rings(channel_count, rxrings);
1079*a1e26a70SApple OSS Distributions
1080*a1e26a70SApple OSS Distributions send_one_packet(sockets[si], type);
1081*a1e26a70SApple OSS Distributions }
1082*a1e26a70SApple OSS Distributions
1083*a1e26a70SApple OSS Distributions /* Sleep to make sure all packets get delivered */
1084*a1e26a70SApple OSS Distributions struct timespec to = { 0, 100 * NSEC_PER_MSEC }; // 100 ms
1085*a1e26a70SApple OSS Distributions nanosleep(&to, NULL);
1086*a1e26a70SApple OSS Distributions
1087*a1e26a70SApple OSS Distributions /* Wait for the packet delivery and check that all rings event */
1088*a1e26a70SApple OSS Distributions struct kevent kev[channel_count + 1];
1089*a1e26a70SApple OSS Distributions int nev;
1090*a1e26a70SApple OSS Distributions memset(kev, 0, sizeof(kev));
1091*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_POSIX_SUCCESS(nev = kevent(kq, NULL, 0, kev, channel_count + 1, &to), NULL);
1092*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_INT(nev, channel_count, NULL);
1093*a1e26a70SApple OSS Distributions
1094*a1e26a70SApple OSS Distributions uint32_t found[channel_count];
1095*a1e26a70SApple OSS Distributions memset(found, 0, sizeof(found));
1096*a1e26a70SApple OSS Distributions for (int e = 0; e < nev; e++) {
1097*a1e26a70SApple OSS Distributions T_LOG("kevent %lu filter 0x%4x flags 0x%04x fflags 0x%08x data %"PRIdPTR" udata %p",
1098*a1e26a70SApple OSS Distributions kev[e].ident, kev[e].filter, kev[e].flags, kev[e].fflags, kev[e].data, kev[e].udata);
1099*a1e26a70SApple OSS Distributions
1100*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_GE_PTR(kev[e].udata, (void *)0, NULL);
1101*a1e26a70SApple OSS Distributions T_QUIET; T_ASSERT_LT_PTR(kev[e].udata, (void *)(intptr_t)channel_count, NULL);
1102*a1e26a70SApple OSS Distributions int ri = (int)kev[e].udata;
1103*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_UINT(found[ri], 0U, NULL);
1104*a1e26a70SApple OSS Distributions
1105*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_ULONG(kev[e].ident, (uintptr_t)cfds[ri], NULL);
1106*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_SHORT(kev[e].filter, (short)EVFILT_READ, NULL);
1107*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(kev[e].flags & EV_ERROR, NULL);
1108*a1e26a70SApple OSS Distributions
1109*a1e26a70SApple OSS Distributions if (channel_count == 1) {
1110*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_LONG(kev[e].data, (long)SO_TC_MAX, NULL);
1111*a1e26a70SApple OSS Distributions } else {
1112*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_EQ_LONG(kev[e].data, (long)RING_TO_TC_COUNT[ri], NULL);
1113*a1e26a70SApple OSS Distributions }
1114*a1e26a70SApple OSS Distributions
1115*a1e26a70SApple OSS Distributions found[ri] += (uint32_t)kev[e].data;
1116*a1e26a70SApple OSS Distributions }
1117*a1e26a70SApple OSS Distributions /* Check that something came out of all rings */
1118*a1e26a70SApple OSS Distributions for (int ri = 0; ri < channel_count; ri++) {
1119*a1e26a70SApple OSS Distributions T_QUIET; T_EXPECT_NE_UINT(found[ri], 0U, NULL);
1120*a1e26a70SApple OSS Distributions }
1121*a1e26a70SApple OSS Distributions
1122*a1e26a70SApple OSS Distributions /* Make sure it comes out the expected interface */
1123*a1e26a70SApple OSS Distributions for (int ri = 0; ri < channel_count; ri++) {
1124*a1e26a70SApple OSS Distributions uint32_t sc = os_channel_available_slot_count(rxrings[ri]);
1125*a1e26a70SApple OSS Distributions if (channel_count == 1) {
1126*a1e26a70SApple OSS Distributions if (sc == SO_TC_MAX) {
1127*a1e26a70SApple OSS Distributions T_PASS("ring %d got %"PRIu32" slots expecting %"PRIu32"", ri, sc, SO_TC_MAX);
1128*a1e26a70SApple OSS Distributions } else {
1129*a1e26a70SApple OSS Distributions T_FAIL("ring %d got %"PRIu32" slots expecting %"PRIu32"", ri, sc, SO_TC_MAX);
1130*a1e26a70SApple OSS Distributions }
1131*a1e26a70SApple OSS Distributions } else {
1132*a1e26a70SApple OSS Distributions if (sc == (uint32_t)RING_TO_TC_COUNT[ri]) {
1133*a1e26a70SApple OSS Distributions T_PASS("ring %d got %"PRIu32" slots expecting %"PRIu32"", ri, sc, (uint32_t)RING_TO_TC_COUNT[ri]);
1134*a1e26a70SApple OSS Distributions } else {
1135*a1e26a70SApple OSS Distributions T_FAIL("ring %d got %"PRIu32" slots expecting %"PRIu32"", ri, sc, (uint32_t)RING_TO_TC_COUNT[ri]);
1136*a1e26a70SApple OSS Distributions }
1137*a1e26a70SApple OSS Distributions }
1138*a1e26a70SApple OSS Distributions
1139*a1e26a70SApple OSS Distributions drain_ring(rxrings[ri]);
1140*a1e26a70SApple OSS Distributions }
1141*a1e26a70SApple OSS Distributions
1142*a1e26a70SApple OSS Distributions cleanup_sockets(sockets);
1143*a1e26a70SApple OSS Distributions
1144*a1e26a70SApple OSS Distributions cleanup_channels_and_rings(channel_count, channels, rxrings, NULL, uuids);
1145*a1e26a70SApple OSS Distributions
1146*a1e26a70SApple OSS Distributions T_QUIET; T_WITH_ERRNO; T_EXPECT_POSIX_ZERO(close(kq), NULL);
1147*a1e26a70SApple OSS Distributions }
1148*a1e26a70SApple OSS Distributions
1149*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979u1m, "transfers 1 packet together of each sevice class over udp to a single ring", T_META_TAG_VM_PREFERRED)
1150*a1e26a70SApple OSS Distributions {
1151*a1e26a70SApple OSS Distributions setup_ipsec_test();
1152*a1e26a70SApple OSS Distributions xfer_1_packet_together(1, SOCK_DGRAM);
1153*a1e26a70SApple OSS Distributions }
1154*a1e26a70SApple OSS Distributions
1155*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979u4m, "transfers 1 packet together of each sevice class over udp to 4 rings", T_META_TAG_VM_PREFERRED)
1156*a1e26a70SApple OSS Distributions {
1157*a1e26a70SApple OSS Distributions setup_ipsec_test();
1158*a1e26a70SApple OSS Distributions xfer_1_packet_together(4, SOCK_DGRAM);
1159*a1e26a70SApple OSS Distributions }
1160*a1e26a70SApple OSS Distributions
1161*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979t1m, "transfers 1 packet together of each sevice class over tcp to a single ring", T_META_TAG_VM_PREFERRED)
1162*a1e26a70SApple OSS Distributions {
1163*a1e26a70SApple OSS Distributions setup_ipsec_test();
1164*a1e26a70SApple OSS Distributions xfer_1_packet_together(1, SOCK_STREAM);
1165*a1e26a70SApple OSS Distributions }
1166*a1e26a70SApple OSS Distributions
1167*a1e26a70SApple OSS Distributions T_DECL(ipsec35889979t4m, "transfers 1 packet together of each sevice class over tcp to 4 rings",
1168*a1e26a70SApple OSS Distributions /* This test will fail because tcp syn packets get elevated
1169*a1e26a70SApple OSS Distributions * due to ack prioritization
1170*a1e26a70SApple OSS Distributions */
1171*a1e26a70SApple OSS Distributions T_META_ENABLED(false), T_META_TAG_VM_PREFERRED)
1172*a1e26a70SApple OSS Distributions {
1173*a1e26a70SApple OSS Distributions setup_ipsec_test();
1174*a1e26a70SApple OSS Distributions xfer_1_packet_together(4, SOCK_STREAM);
1175*a1e26a70SApple OSS Distributions }
1176