xref: /dpdk/app/test/test_net_ether.c (revision 719b37dd5676b7204cb16d204d8762a92d3b1ecd)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2023 Stephen Hemminger
3  */
4 
5 #include <rte_ether.h>
6 
7 #include <rte_test.h>
8 #include "test.h"
9 
10 #define N 1000000
11 
12 static const struct rte_ether_addr zero_ea;
13 static const struct rte_ether_addr bcast_ea = {
14 	.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
15 };
16 
17 static int
test_ether_addr(void)18 test_ether_addr(void)
19 {
20 	struct rte_ether_addr rand_ea = { };
21 	unsigned int i;
22 
23 	RTE_TEST_ASSERT(rte_is_zero_ether_addr(&zero_ea), "Zero address is not zero");
24 	RTE_TEST_ASSERT(!rte_is_zero_ether_addr(&bcast_ea), "Broadcast is zero");
25 
26 	for (i = 0; i < N; i++) {
27 		rte_eth_random_addr(rand_ea.addr_bytes);
28 		RTE_TEST_ASSERT(!rte_is_zero_ether_addr(&rand_ea),
29 				"Random address is zero");
30 		RTE_TEST_ASSERT(rte_is_unicast_ether_addr(&rand_ea),
31 				"Random address is not unicast");
32 		RTE_TEST_ASSERT(rte_is_local_admin_ether_addr(&rand_ea),
33 				"Random address is not local admin");
34 	}
35 
36 	return 0;
37 }
38 
39 static int
test_format_addr(void)40 test_format_addr(void)
41 {
42 	struct rte_ether_addr rand_ea = { };
43 	char buf[RTE_ETHER_ADDR_FMT_SIZE];
44 	unsigned int i;
45 
46 	for (i = 0; i < N; i++) {
47 		struct rte_ether_addr result = { };
48 		int ret;
49 
50 		rte_eth_random_addr(rand_ea.addr_bytes);
51 
52 		rte_ether_format_addr(buf, sizeof(buf), &rand_ea);
53 
54 		ret = rte_ether_unformat_addr(buf, &result);
55 		if (ret != 0) {
56 			fprintf(stderr, "rte_ether_unformat_addr(%s) failed\n", buf);
57 			return -1;
58 		}
59 		RTE_TEST_ASSERT(rte_is_same_ether_addr(&rand_ea, &result),
60 			"rte_ether_format/unformat mismatch");
61 	}
62 	return 0;
63 
64 }
65 
66 static int
test_unformat_addr(void)67 test_unformat_addr(void)
68 {
69 	const struct rte_ether_addr expected = {
70 		.addr_bytes = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc },
71 	};
72 	const struct rte_ether_addr nozero_ea = {
73 		.addr_bytes = { 1, 2, 3, 4, 5, 6 },
74 	};
75 	struct rte_ether_addr result;
76 	int ret;
77 
78 	/* Test IETF format */
79 	memset(&result, 0, sizeof(result));
80 	ret = rte_ether_unformat_addr("12:34:56:78:9a:bc", &result);
81 	RTE_TEST_ASSERT(ret == 0, "IETF unformat failed");
82 	RTE_TEST_ASSERT(rte_is_same_ether_addr(&expected, &result),
83 		"IETF unformat mismatch");
84 
85 	/* Test IEEE format */
86 	memset(&result, 0, sizeof(result));
87 	ret = rte_ether_unformat_addr("12-34-56-78-9A-BC", &result);
88 	RTE_TEST_ASSERT(ret == 0, "IEEE unformat failed");
89 	RTE_TEST_ASSERT(rte_is_same_ether_addr(&expected, &result),
90 			"IEEE unformat mismatch");
91 
92 	/* Test Cisco format */
93 	memset(&result, 0, sizeof(result));
94 	ret = rte_ether_unformat_addr("1234.5678.9ABC", &result);
95 	RTE_TEST_ASSERT(ret == 0, "Cisco unformat failed");
96 	RTE_TEST_ASSERT(rte_is_same_ether_addr(&expected, &result),
97 			"Cisco unformat mismatch");
98 
99 	/* Test no leading zeros - IETF */
100 	memset(&result, 0, sizeof(result));
101 	ret = rte_ether_unformat_addr("1:2:3:4:5:6", &result);
102 	RTE_TEST_ASSERT(ret == 0, "IETF leading zero failed");
103 	RTE_TEST_ASSERT(rte_is_same_ether_addr(&nozero_ea, &result),
104 			"IETF leading zero mismatch");
105 
106 	/* Test no-leading zero - IEEE format */
107 	memset(&result, 0, sizeof(result));
108 	ret = rte_ether_unformat_addr("1-2-3-4-5-6", &result);
109 	RTE_TEST_ASSERT(ret == 0, "IEEE leading zero failed");
110 	RTE_TEST_ASSERT(rte_is_same_ether_addr(&nozero_ea, &result),
111 			"IEEE leading zero mismatch");
112 
113 
114 	return 0;
115 }
116 
117 static int
test_invalid_addr(void)118 test_invalid_addr(void)
119 {
120 	static const char * const invalid[] = {
121 		"123",
122 		"123:456",
123 		"12:34:56:78:9a:gh",
124 		"12:34:56:78:9a",
125 		"100:34:56:78:9a:bc",
126 		"34-56-78-9a-bc",
127 		"12:34:56-78:9a:bc",
128 		"12:34:56.78:9a:bc",
129 		"123:456:789:abc",
130 		"NOT.AN.ADDRESS",
131 		"102.304.506",
132 		"",
133 	};
134 	struct rte_ether_addr result;
135 	unsigned int i;
136 
137 	for (i = 0; i < RTE_DIM(invalid); ++i) {
138 		if (!rte_ether_unformat_addr(invalid[i], &result)) {
139 			fprintf(stderr, "rte_ether_unformat_addr(%s) succeeded!\n",
140 				invalid[i]);
141 			return -1;
142 		}
143 	}
144 	return 0;
145 }
146 
147 static int
test_net_ether(void)148 test_net_ether(void)
149 {
150 	if (test_ether_addr())
151 		return -1;
152 
153 	if (test_format_addr())
154 		return -1;
155 
156 	if (test_unformat_addr())
157 		return -1;
158 
159 	if (test_invalid_addr())
160 		return -1;
161 
162 	return 0;
163 }
164 
165 REGISTER_FAST_TEST(net_ether_autotest, true, true, test_net_ether);
166