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 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 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 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 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 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