1 #include "test_netif.h"
2
3 #include "lwip/netif.h"
4 #include "lwip/stats.h"
5 #include "lwip/etharp.h"
6 #include "netif/ethernet.h"
7
8 #if !LWIP_NETIF_EXT_STATUS_CALLBACK
9 #error "This tests needs LWIP_NETIF_EXT_STATUS_CALLBACK enabled"
10 #endif
11
12 static struct netif net_test;
13
14
15 /* Setups/teardown functions */
16
17 static void
netif_setup(void)18 netif_setup(void)
19 {
20 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
21 }
22
23 static void
netif_teardown(void)24 netif_teardown(void)
25 {
26 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
27 }
28
29 /* test helper functions */
30
31 static err_t
testif_tx_func(struct netif * netif,struct pbuf * p)32 testif_tx_func(struct netif *netif, struct pbuf *p)
33 {
34 LWIP_UNUSED_ARG(netif);
35 LWIP_UNUSED_ARG(p);
36 return ERR_OK;
37 }
38
39 static err_t
testif_init(struct netif * netif)40 testif_init(struct netif *netif)
41 {
42 netif->name[0] = 'c';
43 netif->name[1] = 'h';
44 netif->output = etharp_output;
45 netif->linkoutput = testif_tx_func;
46 netif->mtu = 1500;
47 netif->hwaddr_len = 6;
48 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
49
50 netif->hwaddr[0] = 0x02;
51 netif->hwaddr[1] = 0x03;
52 netif->hwaddr[2] = 0x04;
53 netif->hwaddr[3] = 0x05;
54 netif->hwaddr[4] = 0x06;
55 netif->hwaddr[5] = 0x07;
56
57 return ERR_OK;
58 }
59
60 #define MAX_NSC_REASON_IDX 10
61 static netif_nsc_reason_t expected_reasons;
62 static int callback_ctr;
63
64 static int dummy_active;
65
66 static void
test_netif_ext_callback_dummy(struct netif * netif,netif_nsc_reason_t reason,const netif_ext_callback_args_t * args)67 test_netif_ext_callback_dummy(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
68 {
69 LWIP_UNUSED_ARG(netif);
70 LWIP_UNUSED_ARG(reason);
71 LWIP_UNUSED_ARG(args);
72
73 fail_unless(dummy_active);
74 }
75
76 static void
test_netif_ext_callback(struct netif * netif,netif_nsc_reason_t reason,const netif_ext_callback_args_t * args)77 test_netif_ext_callback(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
78 {
79 LWIP_UNUSED_ARG(args); /* @todo */
80 callback_ctr++;
81
82 fail_unless(netif == &net_test);
83
84 fail_unless(expected_reasons == reason);
85 }
86
87 /* Test functions */
88
89 NETIF_DECLARE_EXT_CALLBACK(netif_callback_1)
NETIF_DECLARE_EXT_CALLBACK(netif_callback_2)90 NETIF_DECLARE_EXT_CALLBACK(netif_callback_2)
91 NETIF_DECLARE_EXT_CALLBACK(netif_callback_3)
92
93 START_TEST(test_netif_extcallbacks)
94 {
95 ip4_addr_t addr;
96 ip4_addr_t netmask;
97 ip4_addr_t gw;
98 LWIP_UNUSED_ARG(_i);
99
100 IP4_ADDR(&addr, 0, 0, 0, 0);
101 IP4_ADDR(&netmask, 0, 0, 0, 0);
102 IP4_ADDR(&gw, 0, 0, 0, 0);
103
104 netif_add_ext_callback(&netif_callback_3, test_netif_ext_callback_dummy);
105 netif_add_ext_callback(&netif_callback_2, test_netif_ext_callback);
106 netif_add_ext_callback(&netif_callback_1, test_netif_ext_callback_dummy);
107
108 dummy_active = 1;
109
110 /* positive tests: check that single events come as expected */
111
112 expected_reasons = LWIP_NSC_NETIF_ADDED;
113 callback_ctr = 0;
114 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
115 fail_unless(callback_ctr == 1);
116
117 expected_reasons = LWIP_NSC_LINK_CHANGED;
118 callback_ctr = 0;
119 netif_set_link_up(&net_test);
120 fail_unless(callback_ctr == 1);
121
122 expected_reasons = LWIP_NSC_STATUS_CHANGED;
123 callback_ctr = 0;
124 netif_set_up(&net_test);
125 fail_unless(callback_ctr == 1);
126
127 IP4_ADDR(&addr, 1, 2, 3, 4);
128 expected_reasons = LWIP_NSC_IPV4_ADDRESS_CHANGED;
129 callback_ctr = 0;
130 netif_set_ipaddr(&net_test, &addr);
131 fail_unless(callback_ctr == 1);
132
133 IP4_ADDR(&netmask, 255, 255, 255, 0);
134 expected_reasons = LWIP_NSC_IPV4_NETMASK_CHANGED;
135 callback_ctr = 0;
136 netif_set_netmask(&net_test, &netmask);
137 fail_unless(callback_ctr == 1);
138
139 IP4_ADDR(&gw, 1, 2, 3, 254);
140 expected_reasons = LWIP_NSC_IPV4_GATEWAY_CHANGED;
141 callback_ctr = 0;
142 netif_set_gw(&net_test, &gw);
143 fail_unless(callback_ctr == 1);
144
145 IP4_ADDR(&addr, 0, 0, 0, 0);
146 expected_reasons = LWIP_NSC_IPV4_ADDRESS_CHANGED;
147 callback_ctr = 0;
148 netif_set_ipaddr(&net_test, &addr);
149 fail_unless(callback_ctr == 1);
150
151 IP4_ADDR(&netmask, 0, 0, 0, 0);
152 expected_reasons = LWIP_NSC_IPV4_NETMASK_CHANGED;
153 callback_ctr = 0;
154 netif_set_netmask(&net_test, &netmask);
155 fail_unless(callback_ctr == 1);
156
157 IP4_ADDR(&gw, 0, 0, 0, 0);
158 expected_reasons = LWIP_NSC_IPV4_GATEWAY_CHANGED;
159 callback_ctr = 0;
160 netif_set_gw(&net_test, &gw);
161 fail_unless(callback_ctr == 1);
162
163 /* check for multi-events (only one combined callback expected) */
164
165 IP4_ADDR(&addr, 1, 2, 3, 4);
166 IP4_ADDR(&netmask, 255, 255, 255, 0);
167 IP4_ADDR(&gw, 1, 2, 3, 254);
168 expected_reasons = (netif_nsc_reason_t)(LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED |
169 LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_SETTINGS_CHANGED |
170 LWIP_NSC_IPV4_ADDR_VALID);
171 callback_ctr = 0;
172 netif_set_addr(&net_test, &addr, &netmask, &gw);
173 fail_unless(callback_ctr == 1);
174
175 /* check that for no-change, no callback is expected */
176 expected_reasons = LWIP_NSC_NONE;
177 callback_ctr = 0;
178 netif_set_ipaddr(&net_test, &addr);
179 fail_unless(callback_ctr == 0);
180
181 netif_set_netmask(&net_test, &netmask);
182 callback_ctr = 0;
183 fail_unless(callback_ctr == 0);
184
185 callback_ctr = 0;
186 netif_set_gw(&net_test, &gw);
187 fail_unless(callback_ctr == 0);
188
189 /* netif_set_addr() always issues at least LWIP_NSC_IPV4_ADDR_VALID */
190 expected_reasons = LWIP_NSC_IPV4_ADDR_VALID;
191 callback_ctr = 0;
192 netif_set_addr(&net_test, &addr, &netmask, &gw);
193 fail_unless(callback_ctr == 1);
194
195 /* check for single-events */
196 IP4_ADDR(&addr, 1, 2, 3, 5);
197 expected_reasons = (netif_nsc_reason_t)(LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_SETTINGS_CHANGED |
198 LWIP_NSC_IPV4_ADDR_VALID);
199 callback_ctr = 0;
200 netif_set_addr(&net_test, &addr, &netmask, &gw);
201 fail_unless(callback_ctr == 1);
202
203 expected_reasons = LWIP_NSC_STATUS_CHANGED;
204 callback_ctr = 0;
205 netif_set_down(&net_test);
206 fail_unless(callback_ctr == 1);
207
208 expected_reasons = LWIP_NSC_NETIF_REMOVED;
209 callback_ctr = 0;
210 netif_remove(&net_test);
211 fail_unless(callback_ctr == 1);
212
213 expected_reasons = LWIP_NSC_NONE;
214
215 netif_remove_ext_callback(&netif_callback_2);
216 netif_remove_ext_callback(&netif_callback_3);
217 netif_remove_ext_callback(&netif_callback_1);
218 dummy_active = 0;
219 }
220 END_TEST
221
START_TEST(test_netif_flag_set)222 START_TEST(test_netif_flag_set)
223 {
224 ip4_addr_t addr;
225 ip4_addr_t netmask;
226 ip4_addr_t gw;
227 LWIP_UNUSED_ARG(_i);
228
229 IP4_ADDR(&addr, 0, 0, 0, 0);
230 IP4_ADDR(&netmask, 0, 0, 0, 0);
231 IP4_ADDR(&gw, 0, 0, 0, 0);
232
233 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
234
235 fail_if(netif_is_flag_set(&net_test, NETIF_FLAG_UP));
236 fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_BROADCAST));
237 fail_if(netif_is_flag_set(&net_test, NETIF_FLAG_LINK_UP));
238 fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_ETHARP));
239 fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_ETHERNET));
240 fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_IGMP));
241 fail_unless(netif_is_flag_set(&net_test, NETIF_FLAG_MLD6));
242
243 netif_remove(&net_test);
244 }
245 END_TEST
246
START_TEST(test_netif_find)247 START_TEST(test_netif_find)
248 {
249 struct netif net0;
250 struct netif net1;
251 LWIP_UNUSED_ARG(_i);
252
253 /* No netifs available */
254 fail_unless(netif_find("ch0") == NULL);
255
256 /* Add netifs with known names */
257 fail_unless(netif_add_noaddr(&net0, NULL, testif_init, ethernet_input) == &net0);
258 net0.num = 0;
259 fail_unless(netif_add_noaddr(&net1, NULL, testif_init, ethernet_input) == &net1);
260 net1.num = 1;
261
262 fail_unless(netif_find("ch0") == &net0);
263 fail_unless(netif_find("CH0") == NULL);
264 fail_unless(netif_find("ch1") == &net1);
265 fail_unless(netif_find("ch3") == NULL);
266 /* atoi failure is not treated as zero */
267 fail_unless(netif_find("chX") == NULL);
268 fail_unless(netif_find("ab0") == NULL);
269
270 netif_remove(&net0);
271 netif_remove(&net1);
272 }
273 END_TEST
274
275 /** Create the suite including all tests for this module */
276 Suite *
netif_suite(void)277 netif_suite(void)
278 {
279 testfunc tests[] = {
280 TESTFUNC(test_netif_extcallbacks),
281 TESTFUNC(test_netif_flag_set),
282 TESTFUNC(test_netif_find)
283 };
284 return create_suite("NETIF", tests, sizeof(tests)/sizeof(testfunc), netif_setup, netif_teardown);
285 }
286