1*33de042dSApple OSS Distributions /*
2*33de042dSApple OSS Distributions * Copyright (c) 2024 Apple Inc. All rights reserved.
3*33de042dSApple OSS Distributions *
4*33de042dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*33de042dSApple OSS Distributions *
6*33de042dSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*33de042dSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*33de042dSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*33de042dSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*33de042dSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*33de042dSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*33de042dSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*33de042dSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*33de042dSApple OSS Distributions *
15*33de042dSApple OSS Distributions * Please obtain a copy of the License at
16*33de042dSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*33de042dSApple OSS Distributions *
18*33de042dSApple OSS Distributions * The Original Code and all software distributed under the License are
19*33de042dSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*33de042dSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*33de042dSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*33de042dSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*33de042dSApple OSS Distributions * Please see the License for the specific language governing rights and
24*33de042dSApple OSS Distributions * limitations under the License.
25*33de042dSApple OSS Distributions *
26*33de042dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*33de042dSApple OSS Distributions */
28*33de042dSApple OSS Distributions
29*33de042dSApple OSS Distributions /*
30*33de042dSApple OSS Distributions * net_vlan.c
31*33de042dSApple OSS Distributions * - test if_vlan.c functionality
32*33de042dSApple OSS Distributions */
33*33de042dSApple OSS Distributions
34*33de042dSApple OSS Distributions #include <darwintest.h>
35*33de042dSApple OSS Distributions #include <stdio.h>
36*33de042dSApple OSS Distributions #include <unistd.h>
37*33de042dSApple OSS Distributions #include <stddef.h>
38*33de042dSApple OSS Distributions #include <stdlib.h>
39*33de042dSApple OSS Distributions #include <string.h>
40*33de042dSApple OSS Distributions #include <sys/socket.h>
41*33de042dSApple OSS Distributions #include <arpa/inet.h>
42*33de042dSApple OSS Distributions #include <sys/event.h>
43*33de042dSApple OSS Distributions #include <net/if.h>
44*33de042dSApple OSS Distributions #include <net/if_vlan_var.h>
45*33de042dSApple OSS Distributions #include <netinet/in.h>
46*33de042dSApple OSS Distributions #include <netinet6/in6_var.h>
47*33de042dSApple OSS Distributions #include <netinet6/nd6.h>
48*33de042dSApple OSS Distributions #include <netinet/in.h>
49*33de042dSApple OSS Distributions #include <netinet/ip.h>
50*33de042dSApple OSS Distributions #include <netinet/udp.h>
51*33de042dSApple OSS Distributions #include <netinet/tcp.h>
52*33de042dSApple OSS Distributions #include <netinet/if_ether.h>
53*33de042dSApple OSS Distributions #include <netinet/ip6.h>
54*33de042dSApple OSS Distributions #include <netinet/icmp6.h>
55*33de042dSApple OSS Distributions #include <net/if_arp.h>
56*33de042dSApple OSS Distributions #include <net/bpf.h>
57*33de042dSApple OSS Distributions #include <sys/ioctl.h>
58*33de042dSApple OSS Distributions #include <sys/types.h>
59*33de042dSApple OSS Distributions #include <sys/stat.h>
60*33de042dSApple OSS Distributions #include <errno.h>
61*33de042dSApple OSS Distributions #include <pthread.h>
62*33de042dSApple OSS Distributions #include <stdbool.h>
63*33de042dSApple OSS Distributions #include <TargetConditionals.h>
64*33de042dSApple OSS Distributions #include <darwintest_utils.h>
65*33de042dSApple OSS Distributions #include <os/variant_private.h>
66*33de042dSApple OSS Distributions
67*33de042dSApple OSS Distributions #include "net_test_lib.h"
68*33de042dSApple OSS Distributions #include "inet_transfer.h"
69*33de042dSApple OSS Distributions #include "bpflib.h"
70*33de042dSApple OSS Distributions #include "in_cksum.h"
71*33de042dSApple OSS Distributions
72*33de042dSApple OSS Distributions #define VLAN_UNIT_START 200 /* start at vlan200 to avoid conflicts */
73*33de042dSApple OSS Distributions #define TEN_NET 0x0a000000
74*33de042dSApple OSS Distributions #define TEN_1_NET (TEN_NET | 0x010000)
75*33de042dSApple OSS Distributions #define VLAN_TAG_START 1
76*33de042dSApple OSS Distributions
77*33de042dSApple OSS Distributions static void
get_ipv4_address(u_int unit,u_int addr_index,struct in_addr * ip)78*33de042dSApple OSS Distributions get_ipv4_address(u_int unit, u_int addr_index, struct in_addr *ip)
79*33de042dSApple OSS Distributions {
80*33de042dSApple OSS Distributions /* up to 255 units, 255 addresses */
81*33de042dSApple OSS Distributions ip->s_addr = htonl(TEN_1_NET | (unit << 8) | addr_index);
82*33de042dSApple OSS Distributions return;
83*33de042dSApple OSS Distributions }
84*33de042dSApple OSS Distributions
85*33de042dSApple OSS Distributions /**
86*33de042dSApple OSS Distributions ** interface management
87*33de042dSApple OSS Distributions **/
88*33de042dSApple OSS Distributions
89*33de042dSApple OSS Distributions /**
90*33de042dSApple OSS Distributions ** Test Main
91*33de042dSApple OSS Distributions **/
92*33de042dSApple OSS Distributions static network_interface_pair_list_t S_feth_pairs;
93*33de042dSApple OSS Distributions static network_interface_pair_list_t S_vlan_pairs;
94*33de042dSApple OSS Distributions static const char * S_bridge;
95*33de042dSApple OSS Distributions
96*33de042dSApple OSS Distributions #define VLAN_SYSCTL "net.link.vlan"
97*33de042dSApple OSS Distributions #define VLAN_SYSCTL_ENABLED VLAN_SYSCTL ".enabled"
98*33de042dSApple OSS Distributions
99*33de042dSApple OSS Distributions #define FAKE_SYSCTL "net.link.fake"
100*33de042dSApple OSS Distributions #define FAKE_SYSCTL_BSD_MODE FAKE_SYSCTL ".bsd_mode"
101*33de042dSApple OSS Distributions #define FAKE_SYSCTL_VLAN_TAGGING FAKE_SYSCTL ".vlan_tagging"
102*33de042dSApple OSS Distributions
103*33de042dSApple OSS Distributions static int fake_bsd_mode;
104*33de042dSApple OSS Distributions static bool fake_bsd_mode_was_set;
105*33de042dSApple OSS Distributions static int fake_vlan_tagging;
106*33de042dSApple OSS Distributions static bool fake_vlan_tagging_was_set;
107*33de042dSApple OSS Distributions
108*33de042dSApple OSS Distributions static void
sysctl_set_integer(const char * name,int val,int * restore_val,bool * was_set)109*33de042dSApple OSS Distributions sysctl_set_integer(const char * name, int val, int * restore_val,
110*33de042dSApple OSS Distributions bool * was_set)
111*33de042dSApple OSS Distributions {
112*33de042dSApple OSS Distributions int error;
113*33de042dSApple OSS Distributions size_t len;
114*33de042dSApple OSS Distributions
115*33de042dSApple OSS Distributions T_LOG("%s\n", __func__);
116*33de042dSApple OSS Distributions len = sizeof(int);
117*33de042dSApple OSS Distributions error = sysctlbyname(name, restore_val, &len, &val, sizeof(int));
118*33de042dSApple OSS Distributions T_ASSERT_EQ(error, 0, "sysctl %s %d -> %d", name, *restore_val, val);
119*33de042dSApple OSS Distributions *was_set = (*restore_val != val);
120*33de042dSApple OSS Distributions }
121*33de042dSApple OSS Distributions
122*33de042dSApple OSS Distributions static void
sysctl_restore_integer(const char * name,int restore_val,bool was_set)123*33de042dSApple OSS Distributions sysctl_restore_integer(const char * name, int restore_val, bool was_set)
124*33de042dSApple OSS Distributions {
125*33de042dSApple OSS Distributions if (was_set) {
126*33de042dSApple OSS Distributions int error;
127*33de042dSApple OSS Distributions
128*33de042dSApple OSS Distributions error = sysctlbyname(name, NULL, 0, &restore_val, sizeof(int));
129*33de042dSApple OSS Distributions T_ASSERT_EQ(error, 0, "sysctl %s %d", name, restore_val);
130*33de042dSApple OSS Distributions } else {
131*33de042dSApple OSS Distributions T_LOG("sysctl %s not modified", name);
132*33de042dSApple OSS Distributions }
133*33de042dSApple OSS Distributions }
134*33de042dSApple OSS Distributions
135*33de042dSApple OSS Distributions static void
fake_set_bsd_mode(bool enable)136*33de042dSApple OSS Distributions fake_set_bsd_mode(bool enable)
137*33de042dSApple OSS Distributions {
138*33de042dSApple OSS Distributions sysctl_set_integer(FAKE_SYSCTL_BSD_MODE, enable ? 1 : 0,
139*33de042dSApple OSS Distributions &fake_bsd_mode, &fake_bsd_mode_was_set);
140*33de042dSApple OSS Distributions }
141*33de042dSApple OSS Distributions
142*33de042dSApple OSS Distributions static void
fake_restore_bsd_mode(void)143*33de042dSApple OSS Distributions fake_restore_bsd_mode(void)
144*33de042dSApple OSS Distributions {
145*33de042dSApple OSS Distributions sysctl_restore_integer(FAKE_SYSCTL_BSD_MODE,
146*33de042dSApple OSS Distributions fake_bsd_mode, fake_bsd_mode_was_set);
147*33de042dSApple OSS Distributions }
148*33de042dSApple OSS Distributions
149*33de042dSApple OSS Distributions static void
fake_set_vlan_tagging(bool enable)150*33de042dSApple OSS Distributions fake_set_vlan_tagging(bool enable)
151*33de042dSApple OSS Distributions {
152*33de042dSApple OSS Distributions sysctl_set_integer(FAKE_SYSCTL_VLAN_TAGGING, enable ? 1 : 0,
153*33de042dSApple OSS Distributions &fake_vlan_tagging, &fake_vlan_tagging_was_set);
154*33de042dSApple OSS Distributions }
155*33de042dSApple OSS Distributions
156*33de042dSApple OSS Distributions static void
fake_restore_vlan_tagging(void)157*33de042dSApple OSS Distributions fake_restore_vlan_tagging(void)
158*33de042dSApple OSS Distributions {
159*33de042dSApple OSS Distributions sysctl_restore_integer(FAKE_SYSCTL_VLAN_TAGGING, fake_vlan_tagging,
160*33de042dSApple OSS Distributions fake_vlan_tagging_was_set);
161*33de042dSApple OSS Distributions }
162*33de042dSApple OSS Distributions
163*33de042dSApple OSS Distributions #if !TARGET_OS_BRIDGE
164*33de042dSApple OSS Distributions #if !TARGET_OS_OSX
165*33de042dSApple OSS Distributions static bool
vlan_is_enabled(void)166*33de042dSApple OSS Distributions vlan_is_enabled(void)
167*33de042dSApple OSS Distributions {
168*33de042dSApple OSS Distributions size_t len = sizeof(int);
169*33de042dSApple OSS Distributions int val = 0;
170*33de042dSApple OSS Distributions
171*33de042dSApple OSS Distributions (void)sysctlbyname(VLAN_SYSCTL_ENABLED, &val, &len, NULL, 0);
172*33de042dSApple OSS Distributions return val != 0;
173*33de042dSApple OSS Distributions }
174*33de042dSApple OSS Distributions #endif /* !TARGET_OS_OSX */
175*33de042dSApple OSS Distributions #endif /* !TARGET_OS_BRIDGE */
176*33de042dSApple OSS Distributions
177*33de042dSApple OSS Distributions static void
cleanup_common(void)178*33de042dSApple OSS Distributions cleanup_common(void)
179*33de042dSApple OSS Distributions {
180*33de042dSApple OSS Distributions if (G_debug) {
181*33de042dSApple OSS Distributions T_LOG("Sleeping for 5 seconds\n");
182*33de042dSApple OSS Distributions sleep(5);
183*33de042dSApple OSS Distributions }
184*33de042dSApple OSS Distributions if (S_bridge != NULL) {
185*33de042dSApple OSS Distributions ifnet_destroy(S_bridge, false);
186*33de042dSApple OSS Distributions }
187*33de042dSApple OSS Distributions fake_restore_bsd_mode();
188*33de042dSApple OSS Distributions fake_restore_vlan_tagging();
189*33de042dSApple OSS Distributions network_interface_pair_list_destroy(S_feth_pairs);
190*33de042dSApple OSS Distributions network_interface_pair_list_destroy(S_vlan_pairs);
191*33de042dSApple OSS Distributions return;
192*33de042dSApple OSS Distributions }
193*33de042dSApple OSS Distributions
194*33de042dSApple OSS Distributions static void
cleanup(void)195*33de042dSApple OSS Distributions cleanup(void)
196*33de042dSApple OSS Distributions {
197*33de042dSApple OSS Distributions cleanup_common();
198*33de042dSApple OSS Distributions return;
199*33de042dSApple OSS Distributions }
200*33de042dSApple OSS Distributions
201*33de042dSApple OSS Distributions static void
sigint_handler(__unused int sig)202*33de042dSApple OSS Distributions sigint_handler(__unused int sig)
203*33de042dSApple OSS Distributions {
204*33de042dSApple OSS Distributions cleanup_common();
205*33de042dSApple OSS Distributions signal(SIGINT, SIG_DFL);
206*33de042dSApple OSS Distributions }
207*33de042dSApple OSS Distributions
208*33de042dSApple OSS Distributions static void
test_traffic_for_network_interfaces(network_interface_t one,network_interface_t two,uint8_t af)209*33de042dSApple OSS Distributions test_traffic_for_network_interfaces(network_interface_t one,
210*33de042dSApple OSS Distributions network_interface_t two,
211*33de042dSApple OSS Distributions uint8_t af)
212*33de042dSApple OSS Distributions {
213*33de042dSApple OSS Distributions inet_address server;
214*33de042dSApple OSS Distributions
215*33de042dSApple OSS Distributions T_LOG("Testing %s -> %s\n",
216*33de042dSApple OSS Distributions one->if_name, two->if_name);
217*33de042dSApple OSS Distributions if (af == AF_INET) {
218*33de042dSApple OSS Distributions server.v4 = one->ip;
219*33de042dSApple OSS Distributions } else {
220*33de042dSApple OSS Distributions server.v6 = two->ip6;
221*33de042dSApple OSS Distributions }
222*33de042dSApple OSS Distributions inet_test_traffic(af, &server, one->if_name, one->if_index,
223*33de042dSApple OSS Distributions two->if_name, two->if_index);
224*33de042dSApple OSS Distributions }
225*33de042dSApple OSS Distributions
226*33de042dSApple OSS Distributions static void
test_traffic_for_pair(network_interface_pair_t pair,uint8_t af)227*33de042dSApple OSS Distributions test_traffic_for_pair(network_interface_pair_t pair, uint8_t af)
228*33de042dSApple OSS Distributions {
229*33de042dSApple OSS Distributions test_traffic_for_network_interfaces(&pair->one, &pair->two, af);
230*33de042dSApple OSS Distributions }
231*33de042dSApple OSS Distributions
232*33de042dSApple OSS Distributions static void
test_traffic_for_af(uint8_t af)233*33de042dSApple OSS Distributions test_traffic_for_af(uint8_t af)
234*33de042dSApple OSS Distributions {
235*33de042dSApple OSS Distributions test_traffic_for_pair(S_feth_pairs->list, af);
236*33de042dSApple OSS Distributions
237*33de042dSApple OSS Distributions for (u_int i = 0; i < S_vlan_pairs->count; i++) {
238*33de042dSApple OSS Distributions network_interface_pair_t pair;
239*33de042dSApple OSS Distributions
240*33de042dSApple OSS Distributions pair = &S_vlan_pairs->list[i];
241*33de042dSApple OSS Distributions test_traffic_for_pair(pair, af);
242*33de042dSApple OSS Distributions }
243*33de042dSApple OSS Distributions }
244*33de042dSApple OSS Distributions
245*33de042dSApple OSS Distributions static void
network_interface_assign_address(network_interface_t netif,unsigned int unit,unsigned int address_index)246*33de042dSApple OSS Distributions network_interface_assign_address(network_interface_t netif,
247*33de042dSApple OSS Distributions unsigned int unit, unsigned int address_index)
248*33de042dSApple OSS Distributions {
249*33de042dSApple OSS Distributions get_ipv4_address(unit, address_index, &netif->ip);
250*33de042dSApple OSS Distributions ifnet_add_ip_address(netif->if_name, netif->ip,
251*33de042dSApple OSS Distributions inet_class_c_subnet_mask);
252*33de042dSApple OSS Distributions route_add_inet_scoped_subnet(netif->if_name, netif->if_index,
253*33de042dSApple OSS Distributions netif->ip, inet_class_c_subnet_mask);
254*33de042dSApple OSS Distributions }
255*33de042dSApple OSS Distributions
256*33de042dSApple OSS Distributions static void
initialize_feth_pairs(u_int n,bool need_address)257*33de042dSApple OSS Distributions initialize_feth_pairs(u_int n, bool need_address)
258*33de042dSApple OSS Distributions {
259*33de042dSApple OSS Distributions network_interface_pair_t scan;
260*33de042dSApple OSS Distributions
261*33de042dSApple OSS Distributions S_feth_pairs = network_interface_pair_list_alloc(n);
262*33de042dSApple OSS Distributions scan = S_feth_pairs->list;
263*33de042dSApple OSS Distributions for (unsigned int i = 0; i < n; i++, scan++) {
264*33de042dSApple OSS Distributions network_interface_create(&scan->one, FETH_NAME);
265*33de042dSApple OSS Distributions network_interface_create(&scan->two, FETH_NAME);
266*33de042dSApple OSS Distributions if (need_address) {
267*33de042dSApple OSS Distributions network_interface_assign_address(&scan->one, i, 1);
268*33de042dSApple OSS Distributions network_interface_assign_address(&scan->two, i, 2);
269*33de042dSApple OSS Distributions }
270*33de042dSApple OSS Distributions fake_set_peer(scan->one.if_name, scan->two.if_name);
271*33de042dSApple OSS Distributions }
272*33de042dSApple OSS Distributions }
273*33de042dSApple OSS Distributions
274*33de042dSApple OSS Distributions static void
initialize_vlan_pairs(u_int n,bool need_address)275*33de042dSApple OSS Distributions initialize_vlan_pairs(u_int n, bool need_address)
276*33de042dSApple OSS Distributions {
277*33de042dSApple OSS Distributions network_interface_pair_t feth_pair;
278*33de042dSApple OSS Distributions network_interface_pair_t scan;
279*33de042dSApple OSS Distributions int vlan_unit = VLAN_UNIT_START;
280*33de042dSApple OSS Distributions
281*33de042dSApple OSS Distributions feth_pair = S_feth_pairs->list;
282*33de042dSApple OSS Distributions S_vlan_pairs = network_interface_pair_list_alloc(n);
283*33de042dSApple OSS Distributions scan = S_vlan_pairs->list;
284*33de042dSApple OSS Distributions for (size_t i = 0; i < n; i++, scan++) {
285*33de042dSApple OSS Distributions if_name_t name;
286*33de042dSApple OSS Distributions uint16_t tag = (uint16_t)(i + VLAN_TAG_START);
287*33de042dSApple OSS Distributions
288*33de042dSApple OSS Distributions snprintf(name, sizeof(name), "%s%d", VLAN_NAME, vlan_unit++);
289*33de042dSApple OSS Distributions network_interface_create(&scan->one, name);
290*33de042dSApple OSS Distributions siocsifvlan(scan->one.if_name, feth_pair->one.if_name, tag);
291*33de042dSApple OSS Distributions if (need_address) {
292*33de042dSApple OSS Distributions network_interface_assign_address(&scan->one, tag, 1);
293*33de042dSApple OSS Distributions }
294*33de042dSApple OSS Distributions
295*33de042dSApple OSS Distributions snprintf(name, sizeof(name), "%s%d", VLAN_NAME, vlan_unit++);
296*33de042dSApple OSS Distributions network_interface_create(&scan->two, name);
297*33de042dSApple OSS Distributions siocsifvlan(scan->two.if_name, feth_pair->two.if_name, tag);
298*33de042dSApple OSS Distributions if (need_address) {
299*33de042dSApple OSS Distributions network_interface_assign_address(&scan->two, tag, 2);
300*33de042dSApple OSS Distributions }
301*33de042dSApple OSS Distributions }
302*33de042dSApple OSS Distributions }
303*33de042dSApple OSS Distributions
304*33de042dSApple OSS Distributions static void
vlan_send_short_packet(void)305*33de042dSApple OSS Distributions vlan_send_short_packet(void)
306*33de042dSApple OSS Distributions {
307*33de042dSApple OSS Distributions ether_addr_t eaddr;
308*33de042dSApple OSS Distributions struct ether_vlan_header * evl_p;
309*33de042dSApple OSS Distributions int fd;
310*33de042dSApple OSS Distributions size_t frame_length;
311*33de042dSApple OSS Distributions const char * ifname;
312*33de042dSApple OSS Distributions uint16_t * length;
313*33de042dSApple OSS Distributions uint8_t * data;
314*33de042dSApple OSS Distributions ssize_t n;
315*33de042dSApple OSS Distributions int opt;
316*33de042dSApple OSS Distributions ether_packet pkt;
317*33de042dSApple OSS Distributions
318*33de042dSApple OSS Distributions ifname = S_feth_pairs->list->one.if_name;
319*33de042dSApple OSS Distributions fd = bpf_new();
320*33de042dSApple OSS Distributions T_ASSERT_GE(fd, 0, "bpf_new() %d", fd);
321*33de042dSApple OSS Distributions bpf_set_traffic_class(fd, SO_TC_CTL);
322*33de042dSApple OSS Distributions opt = 1;
323*33de042dSApple OSS Distributions T_QUIET;
324*33de042dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ioctl(fd, FIONBIO, &opt), NULL);
325*33de042dSApple OSS Distributions T_QUIET;
326*33de042dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_immediate(fd, 1), NULL);
327*33de042dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_setif(fd, ifname), "bpf set if %s",
328*33de042dSApple OSS Distributions ifname);
329*33de042dSApple OSS Distributions T_QUIET;
330*33de042dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_see_sent(fd, 0), NULL);
331*33de042dSApple OSS Distributions T_QUIET;
332*33de042dSApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bpf_set_header_complete(fd, 1), NULL);
333*33de042dSApple OSS Distributions T_QUIET;
334*33de042dSApple OSS Distributions ifnet_get_lladdr(ifname, &eaddr);
335*33de042dSApple OSS Distributions
336*33de042dSApple OSS Distributions #define VLAN_SHORT_PAYLOAD_LENGTH 6
337*33de042dSApple OSS Distributions /* send broadcast 802.3 LLC frame of length 6 (rdar://129012466) */
338*33de042dSApple OSS Distributions bzero(&pkt, sizeof(pkt));
339*33de042dSApple OSS Distributions frame_length = sizeof(*evl_p) + VLAN_SHORT_PAYLOAD_LENGTH;
340*33de042dSApple OSS Distributions evl_p = (struct ether_vlan_header *)&pkt;
341*33de042dSApple OSS Distributions bcopy(ðer_broadcast, evl_p->evl_dhost, sizeof(evl_p->evl_dhost));
342*33de042dSApple OSS Distributions bcopy(&eaddr, evl_p->evl_shost, sizeof(evl_p->evl_shost));
343*33de042dSApple OSS Distributions evl_p->evl_tag = htons(VLAN_TAG_START);
344*33de042dSApple OSS Distributions evl_p->evl_encap_proto = htons(ETHERTYPE_VLAN);
345*33de042dSApple OSS Distributions length = (uint16_t *)&evl_p->evl_proto;
346*33de042dSApple OSS Distributions *length = htons(VLAN_SHORT_PAYLOAD_LENGTH);
347*33de042dSApple OSS Distributions /* make it an LLC frame so that it will decode as a valid packet */
348*33de042dSApple OSS Distributions data = (uint8_t *)(length + 1);
349*33de042dSApple OSS Distributions *data++ = 0x00;
350*33de042dSApple OSS Distributions *data++ = 0x0a;
351*33de042dSApple OSS Distributions *data++ = 0x00;
352*33de042dSApple OSS Distributions *data++ = 0x06;
353*33de042dSApple OSS Distributions *data++ = 0x00;
354*33de042dSApple OSS Distributions *data++ = 0x01;
355*33de042dSApple OSS Distributions n = write(fd, &pkt, frame_length);
356*33de042dSApple OSS Distributions T_ASSERT_EQ((size_t)n, frame_length, "write");
357*33de042dSApple OSS Distributions close(fd);
358*33de042dSApple OSS Distributions }
359*33de042dSApple OSS Distributions
360*33de042dSApple OSS Distributions static void
vlan_test_check_skip(void)361*33de042dSApple OSS Distributions vlan_test_check_skip(void)
362*33de042dSApple OSS Distributions {
363*33de042dSApple OSS Distributions #if TARGET_OS_BRIDGE
364*33de042dSApple OSS Distributions T_SKIP("Skipping test on bridgeOS");
365*33de042dSApple OSS Distributions #else /* TARGET_OS_BRIDGE */
366*33de042dSApple OSS Distributions #if !TARGET_OS_OSX
367*33de042dSApple OSS Distributions #define XNU_TEST_NET_VLAN "com.apple.xnu.test.net_vlan"
368*33de042dSApple OSS Distributions if (!vlan_is_enabled()) {
369*33de042dSApple OSS Distributions if (os_variant_is_darwinos(XNU_TEST_NET_VLAN)) {
370*33de042dSApple OSS Distributions T_FAIL("darwinos should support VLAN");
371*33de042dSApple OSS Distributions }
372*33de042dSApple OSS Distributions if (os_variant_has_factory_content(XNU_TEST_NET_VLAN)) {
373*33de042dSApple OSS Distributions T_FAIL("non-ui should support VLAN");
374*33de042dSApple OSS Distributions }
375*33de042dSApple OSS Distributions T_SKIP("VLAN is not available on this os variant");
376*33de042dSApple OSS Distributions }
377*33de042dSApple OSS Distributions #endif /* !TARGET_OS_OSX */
378*33de042dSApple OSS Distributions #endif /* TARGET_OS_BRIDGE */
379*33de042dSApple OSS Distributions }
380*33de042dSApple OSS Distributions
381*33de042dSApple OSS Distributions
382*33de042dSApple OSS Distributions static void
vlan_test_traffic(bool hw_vlan)383*33de042dSApple OSS Distributions vlan_test_traffic(bool hw_vlan)
384*33de042dSApple OSS Distributions {
385*33de042dSApple OSS Distributions vlan_test_check_skip();
386*33de042dSApple OSS Distributions
387*33de042dSApple OSS Distributions signal(SIGINT, sigint_handler);
388*33de042dSApple OSS Distributions T_ATEND(cleanup);
389*33de042dSApple OSS Distributions T_LOG("VLAN test %s\n",
390*33de042dSApple OSS Distributions hw_vlan ? "hardware tagging" : "software tagging");
391*33de042dSApple OSS Distributions fake_set_bsd_mode(true);
392*33de042dSApple OSS Distributions fake_set_vlan_tagging(hw_vlan);
393*33de042dSApple OSS Distributions initialize_feth_pairs(1, true);
394*33de042dSApple OSS Distributions initialize_vlan_pairs(5, true);
395*33de042dSApple OSS Distributions test_traffic_for_af(AF_INET6);
396*33de042dSApple OSS Distributions test_traffic_for_af(AF_INET);
397*33de042dSApple OSS Distributions if (G_debug) {
398*33de042dSApple OSS Distributions T_LOG("Sleeping for 5 seconds\n");
399*33de042dSApple OSS Distributions sleep(5);
400*33de042dSApple OSS Distributions }
401*33de042dSApple OSS Distributions }
402*33de042dSApple OSS Distributions
403*33de042dSApple OSS Distributions static void
vlan_test_bridged_traffic(bool hw_vlan)404*33de042dSApple OSS Distributions vlan_test_bridged_traffic(bool hw_vlan)
405*33de042dSApple OSS Distributions {
406*33de042dSApple OSS Distributions errno_t err;
407*33de042dSApple OSS Distributions network_interface_pair_t feth_pair;
408*33de042dSApple OSS Distributions network_interface_pair_t vlan_pair;
409*33de042dSApple OSS Distributions
410*33de042dSApple OSS Distributions vlan_test_check_skip();
411*33de042dSApple OSS Distributions
412*33de042dSApple OSS Distributions signal(SIGINT, sigint_handler);
413*33de042dSApple OSS Distributions T_ATEND(cleanup);
414*33de042dSApple OSS Distributions T_LOG("VLAN test bridged %s\n",
415*33de042dSApple OSS Distributions hw_vlan ? "hardware tagging" : "software tagging");
416*33de042dSApple OSS Distributions fake_set_bsd_mode(true);
417*33de042dSApple OSS Distributions fake_set_vlan_tagging(hw_vlan);
418*33de042dSApple OSS Distributions initialize_feth_pairs(2, false);
419*33de042dSApple OSS Distributions initialize_vlan_pairs(1, false);
420*33de042dSApple OSS Distributions
421*33de042dSApple OSS Distributions /* get the single VLAN pair */
422*33de042dSApple OSS Distributions vlan_pair = S_vlan_pairs->list;
423*33de042dSApple OSS Distributions
424*33de042dSApple OSS Distributions /* get the second FETH pair */
425*33de042dSApple OSS Distributions feth_pair = S_feth_pairs->list + 1;
426*33de042dSApple OSS Distributions
427*33de042dSApple OSS Distributions /* create a bridge */
428*33de042dSApple OSS Distributions S_bridge = BRIDGE200;
429*33de042dSApple OSS Distributions err = ifnet_create(S_bridge);
430*33de042dSApple OSS Distributions T_ASSERT_EQ(err, 0, "ifnet_create %s", S_bridge);
431*33de042dSApple OSS Distributions
432*33de042dSApple OSS Distributions /* add first VLAN to bridge */
433*33de042dSApple OSS Distributions err = bridge_add_member(S_bridge, vlan_pair->one.if_name);
434*33de042dSApple OSS Distributions T_ASSERT_EQ(err, 0, "bridge_add_member(%s, %s)", S_bridge,
435*33de042dSApple OSS Distributions vlan_pair->one.if_name);
436*33de042dSApple OSS Distributions
437*33de042dSApple OSS Distributions /* assign address to second VLAN */
438*33de042dSApple OSS Distributions network_interface_assign_address(&vlan_pair->two, 0, 1);
439*33de042dSApple OSS Distributions
440*33de042dSApple OSS Distributions /* add feth in second pair to bridge */
441*33de042dSApple OSS Distributions err = bridge_add_member(S_bridge, feth_pair->one.if_name);
442*33de042dSApple OSS Distributions T_ASSERT_EQ(err, 0, "bridge_add_member(%s, %s)", S_bridge,
443*33de042dSApple OSS Distributions feth_pair->one.if_name);
444*33de042dSApple OSS Distributions
445*33de042dSApple OSS Distributions /* assign address to second feth in second pair */
446*33de042dSApple OSS Distributions network_interface_assign_address(&feth_pair->two, 0, 2);
447*33de042dSApple OSS Distributions
448*33de042dSApple OSS Distributions test_traffic_for_network_interfaces(&vlan_pair->two, &feth_pair->two,
449*33de042dSApple OSS Distributions AF_INET);
450*33de042dSApple OSS Distributions test_traffic_for_network_interfaces(&vlan_pair->two, &feth_pair->two,
451*33de042dSApple OSS Distributions AF_INET6);
452*33de042dSApple OSS Distributions }
453*33de042dSApple OSS Distributions
454*33de042dSApple OSS Distributions static void
vlan_test_short_packet(void)455*33de042dSApple OSS Distributions vlan_test_short_packet(void)
456*33de042dSApple OSS Distributions {
457*33de042dSApple OSS Distributions vlan_test_check_skip();
458*33de042dSApple OSS Distributions
459*33de042dSApple OSS Distributions signal(SIGINT, sigint_handler);
460*33de042dSApple OSS Distributions T_ATEND(cleanup);
461*33de042dSApple OSS Distributions T_LOG("VLAN test short packet\n");
462*33de042dSApple OSS Distributions fake_set_bsd_mode(true);
463*33de042dSApple OSS Distributions fake_set_vlan_tagging(false);
464*33de042dSApple OSS Distributions
465*33de042dSApple OSS Distributions initialize_feth_pairs(1, true);
466*33de042dSApple OSS Distributions initialize_vlan_pairs(1, true);
467*33de042dSApple OSS Distributions /* send VLAN packet over feth */
468*33de042dSApple OSS Distributions vlan_send_short_packet();
469*33de042dSApple OSS Distributions if (G_debug) {
470*33de042dSApple OSS Distributions T_LOG("Sleeping for 5 seconds\n");
471*33de042dSApple OSS Distributions sleep(5);
472*33de042dSApple OSS Distributions }
473*33de042dSApple OSS Distributions }
474*33de042dSApple OSS Distributions
475*33de042dSApple OSS Distributions T_DECL(net_if_vlan_test_software_tagging,
476*33de042dSApple OSS Distributions "vlan test traffic software tagging",
477*33de042dSApple OSS Distributions T_META_ASROOT(true))
478*33de042dSApple OSS Distributions {
479*33de042dSApple OSS Distributions vlan_test_traffic(false);
480*33de042dSApple OSS Distributions }
481*33de042dSApple OSS Distributions
482*33de042dSApple OSS Distributions T_DECL(net_if_vlan_test_hardware_tagging,
483*33de042dSApple OSS Distributions "vlan test hardware tagging",
484*33de042dSApple OSS Distributions T_META_ASROOT(true))
485*33de042dSApple OSS Distributions {
486*33de042dSApple OSS Distributions vlan_test_traffic(true);
487*33de042dSApple OSS Distributions }
488*33de042dSApple OSS Distributions
489*33de042dSApple OSS Distributions T_DECL(net_if_vlan_test_software_tagging_bridged,
490*33de042dSApple OSS Distributions "vlan test traffic software tagging bridged",
491*33de042dSApple OSS Distributions T_META_ASROOT(true))
492*33de042dSApple OSS Distributions {
493*33de042dSApple OSS Distributions vlan_test_bridged_traffic(false);
494*33de042dSApple OSS Distributions }
495*33de042dSApple OSS Distributions
496*33de042dSApple OSS Distributions T_DECL(net_if_vlan_test_hardware_tagging_bridged,
497*33de042dSApple OSS Distributions "vlan test hardware tagging bridged",
498*33de042dSApple OSS Distributions T_META_ASROOT(true))
499*33de042dSApple OSS Distributions {
500*33de042dSApple OSS Distributions vlan_test_bridged_traffic(true);
501*33de042dSApple OSS Distributions }
502*33de042dSApple OSS Distributions
503*33de042dSApple OSS Distributions T_DECL(net_if_vlan_test_short_packet,
504*33de042dSApple OSS Distributions "vlan test short packet",
505*33de042dSApple OSS Distributions T_META_ASROOT(true))
506*33de042dSApple OSS Distributions {
507*33de042dSApple OSS Distributions vlan_test_short_packet();
508*33de042dSApple OSS Distributions }
509