1 /* main.c - Application main entry point */
2
3 /*
4 * Copyright (c) 2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_test, CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL);
11
12 #include <zephyr/ztest.h>
13 #include <zephyr/types.h>
14 #include <stddef.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <errno.h>
18 #include <zephyr/device.h>
19 #include <zephyr/init.h>
20 #include <zephyr/sys/printk.h>
21 #include <zephyr/net/net_core.h>
22 #include <zephyr/net/net_ip.h>
23 #include <zephyr/net/ethernet.h>
24 #include <zephyr/linker/sections.h>
25
26 #include "nbr.h"
27
28 #define NET_LOG_ENABLED 1
29 #include "net_private.h"
30
31 static int remove_count, add_count, clear_called;
32
net_neighbor_data_remove(struct net_nbr * nbr)33 static void net_neighbor_data_remove(struct net_nbr *nbr)
34 {
35 printk("Neighbor %p removed\n", nbr);
36
37 remove_count++;
38 }
39
net_neighbor_table_clear(struct net_nbr_table * table)40 static void net_neighbor_table_clear(struct net_nbr_table *table)
41 {
42 printk("Neighbor table %p cleared\n", table);
43
44 clear_called = true;
45 }
46
47 NET_NBR_POOL_INIT(net_test_neighbor_pool, CONFIG_NET_IPV6_MAX_NEIGHBORS,
48 0, net_neighbor_data_remove);
49
50 NET_NBR_TABLE_INIT(NET_NBR_LOCAL, test_neighbor, net_test_neighbor_pool,
51 net_neighbor_table_clear);
52
53
54 static struct net_eth_addr hwaddr1 = { { 0x42, 0x11, 0x69, 0xde, 0xfa, 0x01 } };
55 static struct net_eth_addr hwaddr2 = { { 0x5f, 0x1c, 0x04, 0xae, 0x99, 0x02 } };
56 static struct net_eth_addr hwaddr3 = { { 0xee, 0xe1, 0x55, 0xfe, 0x44, 0x03 } };
57 static struct net_eth_addr hwaddr4 = { { 0x61, 0xf2, 0xfe, 0x4e, 0x8e, 0x04 } };
58 static struct net_eth_addr hwaddr5 = { { 0x8a, 0x52, 0x01, 0x21, 0x11, 0x05 } };
59
ZTEST(neighbor_test_suite,test_neighbor)60 ZTEST(neighbor_test_suite, test_neighbor)
61 {
62 struct net_eth_addr *addrs[] = {
63 &hwaddr1,
64 &hwaddr2,
65 &hwaddr3,
66 &hwaddr4,
67 &hwaddr5,
68 NULL
69 };
70 struct net_nbr *nbrs[sizeof(addrs) - 1] = { 0 };
71 struct net_eth_addr *eth_addr;
72
73 struct net_nbr *nbr;
74 struct net_linkaddr lladdr;
75 struct net_linkaddr_storage *lladdr_ptr;
76 struct net_if *iface1 = INT_TO_POINTER(1);
77 struct net_if *iface2 = INT_TO_POINTER(2);
78 int ret, i;
79
80 zassert_true(CONFIG_NET_IPV6_MAX_NEIGHBORS == (ARRAY_SIZE(addrs) - 2),
81 "There should be exactly %d valid entries in addrs array\n",
82 CONFIG_NET_IPV6_MAX_NEIGHBORS + 1);
83
84 /* First adding a neighbor and trying to add multiple hw addresses
85 * to it. Only the first one should succeed.
86 */
87 nbr = net_nbr_get(&net_test_neighbor.table);
88 zassert_not_null(nbr, "Cannot get neighbor from table %p\n",
89 &net_test_neighbor.table);
90
91 zassert_false(nbr->ref != 1, "Invalid ref count %d\n", nbr->ref);
92
93 lladdr.len = sizeof(struct net_eth_addr);
94
95 for (i = 0; i < 2; i++) {
96 eth_addr = addrs[i];
97
98 lladdr.addr = eth_addr->addr;
99
100 ret = net_nbr_link(nbr, iface1, &lladdr);
101
102 /* One neighbor can have only one lladdr */
103 zassert_false(i == 0 && ret < 0, "Cannot add %s to nbr cache (%d)\n",
104 net_sprint_ll_addr(lladdr.addr, lladdr.len),
105 ret);
106
107 if (!ret) {
108 printk("Adding %s\n",
109 net_sprint_ll_addr(eth_addr->addr,
110 sizeof(struct net_eth_addr)));
111 }
112 }
113
114 lladdr.addr = addrs[0]->addr;
115 nbr = net_nbr_lookup(&net_test_neighbor.table, iface1, &lladdr);
116 zassert_true(nbr->idx == 0, "Wrong index %d should be %d\n", nbr->idx, 0);
117
118 for (i = 0; i < 2; i++) {
119 eth_addr = addrs[i];
120
121 lladdr.addr = eth_addr->addr;
122
123 ret = net_nbr_unlink(nbr, &lladdr);
124 zassert_false(i == 0 && ret < 0, "Cannot add %s to nbr cache (%d)\n",
125 net_sprint_ll_addr(lladdr.addr, lladdr.len),
126 ret);
127 if (!ret) {
128 printk("Deleting %s\n",
129 net_sprint_ll_addr(eth_addr->addr,
130 sizeof(struct net_eth_addr)));
131 }
132 }
133
134 net_nbr_unref(nbr);
135 zassert_false(nbr->ref != 0, "nbr still referenced, ref %d\n",
136 nbr->ref);
137
138 /* Then adding multiple neighbors.
139 */
140 lladdr.len = sizeof(struct net_eth_addr);
141
142 for (i = 0; i < ARRAY_SIZE(addrs); i++) {
143 nbr = net_nbr_get(&net_test_neighbor.table);
144 if (!nbr) {
145 if (i >= CONFIG_NET_IPV6_MAX_NEIGHBORS) {
146 /* Ok, last entry will not fit cache */
147 break;
148 }
149 zassert_true(1, "[%d] Cannot get neighbor from table %p\n",
150 i, &net_test_neighbor.table);
151 }
152
153 zassert_true(nbr->ref == 1, "[%d] Invalid ref count %d\n", i, nbr->ref);
154 nbrs[i] = nbr;
155
156 eth_addr = addrs[i];
157
158 lladdr.addr = eth_addr->addr;
159
160 ret = net_nbr_link(nbr, iface1, &lladdr);
161 zassert_false(ret < 0, "Cannot add %s to nbr cache (%d)\n",
162 net_sprint_ll_addr(lladdr.addr, lladdr.len),
163 ret);
164 printk("Adding %s\n", net_sprint_ll_addr(eth_addr->addr,
165 sizeof(struct net_eth_addr)));
166 }
167
168 for (i = 0; i < ARRAY_SIZE(addrs) - 2; i++) {
169 lladdr.addr = addrs[i]->addr;
170 nbr = net_nbr_lookup(&net_test_neighbor.table, iface1, &lladdr);
171 zassert_false(nbr->idx != i, "Wrong index %d should be %d\n", nbr->idx, i);
172 }
173
174 for (i = 0; i < ARRAY_SIZE(addrs); i++) {
175 eth_addr = addrs[i];
176 nbr = nbrs[i];
177 lladdr.addr = eth_addr->addr;
178
179 if (!nbr || i >= CONFIG_NET_IPV6_MAX_NEIGHBORS) {
180 break;
181 }
182
183 ret = net_nbr_unlink(nbr, &lladdr);
184 zassert_false(ret < 0, "Cannot del %s from nbr cache (%d)\n",
185 net_sprint_ll_addr(lladdr.addr, lladdr.len),
186 ret);
187 printk("Deleting %s\n", net_sprint_ll_addr(eth_addr->addr,
188 sizeof(struct net_eth_addr)));
189
190 net_nbr_unref(nbr);
191 zassert_false(nbr->ref != 0, "nbr still referenced, ref %d\n",
192 nbr->ref);
193 }
194
195 /* Then adding multiple neighbors but some of them in different
196 * interface.
197 */
198 lladdr.len = sizeof(struct net_eth_addr);
199 remove_count = add_count = 0;
200
201 for (i = 0; i < ARRAY_SIZE(addrs); i++) {
202 nbr = net_nbr_get(&net_test_neighbor.table);
203 if (!nbr) {
204 if (i >= CONFIG_NET_IPV6_MAX_NEIGHBORS) {
205 /* Ok, last entry will not fit cache */
206 break;
207 }
208 zassert_true(1, "[%d] Cannot get neighbor from table %p\n",
209 i, &net_test_neighbor.table);
210 }
211
212 zassert_false(nbr->ref != 1, "[%d] Invalid ref count %d\n", i, nbr->ref);
213 nbrs[i] = nbr;
214
215 eth_addr = addrs[i];
216
217 lladdr.addr = eth_addr->addr;
218
219 if (i % 2) {
220 ret = net_nbr_link(nbr, iface1, &lladdr);
221 } else {
222 ret = net_nbr_link(nbr, iface2, &lladdr);
223 }
224 zassert_false(ret < 0, "Cannot add %s to nbr cache (%d)\n",
225 net_sprint_ll_addr(lladdr.addr, lladdr.len),
226 ret);
227 printk("Adding %s iface %p\n",
228 net_sprint_ll_addr(eth_addr->addr,
229 sizeof(struct net_eth_addr)),
230 nbr->iface);
231 add_count++;
232 }
233
234 for (i = 0; i < ARRAY_SIZE(addrs) - 2; i++) {
235 lladdr.addr = addrs[i]->addr;
236 if (i % 2) {
237 nbr = net_nbr_lookup(&net_test_neighbor.table, iface1,
238 &lladdr);
239 } else {
240 nbr = net_nbr_lookup(&net_test_neighbor.table, iface2,
241 &lladdr);
242 }
243 zassert_false(nbr->idx != i, "Wrong index %d should be %d\n", nbr->idx, i);
244
245 lladdr_ptr = net_nbr_get_lladdr(i);
246 if (memcmp(lladdr_ptr->addr, addrs[i]->addr,
247 sizeof(struct net_eth_addr))) {
248 zassert_true(1, "Wrong lladdr %s in index %d\n",
249 net_sprint_ll_addr(lladdr_ptr->addr,
250 lladdr_ptr->len),
251 i);
252 }
253 }
254
255 for (i = 0; i < ARRAY_SIZE(addrs); i++) {
256 struct net_if *iface;
257
258 eth_addr = addrs[i];
259 nbr = nbrs[i];
260 lladdr.addr = eth_addr->addr;
261
262 if (!nbr || i >= CONFIG_NET_IPV6_MAX_NEIGHBORS) {
263 break;
264 }
265
266 iface = nbr->iface;
267
268 ret = net_nbr_unlink(nbr, &lladdr);
269 zassert_false(ret < 0, "Cannot del %s from nbr cache (%d)\n",
270 net_sprint_ll_addr(lladdr.addr, lladdr.len),
271 ret);
272
273 printk("Deleting %s iface %p\n", net_sprint_ll_addr(eth_addr->addr,
274 sizeof(struct net_eth_addr)), iface);
275
276 net_nbr_unref(nbr);
277 zassert_false(nbr->ref != 0, "nbr still referenced, ref %d\n", nbr->ref);
278 }
279
280 zassert_false(add_count != remove_count, "Remove count %d does not match add count %d\n",
281 remove_count, add_count);
282
283 net_nbr_clear_table(&net_test_neighbor.table);
284
285 zassert_true(clear_called, "Table clear check failed");
286
287 /* The table should be empty now */
288 lladdr.addr = addrs[0]->addr;
289 nbr = net_nbr_lookup(&net_test_neighbor.table, iface1, &lladdr);
290
291 zassert_is_null(nbr, "Some entries still found in nbr cache");
292
293 return;
294 }
295
setup(void)296 void *setup(void)
297 {
298 if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) {
299 k_thread_priority_set(k_current_get(),
300 K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1));
301 } else {
302 k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9));
303 }
304 return NULL;
305 }
306
307 /*test case main entry*/
308 ZTEST_SUITE(neighbor_test_suite, NULL, setup, NULL, NULL, NULL);
309