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