1 /**
2 * @file
3 * Network Interface Sequential API module
4 *
5 * @defgroup netifapi NETIF API
6 * @ingroup sequential_api
7 * Thread-safe functions to be called from non-TCPIP threads
8 *
9 * @defgroup netifapi_netif NETIF related
10 * @ingroup netifapi
11 * To be called from non-TCPIP threads
12 */
13
14 /*
15 * Redistribution and use in source and binary forms, with or without modification,
16 * are permitted provided that the following conditions are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright notice,
19 * this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
29 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
31 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 * OF SUCH DAMAGE.
36 *
37 * This file is part of the lwIP TCP/IP stack.
38 *
39 */
40
41 /**********************************************************************************
42 * Notice of Export Control Law
43 * ===============================================
44 * LiteOS may be subject to applicable export control laws and regulations, which
45 * might include those applicable to LiteOS of U.S. and the country in which you
46 * are located.
47 * Import, export and usage of LiteOS in any manner by you shall be in compliance
48 * with such applicable export control laws and regulations.
49 **********************************************************************************/
50
51 #include "lwip/opt.h"
52
53 #if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
54
55 #include "lwip/etharp.h"
56 #include "lwip/netifapi.h"
57 #include "lwip/memp.h"
58 #include "lwip/priv/tcpip_priv.h"
59 #include "lwip/mld6.h"
60 #include "lwip/dhcp.h"
61 #include "lwip/dhcp6.h"
62 #include "lwip/if_api.h"
63 #include "lwip/nd6.h"
64
65 #include <string.h> /* strncpy */
66
67 #define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
68 #define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
69 #define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
70 #define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
71
72 #if LWIP_MPU_COMPATIBLE
netifapi_msg_alloc(struct netifapi_msg ** name)73 static inline err_t netifapi_msg_alloc(struct netifapi_msg **name)
74 {
75 API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, (*name), ERR_MEM);
76 LWIP_UNUSED_ARG(name);
77 return ERR_OK;
78 }
79 #else
netifapi_msg_alloc(struct netifapi_msg * name)80 static inline err_t netifapi_msg_alloc(struct netifapi_msg *name)
81 {
82 LWIP_UNUSED_ARG(name);
83 return ERR_OK;
84 }
85 #endif
86
87 #if LWIP_DHCP_VENDOR_CLASS_IDENTIFIER
88 static err_t do_netifapi_set_vci(struct tcpip_api_call_data *m);
89 err_t netifapi_set_vci(char *vci, u8_t vci_len);
90 static err_t do_netifapi_get_vci(struct tcpip_api_call_data *m);
91 err_t netifapi_get_vci(char *vci, u8_t *vci_len);
92 #endif /* LWIP_DHCP_VENDOR_CLASS_IDENTIFIER */
93
94 /**
95 * Call netif_add() inside the tcpip_thread context.
96 */
97 static err_t
netifapi_do_netif_add(struct tcpip_api_call_data * m)98 netifapi_do_netif_add(struct tcpip_api_call_data *m)
99 {
100 /* cast through void* to silence alignment warnings.
101 * We know it works because the structs have been instantiated as struct netifapi_msg */
102 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
103
104 if (!netif_add(msg->netif
105 #if LWIP_IPV4
106 , API_EXPR_REF(msg->msg.add.ipaddr),
107 API_EXPR_REF(msg->msg.add.netmask),
108 API_EXPR_REF(msg->msg.add.gw)
109 #endif /* LWIP_IPV4 */
110 )) {
111 return ERR_IF;
112 } else {
113 return ERR_OK;
114 }
115 }
116
117 #if LWIP_IPV4
118 /**
119 * Call netif_set_addr() inside the tcpip_thread context.
120 */
121 static err_t
netifapi_do_netif_set_addr(struct tcpip_api_call_data * m)122 netifapi_do_netif_set_addr(struct tcpip_api_call_data *m)
123 {
124 /* cast through void* to silence alignment warnings.
125 * We know it works because the structs have been instantiated as struct netifapi_msg */
126 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
127
128 return netif_set_addr(msg->netif,
129 API_EXPR_REF(msg->msg.add.ipaddr),
130 API_EXPR_REF(msg->msg.add.netmask),
131 API_EXPR_REF(msg->msg.add.gw));
132 }
133
134 /**
135 * Call netif_get_addr() inside the tcpip_thread context.
136 */
137 static err_t
netifapi_do_netif_get_addr(struct tcpip_api_call_data * m)138 netifapi_do_netif_get_addr(struct tcpip_api_call_data *m)
139 {
140 /* cast through void* to silence alignment warnings.
141 * We know it works because the structs have been instantiated as struct netifapi_msg */
142 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
143
144 return netif_get_addr(msg->netif,
145 msg->msg.add_get.ipaddr,
146 msg->msg.add_get.netmask,
147 msg->msg.add_get.gw);
148 }
149
150 #endif /* LWIP_IPV4 */
151
152 #if DRIVER_STATUS_CHECK
153 err_t
netifapi_wake_queue(struct netif * netif)154 netifapi_wake_queue(struct netif *netif)
155 {
156 return netifapi_netif_common(netif, NULL, netif_wake_queue);
157 }
158
159 err_t
netifapi_stop_queue(struct netif * netif)160 netifapi_stop_queue(struct netif *netif)
161 {
162 return netifapi_netif_common(netif, NULL, netif_stop_queue);
163 }
164 #endif /* DRIVER_STATUS_CHECK */
165
166 /**
167 * Call netif_name_to_index() inside the tcpip_thread context.
168 */
169 static err_t
netifapi_do_name_to_index(struct tcpip_api_call_data * m)170 netifapi_do_name_to_index(struct tcpip_api_call_data *m)
171 {
172 /* cast through void* to silence alignment warnings.
173 * We know it works because the structs have been instantiated as struct netifapi_msg */
174 u8_t index;
175 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
176
177 index = netif_name_to_index(msg->msg.ifs.name);
178 msg->msg.ifs.index = index;
179
180 if (index == NETIF_NO_INDEX) {
181 return ERR_VAL;
182 } else {
183 return ERR_OK;
184 }
185 }
186
187 /**
188 * Call netif_index_to_name() inside the tcpip_thread context.
189 */
190 static err_t
netifapi_do_index_to_name(struct tcpip_api_call_data * m)191 netifapi_do_index_to_name(struct tcpip_api_call_data *m)
192 {
193 /* cast through void* to silence alignment warnings.
194 * We know it works because the structs have been instantiated as struct netifapi_msg */
195 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
196
197 if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) {
198 /* return failure via empty name */
199 msg->msg.ifs.name[0] = '\0';
200 }
201 return ERR_OK;
202 }
203
204 /**
205 * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
206 * tcpip_thread context.
207 */
208 static err_t
netifapi_do_netif_common(struct tcpip_api_call_data * m)209 netifapi_do_netif_common(struct tcpip_api_call_data *m)
210 {
211 /* cast through void* to silence alignment warnings.
212 * We know it works because the structs have been instantiated as struct netifapi_msg */
213 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
214
215 if (msg->msg.common.errtfunc != NULL) {
216 return msg->msg.common.errtfunc(msg->netif);
217 } else {
218 msg->msg.common.voidfunc(msg->netif);
219 return ERR_OK;
220 }
221 }
222
223 #if LWIP_ARP && LWIP_IPV4
224 /**
225 * @ingroup netifapi_arp
226 * Add or update an entry in the ARP cache.
227 * For an update, ipaddr is used to find the cache entry.
228 *
229 * @param ipaddr IPv4 address of cache entry
230 * @param ethaddr hardware address mapped to ipaddr
231 * @param type type of ARP cache entry
232 * @return ERR_OK: entry added/updated, else error from err_t
233 */
234 err_t
netifapi_arp_add(const ip4_addr_t * ipaddr,struct eth_addr * ethaddr,enum netifapi_arp_entry type)235 netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type)
236 {
237 err_t err;
238
239 /* We only support permanent entries currently */
240 LWIP_UNUSED_ARG(type);
241
242 #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
243 LOCK_TCPIP_CORE();
244 err = etharp_add_static_entry(ipaddr, ethaddr);
245 UNLOCK_TCPIP_CORE();
246 #else
247 /* @todo add new vars to struct netifapi_msg and create a 'do' func */
248 LWIP_UNUSED_ARG(ipaddr);
249 LWIP_UNUSED_ARG(ethaddr);
250 err = ERR_VAL;
251 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
252
253 return err;
254 }
255
256 /**
257 * @ingroup netifapi_arp
258 * Remove an entry in the ARP cache identified by ipaddr
259 *
260 * @param ipaddr IPv4 address of cache entry
261 * @param type type of ARP cache entry
262 * @return ERR_OK: entry removed, else error from err_t
263 */
264 err_t
netifapi_arp_remove(const ip4_addr_t * ipaddr,enum netifapi_arp_entry type)265 netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type)
266 {
267 err_t err;
268
269 /* We only support permanent entries currently */
270 LWIP_UNUSED_ARG(type);
271
272 #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
273 LOCK_TCPIP_CORE();
274 err = etharp_remove_static_entry(ipaddr);
275 UNLOCK_TCPIP_CORE();
276 #else
277 /* @todo add new vars to struct netifapi_msg and create a 'do' func */
278 LWIP_UNUSED_ARG(ipaddr);
279 err = ERR_VAL;
280 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
281
282 return err;
283 }
284
285 static err_t
netifapi_do_ip_to_mac(struct tcpip_api_call_data * m)286 netifapi_do_ip_to_mac(struct tcpip_api_call_data *m)
287 {
288 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
289 return etharp_ip_to_mac((const ip4_addr_t *)(msg->msg.arp.ip), msg->msg.arp.mac, msg->msg.arp.maclen);
290 }
291
292 err_t
netifapi_ip_to_mac(const ip4_addr_t * ip,u8_t * mac,u8_t * maclen)293 netifapi_ip_to_mac(const ip4_addr_t *ip, u8_t *mac, u8_t *maclen)
294 {
295 err_t err;
296 NETIFAPI_VAR_DECLARE(msg);
297
298 LWIP_ERROR("netifapi_ip_to_mac : invalid arguments \n", ((ip != NULL)), return ERR_ARG);
299 LWIP_ERROR("netifapi_ip_to_mac : invalid arguments \n", ((mac != NULL)), return ERR_ARG);
300 LWIP_ERROR("netifapi_ip_to_mac : invalid arguments \n", ((maclen != NULL)), return ERR_ARG);
301
302 NETIFAPI_VAR_ALLOC(msg);
303 NETIFAPI_VAR_REF(msg).msg.arp.ip = (ip4_addr_t *)ip;
304 NETIFAPI_VAR_REF(msg).msg.arp.mac = mac;
305 NETIFAPI_VAR_REF(msg).msg.arp.maclen = maclen;
306 err = tcpip_api_call(netifapi_do_ip_to_mac, &API_VAR_REF(msg).call);
307 NETIFAPI_VAR_FREE(msg);
308 return err;
309 }
310
311 #endif /* LWIP_ARP && LWIP_IPV4 */
312
313 /**
314 * @ingroup netifapi_netif
315 * Call netif_add() in a thread-safe way by running that function inside the
316 * tcpip_thread context.
317 *
318 * @note for params @see netif_add()
319 */
320 err_t
netifapi_netif_add(struct netif * netif,const ip4_addr_t * ipaddr,const ip4_addr_t * netmask,const ip4_addr_t * gw)321 netifapi_netif_add(struct netif *netif
322 #if LWIP_IPV4
323 ,const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw
324 #endif /* LWIP_IPV4 */
325 )
326 {
327 err_t err;
328 NETIFAPI_VAR_DECLARE(msg);
329 NETIFAPI_VAR_ALLOC(msg);
330
331 #if LWIP_IPV4
332 if (ipaddr == NULL) {
333 ipaddr = IP4_ADDR_ANY4;
334 }
335 if (netmask == NULL) {
336 netmask = IP4_ADDR_ANY4;
337 }
338 if (gw == NULL) {
339 gw = IP4_ADDR_ANY4;
340 }
341 #endif /* LWIP_IPV4 */
342
343 NETIFAPI_VAR_REF(msg).netif = netif;
344 #if LWIP_IPV4
345 NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
346 NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
347 NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
348 #endif /* LWIP_IPV4 */
349 err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
350 NETIFAPI_VAR_FREE(msg);
351 return err;
352 }
353
354 #ifdef LWIP_TESTBED
355 err_t
netifapi_netif_reset(struct netif * netif)356 netifapi_netif_reset(struct netif *netif)
357 {
358 return netifapi_netif_common(netif, NULL, netif_reset);
359 }
360 #endif
361
362 /**
363 * Call netif_find() inside the tcpip_thread context.
364 */
365 static err_t
do_netifapi_netif_find_by_name(struct tcpip_api_call_data * m)366 do_netifapi_netif_find_by_name(struct tcpip_api_call_data *m)
367 {
368 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
369
370 msg->netif = netif_find(msg->msg.find_by_name.name);
371 return ERR_OK;
372 }
373
374 struct netif*
netifapi_netif_find_by_name(const char * name)375 netifapi_netif_find_by_name(const char *name)
376 {
377 struct netif *netif = NULL;
378 NETIFAPI_VAR_DECLARE(msg);
379 if (netifapi_msg_alloc(&msg) != ERR_OK) {
380 return NULL;
381 }
382
383 NETIFAPI_VAR_REF(msg).netif = NULL;
384 NETIFAPI_VAR_REF(msg).msg.find_by_name.name = name;
385 (void)tcpip_api_call(do_netifapi_netif_find_by_name, &API_VAR_REF(msg).call);
386 netif = NETIFAPI_VAR_REF(msg).netif;
387 NETIFAPI_VAR_FREE(msg);
388 return netif;
389 }
390
391 /**
392 * Call netif_find_by_ifindex() inside the tcpip_thread context.
393 */
394 static err_t
do_netifapi_netif_find_by_ifindex(struct tcpip_api_call_data * m)395 do_netifapi_netif_find_by_ifindex(struct tcpip_api_call_data *m)
396 {
397 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
398
399 msg->netif = netif_find_by_ifindex(msg->msg.find_by_ifindex.ifindex);
400 return ERR_OK;
401 }
402
403 struct netif*
netifapi_netif_find_by_ifindex(unsigned ifindex)404 netifapi_netif_find_by_ifindex(unsigned ifindex)
405 {
406 struct netif *netif = NULL;
407 NETIFAPI_VAR_DECLARE(msg);
408 if (netifapi_msg_alloc(&msg) != ERR_OK) {
409 return NULL;
410 }
411
412 NETIFAPI_VAR_REF(msg).netif = NULL;
413 NETIFAPI_VAR_REF(msg).msg.find_by_ifindex.ifindex = (u8_t)ifindex;
414 (void)tcpip_api_call(do_netifapi_netif_find_by_ifindex, &API_VAR_REF(msg).call);
415 netif = NETIFAPI_VAR_REF(msg).netif;
416 NETIFAPI_VAR_FREE(msg);
417 return netif;
418 }
419
420 /**
421 * Call netif_find_by_ipaddr() inside the tcpip_thread context.
422 */
423 static err_t
do_netifapi_netif_find_by_ipaddr(struct tcpip_api_call_data * m)424 do_netifapi_netif_find_by_ipaddr(struct tcpip_api_call_data *m)
425 {
426 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
427 msg->netif = netif_find_by_ipaddr(msg->msg.find_by_ipaddr.ipaddr);
428 return ERR_OK;
429 }
430
431 struct netif *
netifapi_netif_find_by_ipaddr(const ip_addr_t * ipaddr)432 netifapi_netif_find_by_ipaddr(const ip_addr_t *ipaddr)
433 {
434 struct netif *netif = NULL;
435 NETIFAPI_VAR_DECLARE(msg);
436 if (netifapi_msg_alloc(&msg) != ERR_OK) {
437 return NULL;
438 }
439
440 NETIFAPI_VAR_REF(msg).netif = NULL;
441 NETIFAPI_VAR_REF(msg).msg.find_by_ipaddr.ipaddr = ipaddr;
442 (void)tcpip_api_call(do_netifapi_netif_find_by_ipaddr, &API_VAR_REF(msg).call);
443 netif = NETIFAPI_VAR_REF(msg).netif;
444 NETIFAPI_VAR_FREE(msg);
445 return netif;
446 }
447
448 #if LWIP_IPV4
449 /**
450 * @ingroup netifapi_netif
451 * Call netif_set_addr() in a thread-safe way by running that function inside the
452 * tcpip_thread context.
453 *
454 * @note for params @see netif_set_addr()
455 */
456 err_t
netifapi_netif_set_addr(struct netif * netif,const ip4_addr_t * ipaddr,const ip4_addr_t * netmask,const ip4_addr_t * gw)457 netifapi_netif_set_addr(struct netif *netif,
458 const ip4_addr_t *ipaddr,
459 const ip4_addr_t *netmask,
460 const ip4_addr_t *gw)
461 {
462 err_t err;
463 NETIFAPI_VAR_DECLARE(msg);
464 NETIFAPI_VAR_ALLOC(msg);
465
466 if (ipaddr == NULL) {
467 ipaddr = IP4_ADDR_ANY4;
468 }
469 if (netmask == NULL) {
470 netmask = IP4_ADDR_ANY4;
471 }
472 if (gw == NULL) {
473 gw = IP4_ADDR_ANY4;
474 }
475
476 NETIFAPI_VAR_REF(msg).netif = netif;
477 NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
478 NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
479 NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
480 err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
481 NETIFAPI_VAR_FREE(msg);
482 return err;
483 }
484
485 err_t
netifapi_netif_get_addr(struct netif * netif,ip4_addr_t * ipaddr,ip4_addr_t * netmask,ip4_addr_t * gw)486 netifapi_netif_get_addr(struct netif *netif,
487 ip4_addr_t *ipaddr,
488 ip4_addr_t *netmask,
489 ip4_addr_t *gw)
490 {
491 err_t err;
492 NETIFAPI_VAR_DECLARE(msg);
493 NETIFAPI_VAR_ALLOC(msg);
494
495 NETIFAPI_VAR_REF(msg).netif = netif;
496 NETIFAPI_VAR_REF(msg).msg.add_get.ipaddr = ipaddr;
497 NETIFAPI_VAR_REF(msg).msg.add_get.netmask = netmask;
498 NETIFAPI_VAR_REF(msg).msg.add_get.gw = gw;
499 err = tcpip_api_call(netifapi_do_netif_get_addr, &API_VAR_REF(msg).call);
500 NETIFAPI_VAR_FREE(msg);
501 return err;
502 }
503
504 #endif /* LWIP_IPV4 */
505
506 /**
507 * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
508 * way by running that function inside the tcpip_thread context.
509 *
510 * @note use only for functions where there is only "netif" parameter.
511 */
512 err_t
netifapi_netif_common(struct netif * netif,netifapi_void_fn voidfunc,netifapi_errt_fn errtfunc)513 netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
514 netifapi_errt_fn errtfunc)
515 {
516 err_t err;
517 NETIFAPI_VAR_DECLARE(msg);
518
519 LWIP_ERROR("netifapi_netif_common : invalid arguments", voidfunc != NULL || errtfunc != NULL, return ERR_VAL);
520
521 NETIFAPI_VAR_ALLOC(msg);
522 NETIFAPI_VAR_REF(msg).netif = netif;
523 NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
524 NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
525 err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
526 NETIFAPI_VAR_FREE(msg);
527 return err;
528 }
529
530 /*
531 * Remove a network interface from the list of lwIP netifs.
532 *
533 * @param netif the network interface to remove
534 *
535 * @return
536 * - ERR_OK: On success
537 * - ERR_MEM: On failure due to memory
538 * - ERR_VAL: On failure due to Illegal value
539 * - ERR_NODEV: On failure due to No such netif
540 */
541 err_t
netifapi_netif_remove(struct netif * netif)542 netifapi_netif_remove(struct netif *netif)
543 {
544 return netifapi_netif_common(netif, NULL, netif_remove);
545 }
546
547 /*
548 * Bring an interface up, available for processing
549 * traffic.
550 *
551 * @note: Enabling DHCP on a down interface will make it come
552 * up once configured.
553 *
554 * @param netif the network interface
555 *
556 * @return
557 * - ERR_OK: On success
558 * - ERR_MEM: On failure due to memory
559 * - ERR_VAL: On failure due to Illegal value
560 */
561 err_t
netifapi_netif_set_up(struct netif * netif)562 netifapi_netif_set_up(struct netif *netif)
563 {
564 return netifapi_netif_common(netif, NULL, netif_set_up);
565 }
566
567 /*
568 * Bring an interface down, disabling any traffic processing.
569 *
570 * @note: Enabling DHCP on a down interface will make it come
571 * up once configured.
572 *
573 * @param netif the network interface
574 *
575 * @return
576 * - ERR_OK: On success
577 * - ERR_MEM: On failure due to memory
578 * - ERR_VAL: On failure due to Illegal value
579 */
580 err_t
netifapi_netif_set_down(struct netif * netif)581 netifapi_netif_set_down(struct netif *netif)
582 {
583 return netifapi_netif_common(netif, NULL, netif_set_down);
584 }
585
586 /*
587 * Called by a driver when its link goes up
588 *
589 * @param netif The network interface
590 *
591 * @return
592 * - ERR_OK: On success
593 * - ERR_MEM: On failure due to memory
594 * - ERR_VAL: On failure due to Illegal value
595 */
596 err_t
netifapi_netif_set_link_up(struct netif * netif)597 netifapi_netif_set_link_up(struct netif *netif)
598 {
599 return netifapi_netif_common(netif, NULL, netif_set_link_up);
600 }
601
602 /*
603 * Called by a driver when its link goes down
604 *
605 * @param netif The network interface
606 *
607 * @return
608 * - ERR_OK: On success
609 * - ERR_MEM: On failure due to memory
610 * - ERR_VAL: On failure due to Illegal value
611 */
612 err_t
netifapi_netif_set_link_down(struct netif * netif)613 netifapi_netif_set_link_down(struct netif *netif)
614 {
615 return netifapi_netif_common(netif, NULL, netif_set_link_down);
616 }
617
618 #if LWIP_DHCP
619 /*
620 * Start DHCP negotiation for a network interface.
621 *
622 * If no DHCP client instance was attached to this interface,
623 * a new client is created first. If a DHCP client instance
624 * was already present, it restarts negotiation.
625 *
626 * @param netif The lwIP network interface
627 *
628 * @return lwIP error code
629 * - ERR_OK - No error
630 * - ERR_MEM - Out of memory
631 */
632 err_t
netifapi_dhcp_start(struct netif * netif)633 netifapi_dhcp_start(struct netif *netif)
634 {
635 return netifapi_netif_common(netif, NULL, dhcp_start);
636 }
637
638 /*
639 * Remove the DHCP client from the interface.
640 *
641 * @param netif The network interface to stop DHCP on
642 *
643 * @return
644 * - ERR_OK: On success
645 * - ERR_MEM: On failure due to memory
646 * - ERR_VAL: On failure due to Illegal value
647 */
648 err_t
netifapi_dhcp_stop(struct netif * netif)649 netifapi_dhcp_stop(struct netif *netif)
650 {
651 return netifapi_netif_common(netif, dhcp_stop, NULL);
652 }
653
654 /*
655 * Inform a DHCP server of our manual configuration.
656 *
657 * This informs DHCP servers of our fixed IP_add configuration
658 * by sending an INFORM message. It does not involve DHCP address
659 * configuration, it is just here to be nice to the network.
660 *
661 * @param netif The lwIP network interface
662 *
663 * @return
664 * - ERR_OK: On success
665 * - ERR_MEM: On failure due to memory
666 * - ERR_VAL: On failure due to Illegal value
667 */
668 err_t
netifapi_dhcp_inform(struct netif * netif)669 netifapi_dhcp_inform(struct netif *netif)
670 {
671 return netifapi_netif_common(netif, dhcp_inform, NULL);
672 }
673
674 /*
675 * Renew an existing DHCP lease at the involved DHCP server.
676 *
677 * @param netif The lwIP network interface
678 *
679 * @return
680 * - ERR_OK: On success
681 * - ERR_MEM: On failure due to memory
682 * - ERR_VAL: On failure due to Illegal value
683 */
684 err_t
netifapi_dhcp_renew(struct netif * netif)685 netifapi_dhcp_renew(struct netif *netif)
686 {
687 return netifapi_netif_common(netif, NULL, dhcp_renew);
688 }
689
690 /*
691 * Release a DHCP lease (usually called before @ref dhcp_stop).
692 *
693 * @param netif The lwIP network interface
694 *
695 * @return
696 * - ERR_OK: On success
697 * - ERR_MEM: On failure due to memory
698 * - ERR_VAL: On failure due to Illegal value
699 */
700 err_t
netifapi_dhcp_release(struct netif * netif)701 netifapi_dhcp_release(struct netif *netif)
702 {
703 return netifapi_netif_common(netif, NULL, dhcp_release);
704 }
705
706 /*
707 * @ingroup netifapi_dhcp4
708 * @see dhcp_release_and_stop()
709 */
netifapi_dhcp_release_and_stop(struct netif * netif)710 err_t netifapi_dhcp_release_and_stop(struct netif *netif)
711 {
712 return netifapi_netif_common(netif, dhcp_release_and_stop, NULL);
713 }
714
715 /*
716 * Check DHCP negotiation is done for a network interface.
717 *
718 * @param netif The lwIP network interface
719 *
720 * @return
721 * - ERR_OK - if DHCP is bound
722 * - ERR_MEM - if DHCP bound is still progressing
723 */
724 err_t
netifapi_dhcp_is_bound(struct netif * netif)725 netifapi_dhcp_is_bound(struct netif *netif)
726 {
727 return netifapi_netif_common(netif, NULL, dhcp_is_bound);
728 }
729
730 /*
731 * Removes a struct dhcp from a netif.
732 *
733 * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
734 * struct dhcp since the memory is passed back to the heap.
735 *
736 * @param netif the netif from which to remove the struct dhcp
737 *
738 * @return
739 * - ERR_OK: On success
740 * - ERR_MEM: On failure due to memory
741 * - ERR_VAL: On failure due to Illegal value
742 */
743 err_t
netifapi_dhcp_cleanup(struct netif * netif)744 netifapi_dhcp_cleanup(struct netif *netif)
745 {
746 return netifapi_netif_common(netif, dhcp_cleanup, NULL);
747 }
748
749 /**
750 * To call dhcp_set_struct() inside the tcpip_thread context.
751 */
752 static err_t
netifapi_do_dhcp_set_struct(struct tcpip_api_call_data * m)753 netifapi_do_dhcp_set_struct(struct tcpip_api_call_data *m)
754 {
755 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
756
757 dhcp_set_struct(msg->netif, msg->msg.dhcp_struct.dhcp);
758 return ERR_OK;
759 }
760
761 /*
762 * Set a statically allocated struct dhcp to work with.
763 * Using this prevents dhcp_start to allocate it using mem_malloc.
764 *
765 * @param netif the netif for which to set the struct dhcp
766 * @param dhcp (uninitialised) dhcp struct allocated by the application
767 *
768 * @return
769 * - ERR_OK: On success
770 * - ERR_MEM: On failure due to memory
771 * - ERR_VAL: On failure due to Illegal value
772 */
773 err_t
netifapi_dhcp_set_struct(struct netif * netif,struct dhcp * dhcp)774 netifapi_dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
775 {
776 err_t err;
777 NETIFAPI_VAR_DECLARE(msg);
778
779 NETIFAPI_VAR_ALLOC(msg);
780 NETIFAPI_VAR_REF(msg).netif = netif;
781 NETIFAPI_VAR_REF(msg).msg.dhcp_struct.dhcp = dhcp;
782 err = tcpip_api_call(netifapi_do_dhcp_set_struct, &API_VAR_REF(msg).call);
783 NETIFAPI_VAR_FREE(msg);
784 return err;
785 }
786
787 /*
788 * To remove the statically assigned dhcp structure
789 *
790 * @param netif the network interface
791 *
792 * @return
793 * - ERR_OK: On success
794 * - ERR_MEM: On failure due to memory
795 * - ERR_VAL: On failure due to Illegal value
796 */
797 err_t
netifapi_dhcp_remove_struct(struct netif * netif)798 netifapi_dhcp_remove_struct(struct netif *netif)
799 {
800 return netifapi_netif_common(netif, dhcp_remove_struct, NULL);
801 }
802
803 #if LWIP_DHCP_SUBSTITUTE
804 err_t
netifapi_dhcp_clients_info_get(struct netif * netif,struct dhcp_clients_info ** clis_info)805 netifapi_dhcp_clients_info_get(struct netif *netif, struct dhcp_clients_info **clis_info)
806 {
807 return netifapi_netif_call_argcb(netif, dhcp_clients_info_get, (void *)clis_info);
808 }
809
810 err_t
netifapi_dhcp_clients_info_free(struct netif * netif,struct dhcp_clients_info ** clis_info)811 netifapi_dhcp_clients_info_free(struct netif *netif, struct dhcp_clients_info **clis_info)
812 {
813 return netifapi_netif_call_argcb(netif, dhcp_clients_info_free, (void *)clis_info);
814 }
815
816 err_t
netifapi_dhcp_client_info_find(struct netif * netif,struct dhcp_client_info * cli_info)817 netifapi_dhcp_client_info_find(struct netif *netif, struct dhcp_client_info *cli_info)
818 {
819 return netifapi_netif_call_argcb(netif, dhcp_client_info_find, (void *)cli_info);
820 }
821
822 #if LWIP_DHCP_LIMIT_CONCURRENT_REQUESTS
823 static err_t
do_dhcp_set_max_concurrent_num(struct netif * netif,void * arg)824 do_dhcp_set_max_concurrent_num(struct netif *netif, void *arg)
825 {
826 return dhcp_set_max_concurrent_num(netif, *((u16_t *)arg));
827 }
828
829 err_t
netifapi_dhcp_set_max_concurrent_num(struct netif * netif,u16_t dhcp_max_concurrent_num)830 netifapi_dhcp_set_max_concurrent_num(struct netif *netif, u16_t dhcp_max_concurrent_num)
831 {
832 return netifapi_netif_call_argcb(netif, do_dhcp_set_max_concurrent_num, (void *)(&dhcp_max_concurrent_num));
833 }
834 #endif /* LWIP_DHCP_LIMIT_CONCURRENT_REQUESTS */
835 #endif /* LWIP_DHCP_SUBSTITUTE */
836 #endif /* LWIP_DHCP */
837
838 /*
839 * Call the "argfunc" inside the tcpip_thread context.
840 */
841 static err_t
netifapi_do_netif_argcb(struct tcpip_api_call_data * m)842 netifapi_do_netif_argcb(struct tcpip_api_call_data *m)
843 {
844 /* cast through void* to silence alignment warnings.
845 * We know it works because the structs have been instantiated as struct netifapi_msg */
846 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
847 return msg->msg.arg_cb.argfunc(msg->netif, msg->msg.arg_cb.arg);
848 }
849
850 /*
851 * call the "argfunc" with argument arg in a thread-safe
852 * way by running that function inside the tcpip_thread context.
853 *
854 * @note use only for functions where there is only "netif" parameter.
855 */
856 err_t
netifapi_netif_call_argcb(struct netif * netif,netifapi_arg_fn argfunc,void * arg)857 netifapi_netif_call_argcb(struct netif *netif, netifapi_arg_fn argfunc, void *arg)
858 {
859 err_t err;
860 NETIFAPI_VAR_DECLARE(msg);
861
862 LWIP_ERROR("netifapi_netif_call_argcb : invalid arguments", ((netif != NULL)), return ERR_VAL);
863 LWIP_ERROR("netifapi_netif_call_argcb : invalid arguments", ((argfunc != NULL)), return ERR_VAL);
864
865 NETIFAPI_VAR_ALLOC(msg);
866 NETIFAPI_VAR_REF(msg).netif = netif;
867 NETIFAPI_VAR_REF(msg).msg.arg_cb.argfunc = argfunc;
868 NETIFAPI_VAR_REF(msg).msg.arg_cb.arg = arg;
869 err = tcpip_api_call(netifapi_do_netif_argcb, &API_VAR_REF(msg).call);
870 NETIFAPI_VAR_FREE(msg);
871 return err;
872 }
873
874 /*
875 * call the "argfunc" with argument arg in a thread-safe
876 * way by running that function inside the tcpip_thread context.
877 */
878 err_t
netifapi_call_argcb(netifapi_arg_fn argfunc,void * arg)879 netifapi_call_argcb(netifapi_arg_fn argfunc, void *arg)
880 {
881 err_t err;
882 NETIFAPI_VAR_DECLARE(msg);
883
884 LWIP_ERROR("netifapi_netif_call_argcb : invalid arguments", ((argfunc != NULL)), return ERR_VAL);
885
886 NETIFAPI_VAR_ALLOC(msg);
887 NETIFAPI_VAR_REF(msg).netif = NULL;
888 NETIFAPI_VAR_REF(msg).msg.arg_cb.argfunc = argfunc;
889 NETIFAPI_VAR_REF(msg).msg.arg_cb.arg = arg;
890 err = tcpip_api_call(netifapi_do_netif_argcb, &API_VAR_REF(msg).call);
891 NETIFAPI_VAR_FREE(msg);
892 return err;
893 }
894
895 /*
896 * Set a network interface as the default network interface
897 * (used to output all packets for which no specific route is found)
898 *
899 * @param netif the default network interface
900 *
901 * @return
902 * - ERR_OK: On success
903 * - ERR_MEM: On failure due to memory
904 * - ERR_VAL: On failure due to Illegal value
905 */
906 err_t
netifapi_netif_set_default(struct netif * netif)907 netifapi_netif_set_default(struct netif *netif)
908 {
909 return netifapi_netif_common(netif, NULL, netif_set_default);
910 }
911
912 static err_t
do_netifapi_netif_get_default(struct tcpip_api_call_data * m)913 do_netifapi_netif_get_default(struct tcpip_api_call_data *m)
914 {
915 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
916
917 if ((netif_default != NULL) && netif_is_up(netif_default)) {
918 msg->netif = netif_default;
919 } else {
920 msg->netif = NULL;
921 }
922
923 return ERR_OK;
924 }
925
926 /*
927 * Get the default network interface
928 *
929 * @return
930 * - NULL if either the default netif was NOT exist or the default netif was down,
931 * - else return the default netif pointer
932 */
netifapi_netif_get_default(void)933 struct netif *netifapi_netif_get_default(void)
934 {
935 struct netif *netif_def = NULL;
936 NETIFAPI_VAR_DECLARE(msg);
937
938 if (netifapi_msg_alloc(&msg) != ERR_OK) {
939 return NULL;
940 }
941
942 NETIFAPI_VAR_REF(msg).netif = NULL;
943 (void)tcpip_api_call(do_netifapi_netif_get_default, &API_VAR_REF(msg).call);
944 netif_def = NETIFAPI_VAR_REF(msg).netif;
945 NETIFAPI_VAR_FREE(msg);
946 return netif_def;
947 }
948
949 #if LWIP_IPV6
950
netif_create_ip6_linklocal_address_wrapper(struct netif * netif,void * arg)951 err_t netif_create_ip6_linklocal_address_wrapper(struct netif *netif, void *arg)
952 {
953 u32_t *tmp = (u32_t*)arg;
954 u32_t from_mac_48bit = *tmp;
955 return netif_create_ip6_linklocal_address(netif, (u8_t)from_mac_48bit);
956 }
957
958 /*
959 * @ingroup netif_ip6
960 * This function allows for the easy addition of a new IPv6 address to an interface.
961 * It takes care of finding an empty slot and then sets the address tentative
962 * (to make sure that all the subsequent processing happens).
963 *
964 * @param netif netif to add the address on
965 * @param ip6addr address to add
966 * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here
967 */
968 err_t
netifapi_netif_add_ip6_linklocal_address(struct netif * netif,u8_t from_mac_48bit)969 netifapi_netif_add_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
970 {
971 err_t err;
972 u32_t is_from_mac_48bit = from_mac_48bit;
973 NETIFAPI_VAR_DECLARE(msg);
974
975 LWIP_ERROR("netifapi_netif_add_ip6_linklocal_address : invalid arguments", ((netif != NULL)), return ERR_VAL);
976 NETIFAPI_VAR_ALLOC(msg);
977
978 NETIFAPI_VAR_REF(msg).netif = netif;
979 NETIFAPI_VAR_REF(msg).msg.arg_cb.argfunc = netif_create_ip6_linklocal_address_wrapper;
980 NETIFAPI_VAR_REF(msg).msg.arg_cb.arg = &is_from_mac_48bit;
981 err = tcpip_api_call(netifapi_do_netif_argcb, &API_VAR_REF(msg).call);
982 NETIFAPI_VAR_FREE(msg);
983 return err;
984 }
985
986 /*
987 * @ingroup netif_ip6
988 * This function allows for the easy addition of a new IPv6 address to an interface.
989 * It takes care of finding an empty slot and then sets the address tentative
990 * (to make sure that all the subsequent processing happens).
991 *
992 * @param netif netif to add the address on
993 * @param ip6addr address to add
994 * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here
995 */
996 err_t
netifapi_netif_add_ip6_address(struct netif * netif,ip_addr_t * ipaddr)997 netifapi_netif_add_ip6_address(struct netif *netif, ip_addr_t *ipaddr)
998 {
999 err_t err;
1000 NETIFAPI_VAR_DECLARE(msg);
1001
1002 LWIP_ERROR("netifapi_netif_add_ip6_address : invalid arguments", ((ipaddr != NULL)), return ERR_VAL);
1003 LWIP_ERROR("netifapi_netif_add_ip6_address : invalid arguments", ((netif != NULL)), return ERR_VAL);
1004
1005 /* Do no allow multicast or any ip address or loopback address to be set as interface address */
1006 if (!IP_IS_V6(ipaddr) ||
1007 ip_addr_ismulticast(ipaddr) ||
1008 ip_addr_isany(ipaddr) ||
1009 ip_addr_isloopback(ipaddr)) {
1010 return ERR_VAL;
1011 }
1012
1013 NETIFAPI_VAR_ALLOC(msg);
1014
1015 NETIFAPI_VAR_REF(msg).netif = netif;
1016 NETIFAPI_VAR_REF(msg).msg.arg_cb.argfunc = netif_do_add_ipv6_addr;
1017 NETIFAPI_VAR_REF(msg).msg.arg_cb.arg = (void*)ipaddr;
1018 err = tcpip_api_call(netifapi_do_netif_argcb, &API_VAR_REF(msg).call);
1019 NETIFAPI_VAR_FREE(msg);
1020 return err;
1021 }
1022
1023 #if LWIP_IPV6_AUTOCONFIG
1024 err_t
netifapi_set_ip6_autoconfig_enabled(struct netif * netif)1025 netifapi_set_ip6_autoconfig_enabled(struct netif *netif)
1026 {
1027 return netifapi_netif_common(netif, netif_set_ip6_autoconfig_enabled, NULL);
1028 }
1029
1030 err_t
netifapi_set_ip6_autoconfig_disabled(struct netif * netif)1031 netifapi_set_ip6_autoconfig_disabled(struct netif *netif)
1032 {
1033 return netifapi_netif_common(netif, netif_set_ip6_autoconfig_disabled, NULL);
1034 }
1035 #endif /* LWIP_IPV6_AUTOCONFIG */
1036
1037 #endif /* LWIP_IPV6 */
1038
1039 #if LWIP_IPV6 && LWIP_IPV6_MLD
netif_do_join_ip6_multicastgroup(struct netif * netif,void * arguments)1040 err_t netif_do_join_ip6_multicastgroup(struct netif *netif, void *arguments)
1041 {
1042 ip6_addr_t *ipaddr = (ip6_addr_t *)arguments;
1043 err_t err;
1044
1045 err = mld6_join_staticgroup_netif(netif, ipaddr);
1046 return err;
1047 }
1048
1049 err_t
netifapi_netif_join_ip6_multicastgroup(struct netif * netif,ip6_addr_t * ip6addr)1050 netifapi_netif_join_ip6_multicastgroup(struct netif *netif, ip6_addr_t *ip6addr)
1051 {
1052 err_t err;
1053 NETIFAPI_VAR_DECLARE(msg);
1054
1055 LWIP_ERROR("netifapi_netif_add_ip6_address : invalid arguments", ((ip6addr != NULL)), return ERR_VAL);
1056 LWIP_ERROR("netifapi_netif_add_ip6_address : invalid arguments", ((netif != NULL)), return ERR_VAL);
1057
1058 NETIFAPI_VAR_ALLOC(msg);
1059
1060 NETIFAPI_VAR_REF(msg).netif = netif;
1061 NETIFAPI_VAR_REF(msg).msg.arg_cb.argfunc = netif_do_join_ip6_multicastgroup;
1062 NETIFAPI_VAR_REF(msg).msg.arg_cb.arg = (void*)ip6addr;
1063 err = tcpip_api_call(netifapi_do_netif_argcb, &API_VAR_REF(msg).call);
1064 NETIFAPI_VAR_FREE(msg);
1065 return err;
1066 }
1067
1068 #endif
1069
1070 #if LWIP_IPV6
1071 /*
1072 * @ingroup netif_ip6
1073 * This function allows for the easy removal of a existing IPv6 address to an interface.
1074 *
1075 * @param netif netif to add the address on
1076 * @param ip6addr address to add
1077 * @param chosen_idx if != NULL, the chosen IPv6 address index will be removed from here
1078 */
1079 void
netifapi_netif_rmv_ip6_address(struct netif * netif,ip_addr_t * ipaddr)1080 netifapi_netif_rmv_ip6_address(struct netif *netif, ip_addr_t *ipaddr)
1081 {
1082 NETIFAPI_VAR_DECLARE(msg);
1083
1084 LWIP_ERROR("netifapi_netif_add_ip6_address : invalid arguments", ((ipaddr != NULL)), return);
1085 LWIP_ERROR("netifapi_netif_add_ip6_address : invalid arguments", ((netif != NULL)), return);
1086
1087 if (netifapi_msg_alloc(&msg) != ERR_OK) {
1088 return;
1089 }
1090
1091 NETIFAPI_VAR_REF(msg).netif = netif;
1092 NETIFAPI_VAR_REF(msg).msg.arg_cb.argfunc = netif_do_rmv_ipv6_addr;
1093 NETIFAPI_VAR_REF(msg).msg.arg_cb.arg = (void*)ipaddr;
1094 (void)tcpip_api_call(netifapi_do_netif_argcb, &API_VAR_REF(msg).call);
1095 NETIFAPI_VAR_FREE(msg);
1096 return;
1097 }
1098 #endif
1099
1100 #if LWIP_NETIF_LINK_CALLBACK
1101 static err_t
netifapi_do_netif_set_link_callback(struct tcpip_api_call_data * m)1102 netifapi_do_netif_set_link_callback(struct tcpip_api_call_data *m)
1103 {
1104 /* cast through void* to silence alignment warnings.
1105 * We know it works because the structs have been instantiated as struct netifapi_msg */
1106 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1107 err_t err;
1108
1109 err = netif_set_link_callback(msg->netif, msg->msg.netif_link_cb.link_callback);
1110 return err;
1111 }
1112
1113 err_t
netifapi_netif_set_link_callback(struct netif * netif,netif_status_callback_fn link_callback)1114 netifapi_netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)
1115 {
1116 err_t err;
1117 NETIFAPI_VAR_DECLARE(msg);
1118
1119 LWIP_ERROR("netifapi_netif_set_link_callback : invalid arguments", (netif != NULL), return ERR_VAL);
1120 NETIFAPI_VAR_ALLOC(msg);
1121
1122 NETIFAPI_VAR_REF(msg).netif = netif;
1123 NETIFAPI_VAR_REF(msg).msg.netif_link_cb.link_callback = link_callback;
1124 err = tcpip_api_call(netifapi_do_netif_set_link_callback, &API_VAR_REF(msg).call);
1125 NETIFAPI_VAR_FREE(msg);
1126 return err;
1127 }
1128 #endif
1129
1130 #if LWIP_NETIF_EXT_STATUS_CALLBACK
1131 static err_t
netifapi_do_netif_add_ext_callback(struct tcpip_api_call_data * m)1132 netifapi_do_netif_add_ext_callback(struct tcpip_api_call_data *m)
1133 {
1134 /* cast through void* to silence alignment warnings.
1135 * We know it works because the structs have been instantiated as struct netifapi_msg */
1136 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1137 /* avoid adding duplicate cb, otherwise the linklist may form a circle */
1138 netif_remove_ext_callback(msg->msg.netif_ext_cb.cb);
1139 netif_add_ext_callback(msg->msg.netif_ext_cb.cb, msg->msg.netif_ext_cb.fn);
1140 return ERR_OK;
1141 }
1142
1143 err_t
netifapi_netif_add_ext_callback(netif_ext_callback_t * callback,netif_ext_callback_fn fn)1144 netifapi_netif_add_ext_callback(netif_ext_callback_t *callback, netif_ext_callback_fn fn)
1145 {
1146 err_t err;
1147 NETIFAPI_VAR_DECLARE(msg);
1148 LWIP_ERROR("netifapi_netif_add_ext_callback : invalid arguments", (callback != NULL), return ERR_VAL);
1149 LWIP_ERROR("netifapi_netif_add_ext_callback : invalid arguments", (fn != NULL), return ERR_VAL);
1150 NETIFAPI_VAR_ALLOC(msg);
1151 NETIFAPI_VAR_REF(msg).msg.netif_ext_cb.cb = callback;
1152 NETIFAPI_VAR_REF(msg).msg.netif_ext_cb.fn = fn;
1153 err = tcpip_api_call(netifapi_do_netif_add_ext_callback, &API_VAR_REF(msg).call);
1154 NETIFAPI_VAR_FREE(msg);
1155 return err;
1156 }
1157
1158 static err_t
netifapi_do_netif_remove_ext_callback(struct tcpip_api_call_data * m)1159 netifapi_do_netif_remove_ext_callback(struct tcpip_api_call_data *m)
1160 {
1161 /* cast through void* to silence alignment warnings.
1162 * We know it works because the structs have been instantiated as struct netifapi_msg */
1163 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1164 netif_remove_ext_callback(msg->msg.netif_ext_cb.cb);
1165 return ERR_OK;
1166 }
1167
1168 err_t
netifapi_netif_remove_ext_callback(netif_ext_callback_t * callback)1169 netifapi_netif_remove_ext_callback(netif_ext_callback_t *callback)
1170 {
1171 err_t err;
1172 NETIFAPI_VAR_DECLARE(msg);
1173 LWIP_ERROR("netifapi_netif_remove_ext_callback : invalid arguments", (callback != NULL), return ERR_VAL);
1174 NETIFAPI_VAR_ALLOC(msg);
1175 NETIFAPI_VAR_REF(msg).msg.netif_ext_cb.cb = callback;
1176 err = tcpip_api_call(netifapi_do_netif_remove_ext_callback, &API_VAR_REF(msg).call);
1177 NETIFAPI_VAR_FREE(msg);
1178 return err;
1179 }
1180 #endif /* LWIP_NETIF_EXT_STATUS_CALLBACK */
1181
1182 static err_t
netifapi_do_netif_set_mtu(struct tcpip_api_call_data * m)1183 netifapi_do_netif_set_mtu(struct tcpip_api_call_data *m)
1184 {
1185 /* cast through void* to silence alignment warnings.
1186 * We know it works because the structs have been instantiated as struct netifapi_msg */
1187 err_t ret;
1188 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1189 ret = netif_set_mtu(msg->netif, msg->msg.netif_mtu.mtu);
1190 return ret;
1191 }
1192
1193 err_t
netifapi_netif_set_mtu(struct netif * netif,u16_t mtu)1194 netifapi_netif_set_mtu(struct netif *netif, u16_t mtu)
1195 {
1196 err_t err;
1197 NETIFAPI_VAR_DECLARE(msg);
1198
1199 LWIP_ERROR("netifapi_netif_set_mtu : invalid arguments", (netif != NULL), return ERR_VAL);
1200 NETIFAPI_VAR_ALLOC(msg);
1201
1202 NETIFAPI_VAR_REF(msg).netif = netif;
1203 NETIFAPI_VAR_REF(msg).msg.netif_mtu.mtu = mtu;
1204 err = tcpip_api_call(netifapi_do_netif_set_mtu, &API_VAR_REF(msg).call);
1205 NETIFAPI_VAR_FREE(msg);
1206 return err;
1207 }
1208
1209 #if LWIP_DHCPS
1210 static err_t
netifapi_do_dhcps_start(struct tcpip_api_call_data * m)1211 netifapi_do_dhcps_start(struct tcpip_api_call_data *m)
1212 {
1213 /* cast through void* to silence alignment warnings.
1214 * We know it works because the structs have been instantiated as struct netifapi_msg */
1215 err_t ret;
1216 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1217 ret = dhcps_start(msg->netif, msg->msg.dhcp_start_params.start_ip, msg->msg.dhcp_start_params.ip_num);
1218 return ret;
1219 }
1220
1221 err_t
netifapi_dhcps_start(struct netif * netif,char * start_ip,u16_t ip_num)1222 netifapi_dhcps_start(struct netif *netif, char *start_ip, u16_t ip_num)
1223 {
1224 err_t err;
1225 NETIFAPI_VAR_DECLARE(msg);
1226
1227 LWIP_ERROR("netifapi_dhcps_start : invalid arguments", (netif != NULL), return ERR_VAL);
1228 NETIFAPI_VAR_ALLOC(msg);
1229
1230 NETIFAPI_VAR_REF(msg).netif = netif;
1231 NETIFAPI_VAR_REF(msg).msg.dhcp_start_params.start_ip = start_ip;
1232 NETIFAPI_VAR_REF(msg).msg.dhcp_start_params.ip_num = ip_num;
1233
1234 err = tcpip_api_call(netifapi_do_dhcps_start, &API_VAR_REF(msg).call);
1235
1236 NETIFAPI_VAR_FREE(msg);
1237 return err;
1238 }
1239
1240 err_t
netifapi_dhcps_stop(struct netif * netif)1241 netifapi_dhcps_stop(struct netif *netif)
1242 {
1243 LWIP_ERROR("netifapi_dhcps_stop : invalid arguments", (netif != NULL), return ERR_VAL);
1244
1245 return netifapi_netif_common(netif, dhcps_stop, NULL);
1246 }
1247
1248 static err_t
netifapi_do_dhcps_get_client_ip(struct tcpip_api_call_data * m)1249 netifapi_do_dhcps_get_client_ip(struct tcpip_api_call_data *m)
1250 {
1251 /*
1252 * cast through void* to silence alignment warnings.
1253 * We know it works because the structs have been instantiated as struct netifapi_msg
1254 */
1255 err_t ret;
1256 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1257 ret = dhcps_find_client_lease(msg->netif, msg->msg.dhcp_get_ip_params.mac,
1258 msg->msg.dhcp_get_ip_params.maclen, msg->msg.dhcp_get_ip_params.ip);
1259 return ret;
1260 }
1261
1262 err_t
netifapi_dhcps_get_client_ip(struct netif * netif,u8_t * mac,u8_t maclen,ip_addr_t * ip)1263 netifapi_dhcps_get_client_ip(struct netif *netif, u8_t *mac, u8_t maclen, ip_addr_t *ip)
1264 {
1265 err_t err;
1266 NETIFAPI_VAR_DECLARE(msg);
1267
1268 LWIP_ERROR("netifapi_dhcps_get_client_ip : invalid arguments", (netif != NULL), return ERR_VAL);
1269 NETIFAPI_VAR_ALLOC(msg);
1270
1271 NETIFAPI_VAR_REF(msg).netif = netif;
1272 NETIFAPI_VAR_REF(msg).msg.dhcp_get_ip_params.mac = mac;
1273 NETIFAPI_VAR_REF(msg).msg.dhcp_get_ip_params.maclen = maclen;
1274 NETIFAPI_VAR_REF(msg).msg.dhcp_get_ip_params.ip = ip;
1275
1276 err = tcpip_api_call(netifapi_do_dhcps_get_client_ip, &API_VAR_REF(msg).call);
1277
1278 NETIFAPI_VAR_FREE(msg);
1279 return err;
1280 }
1281 #endif /* LWIP_DHCPS */
1282
1283 #if LWIP_AUTOIP
1284 /*
1285 * Call autoip_start() in a thread-safe way by running that function inside the
1286 * tcpip_thread context.
1287 *
1288 * @note use only for functions where there is only "netif" parameter.
1289 */
1290 err_t
netifapi_autoip_start(struct netif * netif)1291 netifapi_autoip_start(struct netif *netif)
1292 {
1293 return netifapi_netif_common(netif, NULL, autoip_start);
1294 }
1295
1296 /*
1297 * Call autoip_stop() in a thread-safe way by running that function inside the
1298 * tcpip_thread context.
1299 *
1300 * @note use only for functions where there is only "netif" parameter.
1301 */
1302 err_t
netifapi_autoip_stop(struct netif * netif)1303 netifapi_autoip_stop(struct netif *netif)
1304 {
1305 return netifapi_netif_common(netif, NULL, autoip_stop);
1306 }
1307 #endif /* LWIP_AUTOIP */
1308
1309 #if LWIP_IPV6_DHCP6
1310 err_t
netifapi_dhcp6_enable_stateful(struct netif * netif)1311 netifapi_dhcp6_enable_stateful(struct netif *netif)
1312 {
1313 LWIP_ERROR("netifapi_dhcp6_enable_stateful : netif == NULL", ((netif != NULL)), return ERR_VAL);
1314 return netifapi_netif_common(netif, NULL, dhcp6_enable_stateful);
1315 }
1316
1317 err_t
netifapi_dhcp6_enable_stateless(struct netif * netif)1318 netifapi_dhcp6_enable_stateless(struct netif *netif)
1319 {
1320 LWIP_ERROR("netifapi_dhcp6_enable_stateless : netif == NULL", ((netif != NULL)), return ERR_VAL);
1321 return netifapi_netif_common(netif, NULL, dhcp6_enable_stateless);
1322 }
1323
1324 err_t
netifapi_dhcp6_disable(struct netif * netif)1325 netifapi_dhcp6_disable(struct netif *netif)
1326 {
1327 LWIP_ERROR("netifapi_dhcp6_disable : netif == NULL", ((netif != NULL)), return ERR_VAL);
1328 return netifapi_netif_common(netif, dhcp6_disable, NULL);
1329 }
1330
1331 err_t
netifapi_dhcp6_release_stateful(struct netif * netif)1332 netifapi_dhcp6_release_stateful(struct netif *netif)
1333 {
1334 LWIP_ERROR("netifapi_dhcp6_release_stateful : netif == NULL", ((netif != NULL)), return ERR_VAL);
1335 return netifapi_netif_common(netif, NULL, dhcp6_release_stateful);
1336 }
1337
1338 err_t
netifapi_dhcp6_cleanup(struct netif * netif)1339 netifapi_dhcp6_cleanup(struct netif *netif)
1340 {
1341 LWIP_ERROR("netifapi_dhcp6_cleanup : netif == NULL", ((netif != NULL)), return ERR_VAL);
1342 return netifapi_netif_common(netif, dhcp6_cleanup, NULL);
1343 }
1344 #endif /* LWIP_IPV6_DHCP6 */
1345
1346 /**
1347 * @ingroup netifapi_netif
1348 * Call netif_name_to_index() in a thread-safe way by running that function inside the
1349 * tcpip_thread context.
1350 *
1351 * @param name the interface name of the netif
1352 * @param idx output index of the found netif
1353 */
1354 err_t
netifapi_netif_name_to_index(const char * name,u8_t * idx)1355 netifapi_netif_name_to_index(const char *name, u8_t *idx)
1356 {
1357 #if LWIP_MPU_COMPATIBLE
1358 size_t namelen;
1359 #endif
1360 err_t err;
1361 NETIFAPI_VAR_DECLARE(msg);
1362 NETIFAPI_VAR_ALLOC(msg);
1363 if ((name == NULL) || (idx == NULL)) {
1364 return ERR_ARG;
1365 }
1366 *idx = 0;
1367
1368 #if LWIP_MPU_COMPATIBLE
1369 namelen = strlen(name);
1370 if (namelen <= (NETIF_NAMESIZE - 1)) {
1371 (void)strncpy_s(NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE, name, namelen);
1372 NETIFAPI_VAR_REF(msg).msg.ifs.name[namelen] = '\0';
1373 } else {
1374 return ERR_ARG;
1375 }
1376 #else
1377 NETIFAPI_VAR_REF(msg).msg.ifs.name = LWIP_CONST_CAST(char *, name);
1378 #endif /* LWIP_MPU_COMPATIBLE */
1379 err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call);
1380 if (!err) {
1381 *idx = NETIFAPI_VAR_REF(msg).msg.ifs.index;
1382 }
1383 NETIFAPI_VAR_FREE(msg);
1384 return err;
1385 }
1386
1387 /**
1388 * @ingroup netifapi_netif
1389 * Call netif_index_to_name() in a thread-safe way by running that function inside the
1390 * tcpip_thread context.
1391 *
1392 * @param idx the interface index of the netif
1393 * @param name output name of the found netif, empty '\0' string if netif not found.
1394 * name should be of at least NETIF_NAMESIZE bytes
1395 */
1396 err_t
netifapi_netif_index_to_name(u8_t idx,char * name)1397 netifapi_netif_index_to_name(u8_t idx, char *name)
1398 {
1399 err_t err;
1400 NETIFAPI_VAR_DECLARE(msg);
1401 NETIFAPI_VAR_ALLOC(msg);
1402
1403 if (name == NULL) {
1404 return ERR_ARG;
1405 }
1406 NETIFAPI_VAR_REF(msg).msg.ifs.index = idx;
1407 #if !LWIP_MPU_COMPATIBLE
1408 NETIFAPI_VAR_REF(msg).msg.ifs.name = name;
1409 #endif /* LWIP_MPU_COMPATIBLE */
1410 err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call);
1411 #if LWIP_MPU_COMPATIBLE
1412 if (!err) {
1413 /* here stack is assuming that the input buffer is of minimum size NETIF_NAMESIZE.
1414 This is a limitation of the API */
1415 (void)strncpy_s(name, NETIF_NAMESIZE,
1416 NETIFAPI_VAR_REF(msg).msg.ifs.name, strlen(NETIFAPI_VAR_REF(msg).msg.ifs.name));
1417 name[strlen(NETIFAPI_VAR_REF(msg).msg.ifs.name)] = '\0';
1418 }
1419 #endif /* LWIP_MPU_COMPATIBLE */
1420 NETIFAPI_VAR_FREE(msg);
1421 return err;
1422 }
1423
1424 /*
1425 * Call netif_get_nameindex_all() inside the tcpip_thread context.
1426 */
1427 static err_t
netifapi_netif_get_nameindex_all(struct tcpip_api_call_data * m)1428 netifapi_netif_get_nameindex_all(struct tcpip_api_call_data *m)
1429 {
1430 err_t err;
1431 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1432 err = netif_get_nameindex_all((void *)(&msg->msg.if_list));
1433 return err;
1434 }
1435
1436 /*
1437 * @ingroup netifapi_netif
1438 * Call netifapi_netif_get_nameindex_all() in a thread-safe way by running that function inside the
1439 * tcpip_thread context.
1440 *
1441 * @param ppIfLst , the pointer to all the interface list in name index format,if_nameindex structure.
1442 *
1443 */
netifapi_netif_nameindex_all(void * arg)1444 err_t netifapi_netif_nameindex_all(void *arg)
1445 {
1446 err_t err;
1447 struct if_nameindex **tmp_iflist = (struct if_nameindex **)arg;
1448 NETIFAPI_VAR_DECLARE(msg);
1449 NETIFAPI_VAR_ALLOC(msg);
1450
1451 if (tmp_iflist == NULL) {
1452 return ERR_ARG;
1453 }
1454
1455 err = tcpip_api_call(netifapi_netif_get_nameindex_all, &API_VAR_REF(msg).call);
1456 *tmp_iflist = NETIFAPI_VAR_REF(msg).msg.if_list;
1457
1458 NETIFAPI_VAR_FREE(msg);
1459 return err;
1460 }
1461
1462 #if LWIP_NETIF_HOSTNAME
1463 static err_t
do_netifapi_set_hostname(struct tcpip_api_call_data * m)1464 do_netifapi_set_hostname(struct tcpip_api_call_data *m)
1465 {
1466 /* cast through void* to silence alignment warnings.
1467 * We know it works because the structs have been instantiated as struct netifapi_msg */
1468 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1469
1470 if (strncpy_s(msg->netif->hostname, NETIF_HOSTNAME_MAX_LEN,
1471 msg->msg.hostname.name, NETIF_HOSTNAME_MAX_LEN - 1) == EOK) {
1472 if (msg->msg.hostname.namelen < (NETIF_HOSTNAME_MAX_LEN - 1)) {
1473 msg->netif->hostname[msg->msg.hostname.namelen] = '\0';
1474 } else {
1475 msg->netif->hostname[NETIF_HOSTNAME_MAX_LEN - 1] = '\0';
1476 }
1477 return ERR_OK;
1478 }
1479 return ERR_VAL;
1480 }
1481
1482 err_t
netifapi_set_hostname(struct netif * netif,char * hostname,u8_t namelen)1483 netifapi_set_hostname(struct netif *netif, char *hostname, u8_t namelen)
1484 {
1485 err_t err;
1486 NETIFAPI_VAR_DECLARE(msg);
1487
1488 LWIP_ERROR("netifapi_set_hostname:netif is NULL", (netif != NULL), return ERR_ARG);
1489 LWIP_ERROR("netifapi_set_hostname:hostname is NULL", (hostname != NULL), return ERR_ARG);
1490
1491 NETIFAPI_VAR_ALLOC(msg);
1492
1493 NETIFAPI_VAR_REF(msg).netif = netif;
1494 NETIFAPI_VAR_REF(msg).msg.hostname.name = hostname;
1495 NETIFAPI_VAR_REF(msg).msg.hostname.namelen = namelen;
1496
1497 err = tcpip_api_call(do_netifapi_set_hostname, &API_VAR_REF(msg).call);
1498 NETIFAPI_VAR_FREE(msg);
1499 return err;
1500 }
1501
1502 static err_t
do_netifapi_get_hostname(struct tcpip_api_call_data * m)1503 do_netifapi_get_hostname(struct tcpip_api_call_data *m)
1504 {
1505 /* cast through void* to silence alignment warnings.
1506 * We know it works because the structs have been instantiated as struct netifapi_msg */
1507 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1508
1509 if (strncpy_s(msg->msg.hostname.name, msg->msg.hostname.namelen,
1510 msg->netif->hostname, (size_t)(msg->msg.hostname.namelen - 1)) == 0) {
1511 msg->msg.hostname.name[msg->msg.hostname.namelen - 1] = '\0';
1512 return ERR_OK;
1513 }
1514 return ERR_VAL;
1515 }
1516
1517 err_t
netifapi_get_hostname(struct netif * netif,char * hostname,u8_t namelen)1518 netifapi_get_hostname(struct netif *netif, char *hostname, u8_t namelen)
1519 {
1520 err_t err;
1521 NETIFAPI_VAR_DECLARE(msg);
1522
1523 LWIP_ERROR("netifapi_get_hostname:netif is NULL", (netif != NULL), return ERR_ARG);
1524 LWIP_ERROR("netifapi_get_hostname:hostname is NULL", (hostname != NULL), return ERR_ARG);
1525
1526 NETIFAPI_VAR_ALLOC(msg);
1527
1528 NETIFAPI_VAR_REF(msg).netif = netif;
1529 NETIFAPI_VAR_REF(msg).msg.hostname.name = hostname;
1530 NETIFAPI_VAR_REF(msg).msg.hostname.namelen = namelen;
1531
1532 err = tcpip_api_call(do_netifapi_get_hostname, &API_VAR_REF(msg).call);
1533 NETIFAPI_VAR_FREE(msg);
1534 return err;
1535 }
1536
1537 #endif /* LWIP_NETIF_HOSTNAME */
1538
1539 #if LWIP_DHCP_VENDOR_CLASS_IDENTIFIER
1540 static err_t
do_netifapi_set_vci(struct tcpip_api_call_data * m)1541 do_netifapi_set_vci(struct tcpip_api_call_data *m)
1542 {
1543 err_t ret;
1544 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1545 ret = dhcp_set_vci(msg->msg.vci.vci, *(msg->msg.vci.vci_len));
1546 return ret;
1547 }
1548
1549 err_t
netifapi_set_vci(char * vci,u8_t vci_len)1550 netifapi_set_vci(char *vci, u8_t vci_len)
1551 {
1552 err_t err;
1553 NETIFAPI_VAR_DECLARE(msg);
1554
1555 LWIP_ERROR("netifapi_set_vci:vci is NULL", (vci != NULL), return ERR_ARG);
1556 LWIP_ERROR("netifapi_set_vci:vci_len > DHCP_VCI_MAX_LEN", (vci_len <= DHCP_VCI_MAX_LEN), return ERR_ARG);
1557
1558 NETIFAPI_VAR_ALLOC(msg);
1559
1560 NETIFAPI_VAR_REF(msg).netif = NULL;
1561 NETIFAPI_VAR_REF(msg).msg.vci.vci = vci;
1562 NETIFAPI_VAR_REF(msg).msg.vci.vci_len = &vci_len;
1563
1564 err = tcpip_api_call(do_netifapi_set_vci, &API_VAR_REF(msg).call);
1565
1566 NETIFAPI_VAR_FREE(msg);
1567 return err;
1568 }
1569
1570 static err_t
do_netifapi_get_vci(struct tcpip_api_call_data * m)1571 do_netifapi_get_vci(struct tcpip_api_call_data *m)
1572 {
1573 err_t ret;
1574 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1575 ret = dhcp_get_vci(msg->msg.vci.vci, msg->msg.vci.vci_len);
1576 return ret;
1577 }
1578
1579 err_t
netifapi_get_vci(char * vci,u8_t * vci_len)1580 netifapi_get_vci(char *vci, u8_t *vci_len)
1581 {
1582 err_t err;
1583 NETIFAPI_VAR_DECLARE(msg);
1584
1585 LWIP_ERROR("netifapi_get_vci:vci is NULL", (vci != NULL), return ERR_ARG);
1586 LWIP_ERROR("netifapi_get_vci:vci_len is NULL", (vci_len != NULL), return ERR_ARG);
1587 LWIP_ERROR("netifapi_get_vci:*vci_len < DHCP_VCI_MAX_LEN", (*vci_len >= DHCP_VCI_MAX_LEN), return ERR_ARG);
1588
1589 NETIFAPI_VAR_ALLOC(msg);
1590
1591 NETIFAPI_VAR_REF(msg).netif = NULL;
1592 NETIFAPI_VAR_REF(msg).msg.vci.vci = vci;
1593 NETIFAPI_VAR_REF(msg).msg.vci.vci_len = vci_len;
1594
1595 err = tcpip_api_call(do_netifapi_get_vci, &API_VAR_REF(msg).call);
1596
1597 NETIFAPI_VAR_FREE(msg);
1598 return err;
1599 }
1600 #endif /* LWIP_DHCP_VENDOR_CLASS_IDENTIFIER */
1601
1602 #if LWIP_IP_FILTER || LWIP_IPV6_FILTER
1603 static err_t
do_netifapi_set_ip_filter(struct tcpip_api_call_data * m)1604 do_netifapi_set_ip_filter(struct tcpip_api_call_data *m)
1605 {
1606 err_t ret = ERR_VAL;
1607 struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
1608 #if LWIP_IP_FILTER
1609 if (msg->msg.ip_filter.type == IPADDR_TYPE_V4) {
1610 ret = set_ip4_filter(msg->msg.ip_filter.filter_fn);
1611 }
1612 #endif /* LWIP_IP_FILTER */
1613 #if LWIP_IPV6_FILTER
1614 if (msg->msg.ip_filter.type == IPADDR_TYPE_V6) {
1615 ret = set_ip6_filter(msg->msg.ip_filter.filter_fn);
1616 }
1617 #endif /* LWIP_IPV6_FILTER */
1618 return ret;
1619 }
1620
1621 /*
1622 * Set ip filter_fn, the filter_fn will be called when pass a packet to ip_input.
1623 *
1624 * @param filter_fn The filter implement function, NULL indicate disable the filter.
1625 * @return
1626 * - ERR_OK: On success
1627 * - ERR_VAL: On failure due to Illegal value
1628 */
1629 err_t
netifapi_set_ip_filter(ip_filter_fn filter_fn,int type)1630 netifapi_set_ip_filter(ip_filter_fn filter_fn, int type)
1631 {
1632 err_t err;
1633 NETIFAPI_VAR_DECLARE(msg);
1634
1635 NETIFAPI_VAR_ALLOC(msg);
1636 (void)memset_s(&msg, sizeof(struct netifapi_msg), 0, sizeof(struct netifapi_msg));
1637
1638 NETIFAPI_VAR_REF(msg).msg.ip_filter.filter_fn = filter_fn;
1639 NETIFAPI_VAR_REF(msg).msg.ip_filter.type = type;
1640
1641 err = tcpip_api_call(do_netifapi_set_ip_filter, &API_VAR_REF(msg).call);
1642 NETIFAPI_VAR_FREE(msg);
1643 return err;
1644 }
1645 #endif /* LWIP_IP_FILTER || LWIP_IPV6_FILTER */
1646
1647 #if LWIP_IPV6
1648 #if LWIP_ND6_ROUTER
1649 static err_t
netifapi_do_set_ra_enable(struct tcpip_api_call_data * m)1650 netifapi_do_set_ra_enable(struct tcpip_api_call_data *m)
1651 {
1652 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1653 struct netif *nif = msg->netif;
1654 u8_t ra_enable = msg->msg.ip6_state.state;
1655
1656 nif->ra_enable = (ra_enable > 0) ? lwIP_TRUE : lwIP_FALSE;
1657 return ERR_OK;
1658 }
1659
1660 err_t
netifapi_set_ra_enable(struct netif * netif,u8_t ra_enable)1661 netifapi_set_ra_enable(struct netif *netif, u8_t ra_enable)
1662 {
1663 err_t err;
1664 NETIFAPI_VAR_DECLARE(msg);
1665
1666 LWIP_ERROR("netifapi_set_ipv6_forwarding : invalid arguments \n", (netif != NULL), return ERR_ARG);
1667
1668 NETIFAPI_VAR_ALLOC(msg);
1669
1670 NETIFAPI_VAR_REF(msg).netif = netif;
1671 NETIFAPI_VAR_REF(msg).msg.ip6_state.state = ra_enable;
1672
1673 err = tcpip_api_call(netifapi_do_set_ra_enable, &API_VAR_REF(msg).call);
1674 NETIFAPI_VAR_FREE(msg);
1675 return err;
1676 }
1677
1678 static err_t
netifapi_do_set_ipv6_forwarding(struct tcpip_api_call_data * m)1679 netifapi_do_set_ipv6_forwarding(struct tcpip_api_call_data *m)
1680 {
1681 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1682 struct netif *nif = msg->netif;
1683 u8_t forwarding = msg->msg.ip6_state.state;
1684
1685 nif->forwarding = forwarding;
1686 return ERR_OK;
1687 }
1688
1689 err_t
netifapi_set_ipv6_forwarding(struct netif * netif,u8_t forwarding)1690 netifapi_set_ipv6_forwarding(struct netif *netif, u8_t forwarding)
1691 {
1692 err_t err;
1693 NETIFAPI_VAR_DECLARE(msg);
1694
1695 LWIP_ERROR("netifapi_set_ipv6_forwarding : invalid arguments \n", (netif != NULL), return ERR_ARG);
1696
1697 NETIFAPI_VAR_ALLOC(msg);
1698
1699 NETIFAPI_VAR_REF(msg).netif = netif;
1700 NETIFAPI_VAR_REF(msg).msg.ip6_state.state = forwarding;
1701
1702 err = tcpip_api_call(netifapi_do_set_ipv6_forwarding, &API_VAR_REF(msg).call);
1703 NETIFAPI_VAR_FREE(msg);
1704 return err;
1705 }
1706
1707 static err_t
netifapi_do_set_accept_ra(struct tcpip_api_call_data * m)1708 netifapi_do_set_accept_ra(struct tcpip_api_call_data *m)
1709 {
1710 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1711 struct netif *nif = msg->netif;
1712 u8_t accept_ra = msg->msg.ip6_state.state;
1713
1714 nif->accept_ra = accept_ra;
1715 return ERR_OK;
1716 }
1717
1718 err_t
netifapi_set_accept_ra(struct netif * netif,u8_t accept_ra)1719 netifapi_set_accept_ra(struct netif *netif, u8_t accept_ra)
1720 {
1721 err_t err;
1722 NETIFAPI_VAR_DECLARE(msg);
1723
1724 LWIP_ERROR("netifapi_set_ipv6_forwarding : invalid arguments \n", (netif != NULL), return ERR_ARG);
1725
1726 NETIFAPI_VAR_ALLOC(msg);
1727
1728 NETIFAPI_VAR_REF(msg).netif = netif;
1729 NETIFAPI_VAR_REF(msg).msg.ip6_state.state = accept_ra;
1730
1731 err = tcpip_api_call(netifapi_do_set_accept_ra, &API_VAR_REF(msg).call);
1732 NETIFAPI_VAR_FREE(msg);
1733 return err;
1734 }
1735 #endif /* LWIP_ND6_ROUTER */
1736
1737 /*
1738 * These APIs will be responsible for adding , deleting and querying the
1739 * neighbor cache when IPv6 is enabled
1740 */
1741 #if LWIP_NETIF_NBR_CACHE_API
1742 static err_t
netifapi_do_add_ipv6_neighbor(struct tcpip_api_call_data * m)1743 netifapi_do_add_ipv6_neighbor(struct tcpip_api_call_data *m)
1744 {
1745 err_t err;
1746 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1747 struct ipv6_neighbor *nb = msg->msg.ipv6_tables_access_params.nbrinfo;
1748 struct nd6_neighbor_info nd6nbr;
1749
1750 nd6nbr.curstate = nb->curstate;
1751 nd6nbr.hwlen = nb->hwlen;
1752 nd6nbr.reachabletime = nb->reachabletime;
1753
1754 if (memcpy_s(nd6nbr.hwaddr, NETIF_MAX_HWADDR_LEN, nb->hwaddr, nb->hwlen) != EOK) {
1755 return ERR_MEM;
1756 }
1757 ip6_addr_set(&(nd6nbr.nbripaddr), &(nb->nbripaddr));
1758
1759 err = nd6_add_neighbor_cache_entry_manually(msg->netif, &nd6nbr);
1760 return err;
1761 }
1762
1763 static err_t
netifapi_do_del_ipv6_neighbor(struct tcpip_api_call_data * m)1764 netifapi_do_del_ipv6_neighbor(struct tcpip_api_call_data *m)
1765 {
1766 err_t err;
1767 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1768 struct ip6_addr *nbrip = msg->msg.ipv6_tables_access_params.nodeip;
1769
1770 err = nd6_del_neighbor_cache_entry_manually(msg->netif, nbrip);
1771 return err;
1772 }
1773
1774 static err_t
netifapi_do_query_ipv6_neighbor(struct tcpip_api_call_data * m)1775 netifapi_do_query_ipv6_neighbor(struct tcpip_api_call_data *m)
1776 {
1777 err_t err;
1778 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1779 struct ipv6_neighbor *nb = msg->msg.ipv6_tables_access_params.nbrinfo;
1780 struct ip6_addr *nbrip = msg->msg.ipv6_tables_access_params.nodeip;
1781
1782 struct nd6_neighbor_info nd6nbr;
1783
1784 err = nd6_get_neighbor_cache_info(msg->netif, nbrip, &nd6nbr);
1785 if (err == ERR_OK) {
1786 /* Copy the info */
1787 nb->curstate = nd6nbr.curstate;
1788 nb->hwlen = nd6nbr.hwlen;
1789 nb->reachabletime = nd6nbr.reachabletime;
1790
1791 if (memcpy_s(nb->hwaddr, NETIF_MAX_HWADDR_LEN, nd6nbr.hwaddr, nd6nbr.hwlen) != EOK) {
1792 return ERR_MEM;
1793 }
1794 nb->hwlen = nd6nbr.hwlen;
1795
1796 ip6_addr_set(&(nb->nbripaddr), &(nd6nbr.nbripaddr));
1797 }
1798
1799 return err;
1800 }
1801
1802 err_t
netifapi_add_ipv6_neighbor(struct netif * netif,struct ipv6_neighbor * nbr)1803 netifapi_add_ipv6_neighbor(struct netif *netif, struct ipv6_neighbor *nbr)
1804 {
1805 err_t err;
1806 NETIFAPI_VAR_DECLARE(msg);
1807
1808 LWIP_ERROR("netifapi_add_ipv6_neighbor : invalid arguments \n", \
1809 ((netif != NULL) && (nbr != NULL)), return ERR_ARG);
1810
1811 LWIP_ERROR("netifapi_add_ipv6_neighbor : MAC len is invalid \n", \
1812 ((nbr->hwlen <= NETIF_MAX_HWADDR_LEN)), return ERR_VAL);
1813
1814 NETIFAPI_VAR_ALLOC(msg);
1815
1816 if ((nbr->curstate != ND6_STATE_REACHABLE)
1817 #if LWIP_ND6_STATIC_NBR
1818 && (nbr->curstate != ND6_STATE_PERMANENT)
1819 #endif
1820 ) {
1821 LWIP_ERROR("netifapi_add_ipv6_neighbor : invalid sate \n", 0, return ERR_VAL);
1822 }
1823
1824 #if LWIP_ND6_STATIC_NBR
1825 if ((nbr->curstate == ND6_STATE_PERMANENT) && (nbr->reachabletime != 0)) {
1826 LWIP_ERROR("netifapi_add_ipv6_neighbor : For static neighbors rechable time " \
1827 "must be set to 0 \n", 0, return ERR_VAL);
1828 }
1829 #endif
1830
1831 if ((nbr->curstate == ND6_STATE_REACHABLE) &&
1832 (nbr->reachabletime > LWIP_ND6_REACHABLE_TIME)) {
1833 LWIP_DEBUGF(NETIF_DEBUG, ("netifapi: Trying to set the reachable time[%u] " \
1834 "greater than configured[%d] after first expiry it will use the " \
1835 "configured one\n", nbr->reachabletime, LWIP_ND6_REACHABLE_TIME));
1836 }
1837
1838 (void)memset_s(&msg, sizeof(struct netifapi_msg), 0, sizeof(struct netifapi_msg));
1839 NETIFAPI_VAR_REF(msg).netif = netif;
1840 NETIFAPI_VAR_REF(msg).msg.ipv6_tables_access_params.nbrinfo = nbr;
1841
1842 err = tcpip_api_call(netifapi_do_add_ipv6_neighbor, &API_VAR_REF(msg).call);
1843 NETIFAPI_VAR_FREE(msg);
1844 return err;
1845
1846 /* Validate the input parameter */
1847 }
1848
1849 err_t
netifapi_del_ipv6_neighbor(struct netif * netif,struct ip6_addr * ipaddr)1850 netifapi_del_ipv6_neighbor(struct netif *netif, struct ip6_addr *ipaddr)
1851 {
1852 err_t err;
1853 NETIFAPI_VAR_DECLARE(msg);
1854
1855 LWIP_ERROR("netifapi_del_ipv6_neighbor : invalid arguments \n", \
1856 ((netif != NULL) && (ipaddr != NULL)), return ERR_ARG);
1857
1858 NETIFAPI_VAR_ALLOC(msg);
1859
1860 (void)memset_s(&msg, sizeof(struct netifapi_msg), 0, sizeof(struct netifapi_msg));
1861 NETIFAPI_VAR_REF(msg).netif = netif;
1862 NETIFAPI_VAR_REF(msg).msg.ipv6_tables_access_params.nodeip = ipaddr;
1863
1864 err = tcpip_api_call(netifapi_do_del_ipv6_neighbor, &API_VAR_REF(msg).call);
1865 NETIFAPI_VAR_FREE(msg);
1866 return err;
1867 }
1868
1869 err_t
netifapi_query_ipv6_neighbor(struct netif * netif,struct ip6_addr * ipaddr,struct ipv6_neighbor * nbrinfo)1870 netifapi_query_ipv6_neighbor(struct netif *netif, struct ip6_addr *ipaddr,
1871 struct ipv6_neighbor *nbrinfo)
1872 {
1873 err_t err;
1874 NETIFAPI_VAR_DECLARE(msg);
1875
1876 LWIP_ERROR("netifapi_del_ipv6_neighbor : invalid arguments \n", \
1877 ((netif != NULL) && (ipaddr != NULL) && (nbrinfo != NULL)), return ERR_ARG);
1878
1879 NETIFAPI_VAR_ALLOC(msg);
1880
1881 (void)memset_s(&msg, sizeof(struct netifapi_msg), 0, sizeof(struct netifapi_msg));
1882 NETIFAPI_VAR_REF(msg).netif = netif;
1883 NETIFAPI_VAR_REF(msg).msg.ipv6_tables_access_params.nodeip = ipaddr;
1884 NETIFAPI_VAR_REF(msg).msg.ipv6_tables_access_params.nbrinfo = nbrinfo;
1885
1886 err = tcpip_api_call(netifapi_do_query_ipv6_neighbor, &API_VAR_REF(msg).call);
1887 NETIFAPI_VAR_FREE(msg);
1888 return err;
1889 }
1890 #endif /* LWIP_NETIF_NBR_CACHE_API */
1891 #endif /* LWIP_IPV6 */
1892
1893 #if LWIP_LOWPOWER
1894 static err_t
netifapi_do_set_lowpower_mod(struct tcpip_api_call_data * m)1895 netifapi_do_set_lowpower_mod(struct tcpip_api_call_data *m)
1896 {
1897 struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
1898 enum lowpower_mod mod = msg->msg.lp.mod;
1899 set_lowpower_mod(mod);
1900 return ERR_OK;
1901 }
1902
1903 err_t
netifapi_enable_lowpower(void)1904 netifapi_enable_lowpower(void)
1905 {
1906 err_t err;
1907 NETIFAPI_VAR_DECLARE(msg);
1908
1909 NETIFAPI_VAR_ALLOC(msg);
1910
1911 NETIFAPI_VAR_REF(msg).msg.lp.mod = LOW_TMR_LOWPOWER_MOD;
1912
1913 err = tcpip_api_call(netifapi_do_set_lowpower_mod, &API_VAR_REF(msg).call);
1914 NETIFAPI_VAR_FREE(msg);
1915 return err;
1916 }
1917
1918 err_t
netifapi_disable_lowpower(void)1919 netifapi_disable_lowpower(void)
1920 {
1921 err_t err;
1922 NETIFAPI_VAR_DECLARE(msg);
1923
1924 NETIFAPI_VAR_ALLOC(msg);
1925
1926 NETIFAPI_VAR_REF(msg).msg.lp.mod = LOW_TMR_NORMAL_MOD;
1927
1928 err = tcpip_api_call(netifapi_do_set_lowpower_mod, &API_VAR_REF(msg).call);
1929 NETIFAPI_VAR_FREE(msg);
1930 return err;
1931 }
1932 #endif /* LWIP_LOWPOWER */
1933
1934 #endif /* LWIP_NETIF_API */
1935