xref: /btstack/3rd-party/lwip/core/src/api/netifapi.c (revision 97dc5e692c7d94a280158af58036a0efee5b0e56)
1*97dc5e69SMatthias Ringwald /**
2*97dc5e69SMatthias Ringwald  * @file
3*97dc5e69SMatthias Ringwald  * Network Interface Sequential API module
4*97dc5e69SMatthias Ringwald  *
5*97dc5e69SMatthias Ringwald  * @defgroup netifapi NETIF API
6*97dc5e69SMatthias Ringwald  * @ingroup sequential_api
7*97dc5e69SMatthias Ringwald  * Thread-safe functions to be called from non-TCPIP threads
8*97dc5e69SMatthias Ringwald  *
9*97dc5e69SMatthias Ringwald  * @defgroup netifapi_netif NETIF related
10*97dc5e69SMatthias Ringwald  * @ingroup netifapi
11*97dc5e69SMatthias Ringwald  * To be called from non-TCPIP threads
12*97dc5e69SMatthias Ringwald  */
13*97dc5e69SMatthias Ringwald 
14*97dc5e69SMatthias Ringwald /*
15*97dc5e69SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without modification,
16*97dc5e69SMatthias Ringwald  * are permitted provided that the following conditions are met:
17*97dc5e69SMatthias Ringwald  *
18*97dc5e69SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright notice,
19*97dc5e69SMatthias Ringwald  *    this list of conditions and the following disclaimer.
20*97dc5e69SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright notice,
21*97dc5e69SMatthias Ringwald  *    this list of conditions and the following disclaimer in the documentation
22*97dc5e69SMatthias Ringwald  *    and/or other materials provided with the distribution.
23*97dc5e69SMatthias Ringwald  * 3. The name of the author may not be used to endorse or promote products
24*97dc5e69SMatthias Ringwald  *    derived from this software without specific prior written permission.
25*97dc5e69SMatthias Ringwald  *
26*97dc5e69SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
27*97dc5e69SMatthias Ringwald  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28*97dc5e69SMatthias Ringwald  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
29*97dc5e69SMatthias Ringwald  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30*97dc5e69SMatthias Ringwald  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
31*97dc5e69SMatthias Ringwald  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32*97dc5e69SMatthias Ringwald  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33*97dc5e69SMatthias Ringwald  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34*97dc5e69SMatthias Ringwald  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35*97dc5e69SMatthias Ringwald  * OF SUCH DAMAGE.
36*97dc5e69SMatthias Ringwald  *
37*97dc5e69SMatthias Ringwald  * This file is part of the lwIP TCP/IP stack.
38*97dc5e69SMatthias Ringwald  *
39*97dc5e69SMatthias Ringwald  */
40*97dc5e69SMatthias Ringwald 
41*97dc5e69SMatthias Ringwald #include "lwip/opt.h"
42*97dc5e69SMatthias Ringwald 
43*97dc5e69SMatthias Ringwald #if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
44*97dc5e69SMatthias Ringwald 
45*97dc5e69SMatthias Ringwald #include "lwip/etharp.h"
46*97dc5e69SMatthias Ringwald #include "lwip/netifapi.h"
47*97dc5e69SMatthias Ringwald #include "lwip/memp.h"
48*97dc5e69SMatthias Ringwald #include "lwip/priv/tcpip_priv.h"
49*97dc5e69SMatthias Ringwald 
50*97dc5e69SMatthias Ringwald #include <string.h> /* strncpy */
51*97dc5e69SMatthias Ringwald 
52*97dc5e69SMatthias Ringwald #define NETIFAPI_VAR_REF(name)      API_VAR_REF(name)
53*97dc5e69SMatthias Ringwald #define NETIFAPI_VAR_DECLARE(name)  API_VAR_DECLARE(struct netifapi_msg, name)
54*97dc5e69SMatthias Ringwald #define NETIFAPI_VAR_ALLOC(name)    API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
55*97dc5e69SMatthias Ringwald #define NETIFAPI_VAR_FREE(name)     API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
56*97dc5e69SMatthias Ringwald 
57*97dc5e69SMatthias Ringwald /**
58*97dc5e69SMatthias Ringwald  * Call netif_add() inside the tcpip_thread context.
59*97dc5e69SMatthias Ringwald  */
60*97dc5e69SMatthias Ringwald static err_t
netifapi_do_netif_add(struct tcpip_api_call_data * m)61*97dc5e69SMatthias Ringwald netifapi_do_netif_add(struct tcpip_api_call_data *m)
62*97dc5e69SMatthias Ringwald {
63*97dc5e69SMatthias Ringwald   /* cast through void* to silence alignment warnings.
64*97dc5e69SMatthias Ringwald    * We know it works because the structs have been instantiated as struct netifapi_msg */
65*97dc5e69SMatthias Ringwald   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
66*97dc5e69SMatthias Ringwald 
67*97dc5e69SMatthias Ringwald   if (!netif_add( msg->netif,
68*97dc5e69SMatthias Ringwald #if LWIP_IPV4
69*97dc5e69SMatthias Ringwald                   API_EXPR_REF(msg->msg.add.ipaddr),
70*97dc5e69SMatthias Ringwald                   API_EXPR_REF(msg->msg.add.netmask),
71*97dc5e69SMatthias Ringwald                   API_EXPR_REF(msg->msg.add.gw),
72*97dc5e69SMatthias Ringwald #endif /* LWIP_IPV4 */
73*97dc5e69SMatthias Ringwald                   msg->msg.add.state,
74*97dc5e69SMatthias Ringwald                   msg->msg.add.init,
75*97dc5e69SMatthias Ringwald                   msg->msg.add.input)) {
76*97dc5e69SMatthias Ringwald     return ERR_IF;
77*97dc5e69SMatthias Ringwald   } else {
78*97dc5e69SMatthias Ringwald     return ERR_OK;
79*97dc5e69SMatthias Ringwald   }
80*97dc5e69SMatthias Ringwald }
81*97dc5e69SMatthias Ringwald 
82*97dc5e69SMatthias Ringwald #if LWIP_IPV4
83*97dc5e69SMatthias Ringwald /**
84*97dc5e69SMatthias Ringwald  * Call netif_set_addr() inside the tcpip_thread context.
85*97dc5e69SMatthias Ringwald  */
86*97dc5e69SMatthias Ringwald static err_t
netifapi_do_netif_set_addr(struct tcpip_api_call_data * m)87*97dc5e69SMatthias Ringwald netifapi_do_netif_set_addr(struct tcpip_api_call_data *m)
88*97dc5e69SMatthias Ringwald {
89*97dc5e69SMatthias Ringwald   /* cast through void* to silence alignment warnings.
90*97dc5e69SMatthias Ringwald    * We know it works because the structs have been instantiated as struct netifapi_msg */
91*97dc5e69SMatthias Ringwald   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
92*97dc5e69SMatthias Ringwald 
93*97dc5e69SMatthias Ringwald   netif_set_addr( msg->netif,
94*97dc5e69SMatthias Ringwald                   API_EXPR_REF(msg->msg.add.ipaddr),
95*97dc5e69SMatthias Ringwald                   API_EXPR_REF(msg->msg.add.netmask),
96*97dc5e69SMatthias Ringwald                   API_EXPR_REF(msg->msg.add.gw));
97*97dc5e69SMatthias Ringwald   return ERR_OK;
98*97dc5e69SMatthias Ringwald }
99*97dc5e69SMatthias Ringwald #endif /* LWIP_IPV4 */
100*97dc5e69SMatthias Ringwald 
101*97dc5e69SMatthias Ringwald /**
102*97dc5e69SMatthias Ringwald * Call netif_name_to_index() inside the tcpip_thread context.
103*97dc5e69SMatthias Ringwald */
104*97dc5e69SMatthias Ringwald static err_t
netifapi_do_name_to_index(struct tcpip_api_call_data * m)105*97dc5e69SMatthias Ringwald netifapi_do_name_to_index(struct tcpip_api_call_data *m)
106*97dc5e69SMatthias Ringwald {
107*97dc5e69SMatthias Ringwald   /* cast through void* to silence alignment warnings.
108*97dc5e69SMatthias Ringwald    * We know it works because the structs have been instantiated as struct netifapi_msg */
109*97dc5e69SMatthias Ringwald   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
110*97dc5e69SMatthias Ringwald 
111*97dc5e69SMatthias Ringwald   msg->msg.ifs.index = netif_name_to_index(msg->msg.ifs.name);
112*97dc5e69SMatthias Ringwald   return ERR_OK;
113*97dc5e69SMatthias Ringwald }
114*97dc5e69SMatthias Ringwald 
115*97dc5e69SMatthias Ringwald /**
116*97dc5e69SMatthias Ringwald * Call netif_index_to_name() inside the tcpip_thread context.
117*97dc5e69SMatthias Ringwald */
118*97dc5e69SMatthias Ringwald static err_t
netifapi_do_index_to_name(struct tcpip_api_call_data * m)119*97dc5e69SMatthias Ringwald netifapi_do_index_to_name(struct tcpip_api_call_data *m)
120*97dc5e69SMatthias Ringwald {
121*97dc5e69SMatthias Ringwald   /* cast through void* to silence alignment warnings.
122*97dc5e69SMatthias Ringwald    * We know it works because the structs have been instantiated as struct netifapi_msg */
123*97dc5e69SMatthias Ringwald   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
124*97dc5e69SMatthias Ringwald 
125*97dc5e69SMatthias Ringwald   if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) {
126*97dc5e69SMatthias Ringwald     /* return failure via empty name */
127*97dc5e69SMatthias Ringwald     msg->msg.ifs.name[0] = '\0';
128*97dc5e69SMatthias Ringwald   }
129*97dc5e69SMatthias Ringwald   return ERR_OK;
130*97dc5e69SMatthias Ringwald }
131*97dc5e69SMatthias Ringwald 
132*97dc5e69SMatthias Ringwald /**
133*97dc5e69SMatthias Ringwald  * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
134*97dc5e69SMatthias Ringwald  * tcpip_thread context.
135*97dc5e69SMatthias Ringwald  */
136*97dc5e69SMatthias Ringwald static err_t
netifapi_do_netif_common(struct tcpip_api_call_data * m)137*97dc5e69SMatthias Ringwald netifapi_do_netif_common(struct tcpip_api_call_data *m)
138*97dc5e69SMatthias Ringwald {
139*97dc5e69SMatthias Ringwald   /* cast through void* to silence alignment warnings.
140*97dc5e69SMatthias Ringwald    * We know it works because the structs have been instantiated as struct netifapi_msg */
141*97dc5e69SMatthias Ringwald   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
142*97dc5e69SMatthias Ringwald 
143*97dc5e69SMatthias Ringwald   if (msg->msg.common.errtfunc != NULL) {
144*97dc5e69SMatthias Ringwald     return msg->msg.common.errtfunc(msg->netif);
145*97dc5e69SMatthias Ringwald   } else {
146*97dc5e69SMatthias Ringwald     msg->msg.common.voidfunc(msg->netif);
147*97dc5e69SMatthias Ringwald     return ERR_OK;
148*97dc5e69SMatthias Ringwald   }
149*97dc5e69SMatthias Ringwald }
150*97dc5e69SMatthias Ringwald 
151*97dc5e69SMatthias Ringwald #if LWIP_ARP && LWIP_IPV4
152*97dc5e69SMatthias Ringwald /**
153*97dc5e69SMatthias Ringwald  * @ingroup netifapi_arp
154*97dc5e69SMatthias Ringwald  * Add or update an entry in the ARP cache.
155*97dc5e69SMatthias Ringwald  * For an update, ipaddr is used to find the cache entry.
156*97dc5e69SMatthias Ringwald  *
157*97dc5e69SMatthias Ringwald  * @param ipaddr IPv4 address of cache entry
158*97dc5e69SMatthias Ringwald  * @param ethaddr hardware address mapped to ipaddr
159*97dc5e69SMatthias Ringwald  * @param type type of ARP cache entry
160*97dc5e69SMatthias Ringwald  * @return ERR_OK: entry added/updated, else error from err_t
161*97dc5e69SMatthias Ringwald  */
162*97dc5e69SMatthias Ringwald err_t
netifapi_arp_add(const ip4_addr_t * ipaddr,struct eth_addr * ethaddr,enum netifapi_arp_entry type)163*97dc5e69SMatthias Ringwald netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type)
164*97dc5e69SMatthias Ringwald {
165*97dc5e69SMatthias Ringwald   err_t err;
166*97dc5e69SMatthias Ringwald 
167*97dc5e69SMatthias Ringwald   /* We only support permanent entries currently */
168*97dc5e69SMatthias Ringwald   LWIP_UNUSED_ARG(type);
169*97dc5e69SMatthias Ringwald 
170*97dc5e69SMatthias Ringwald #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
171*97dc5e69SMatthias Ringwald   LOCK_TCPIP_CORE();
172*97dc5e69SMatthias Ringwald   err = etharp_add_static_entry(ipaddr, ethaddr);
173*97dc5e69SMatthias Ringwald   UNLOCK_TCPIP_CORE();
174*97dc5e69SMatthias Ringwald #else
175*97dc5e69SMatthias Ringwald   /* @todo add new vars to struct netifapi_msg and create a 'do' func */
176*97dc5e69SMatthias Ringwald   LWIP_UNUSED_ARG(ipaddr);
177*97dc5e69SMatthias Ringwald   LWIP_UNUSED_ARG(ethaddr);
178*97dc5e69SMatthias Ringwald   err = ERR_VAL;
179*97dc5e69SMatthias Ringwald #endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
180*97dc5e69SMatthias Ringwald 
181*97dc5e69SMatthias Ringwald   return err;
182*97dc5e69SMatthias Ringwald }
183*97dc5e69SMatthias Ringwald 
184*97dc5e69SMatthias Ringwald /**
185*97dc5e69SMatthias Ringwald  * @ingroup netifapi_arp
186*97dc5e69SMatthias Ringwald  * Remove an entry in the ARP cache identified by ipaddr
187*97dc5e69SMatthias Ringwald  *
188*97dc5e69SMatthias Ringwald  * @param ipaddr IPv4 address of cache entry
189*97dc5e69SMatthias Ringwald  * @param type type of ARP cache entry
190*97dc5e69SMatthias Ringwald  * @return ERR_OK: entry removed, else error from err_t
191*97dc5e69SMatthias Ringwald  */
192*97dc5e69SMatthias Ringwald err_t
netifapi_arp_remove(const ip4_addr_t * ipaddr,enum netifapi_arp_entry type)193*97dc5e69SMatthias Ringwald netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type)
194*97dc5e69SMatthias Ringwald {
195*97dc5e69SMatthias Ringwald   err_t err;
196*97dc5e69SMatthias Ringwald 
197*97dc5e69SMatthias Ringwald   /* We only support permanent entries currently */
198*97dc5e69SMatthias Ringwald   LWIP_UNUSED_ARG(type);
199*97dc5e69SMatthias Ringwald 
200*97dc5e69SMatthias Ringwald #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
201*97dc5e69SMatthias Ringwald   LOCK_TCPIP_CORE();
202*97dc5e69SMatthias Ringwald   err = etharp_remove_static_entry(ipaddr);
203*97dc5e69SMatthias Ringwald   UNLOCK_TCPIP_CORE();
204*97dc5e69SMatthias Ringwald #else
205*97dc5e69SMatthias Ringwald   /* @todo add new vars to struct netifapi_msg and create a 'do' func */
206*97dc5e69SMatthias Ringwald   LWIP_UNUSED_ARG(ipaddr);
207*97dc5e69SMatthias Ringwald   err = ERR_VAL;
208*97dc5e69SMatthias Ringwald #endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
209*97dc5e69SMatthias Ringwald 
210*97dc5e69SMatthias Ringwald   return err;
211*97dc5e69SMatthias Ringwald }
212*97dc5e69SMatthias Ringwald #endif /* LWIP_ARP && LWIP_IPV4 */
213*97dc5e69SMatthias Ringwald 
214*97dc5e69SMatthias Ringwald /**
215*97dc5e69SMatthias Ringwald  * @ingroup netifapi_netif
216*97dc5e69SMatthias Ringwald  * Call netif_add() in a thread-safe way by running that function inside the
217*97dc5e69SMatthias Ringwald  * tcpip_thread context.
218*97dc5e69SMatthias Ringwald  *
219*97dc5e69SMatthias Ringwald  * @note for params @see netif_add()
220*97dc5e69SMatthias Ringwald  */
221*97dc5e69SMatthias Ringwald err_t
netifapi_netif_add(struct netif * netif,const ip4_addr_t * ipaddr,const ip4_addr_t * netmask,const ip4_addr_t * gw,void * state,netif_init_fn init,netif_input_fn input)222*97dc5e69SMatthias Ringwald netifapi_netif_add(struct netif *netif,
223*97dc5e69SMatthias Ringwald #if LWIP_IPV4
224*97dc5e69SMatthias Ringwald                    const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
225*97dc5e69SMatthias Ringwald #endif /* LWIP_IPV4 */
226*97dc5e69SMatthias Ringwald                    void *state, netif_init_fn init, netif_input_fn input)
227*97dc5e69SMatthias Ringwald {
228*97dc5e69SMatthias Ringwald   err_t err;
229*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_DECLARE(msg);
230*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_ALLOC(msg);
231*97dc5e69SMatthias Ringwald 
232*97dc5e69SMatthias Ringwald #if LWIP_IPV4
233*97dc5e69SMatthias Ringwald   if (ipaddr == NULL) {
234*97dc5e69SMatthias Ringwald     ipaddr = IP4_ADDR_ANY4;
235*97dc5e69SMatthias Ringwald   }
236*97dc5e69SMatthias Ringwald   if (netmask == NULL) {
237*97dc5e69SMatthias Ringwald     netmask = IP4_ADDR_ANY4;
238*97dc5e69SMatthias Ringwald   }
239*97dc5e69SMatthias Ringwald   if (gw == NULL) {
240*97dc5e69SMatthias Ringwald     gw = IP4_ADDR_ANY4;
241*97dc5e69SMatthias Ringwald   }
242*97dc5e69SMatthias Ringwald #endif /* LWIP_IPV4 */
243*97dc5e69SMatthias Ringwald 
244*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).netif = netif;
245*97dc5e69SMatthias Ringwald #if LWIP_IPV4
246*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
247*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
248*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
249*97dc5e69SMatthias Ringwald #endif /* LWIP_IPV4 */
250*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.state   = state;
251*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.init    = init;
252*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.input   = input;
253*97dc5e69SMatthias Ringwald   err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
254*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_FREE(msg);
255*97dc5e69SMatthias Ringwald   return err;
256*97dc5e69SMatthias Ringwald }
257*97dc5e69SMatthias Ringwald 
258*97dc5e69SMatthias Ringwald #if LWIP_IPV4
259*97dc5e69SMatthias Ringwald /**
260*97dc5e69SMatthias Ringwald  * @ingroup netifapi_netif
261*97dc5e69SMatthias Ringwald  * Call netif_set_addr() in a thread-safe way by running that function inside the
262*97dc5e69SMatthias Ringwald  * tcpip_thread context.
263*97dc5e69SMatthias Ringwald  *
264*97dc5e69SMatthias Ringwald  * @note for params @see netif_set_addr()
265*97dc5e69SMatthias Ringwald  */
266*97dc5e69SMatthias Ringwald err_t
netifapi_netif_set_addr(struct netif * netif,const ip4_addr_t * ipaddr,const ip4_addr_t * netmask,const ip4_addr_t * gw)267*97dc5e69SMatthias Ringwald netifapi_netif_set_addr(struct netif *netif,
268*97dc5e69SMatthias Ringwald                         const ip4_addr_t *ipaddr,
269*97dc5e69SMatthias Ringwald                         const ip4_addr_t *netmask,
270*97dc5e69SMatthias Ringwald                         const ip4_addr_t *gw)
271*97dc5e69SMatthias Ringwald {
272*97dc5e69SMatthias Ringwald   err_t err;
273*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_DECLARE(msg);
274*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_ALLOC(msg);
275*97dc5e69SMatthias Ringwald 
276*97dc5e69SMatthias Ringwald   if (ipaddr == NULL) {
277*97dc5e69SMatthias Ringwald     ipaddr = IP4_ADDR_ANY4;
278*97dc5e69SMatthias Ringwald   }
279*97dc5e69SMatthias Ringwald   if (netmask == NULL) {
280*97dc5e69SMatthias Ringwald     netmask = IP4_ADDR_ANY4;
281*97dc5e69SMatthias Ringwald   }
282*97dc5e69SMatthias Ringwald   if (gw == NULL) {
283*97dc5e69SMatthias Ringwald     gw = IP4_ADDR_ANY4;
284*97dc5e69SMatthias Ringwald   }
285*97dc5e69SMatthias Ringwald 
286*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).netif = netif;
287*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
288*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
289*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
290*97dc5e69SMatthias Ringwald   err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
291*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_FREE(msg);
292*97dc5e69SMatthias Ringwald   return err;
293*97dc5e69SMatthias Ringwald }
294*97dc5e69SMatthias Ringwald #endif /* LWIP_IPV4 */
295*97dc5e69SMatthias Ringwald 
296*97dc5e69SMatthias Ringwald /**
297*97dc5e69SMatthias Ringwald  * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
298*97dc5e69SMatthias Ringwald  * way by running that function inside the tcpip_thread context.
299*97dc5e69SMatthias Ringwald  *
300*97dc5e69SMatthias Ringwald  * @note use only for functions where there is only "netif" parameter.
301*97dc5e69SMatthias Ringwald  */
302*97dc5e69SMatthias Ringwald err_t
netifapi_netif_common(struct netif * netif,netifapi_void_fn voidfunc,netifapi_errt_fn errtfunc)303*97dc5e69SMatthias Ringwald netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
304*97dc5e69SMatthias Ringwald                       netifapi_errt_fn errtfunc)
305*97dc5e69SMatthias Ringwald {
306*97dc5e69SMatthias Ringwald   err_t err;
307*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_DECLARE(msg);
308*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_ALLOC(msg);
309*97dc5e69SMatthias Ringwald 
310*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).netif = netif;
311*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
312*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
313*97dc5e69SMatthias Ringwald   err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
314*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_FREE(msg);
315*97dc5e69SMatthias Ringwald   return err;
316*97dc5e69SMatthias Ringwald }
317*97dc5e69SMatthias Ringwald 
318*97dc5e69SMatthias Ringwald /**
319*97dc5e69SMatthias Ringwald * @ingroup netifapi_netif
320*97dc5e69SMatthias Ringwald * Call netif_name_to_index() in a thread-safe way by running that function inside the
321*97dc5e69SMatthias Ringwald * tcpip_thread context.
322*97dc5e69SMatthias Ringwald *
323*97dc5e69SMatthias Ringwald * @param name the interface name of the netif
324*97dc5e69SMatthias Ringwald * @param idx output index of the found netif
325*97dc5e69SMatthias Ringwald */
326*97dc5e69SMatthias Ringwald err_t
netifapi_netif_name_to_index(const char * name,u8_t * idx)327*97dc5e69SMatthias Ringwald netifapi_netif_name_to_index(const char *name, u8_t *idx)
328*97dc5e69SMatthias Ringwald {
329*97dc5e69SMatthias Ringwald   err_t err;
330*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_DECLARE(msg);
331*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_ALLOC(msg);
332*97dc5e69SMatthias Ringwald 
333*97dc5e69SMatthias Ringwald   *idx = 0;
334*97dc5e69SMatthias Ringwald 
335*97dc5e69SMatthias Ringwald #if LWIP_MPU_COMPATIBLE
336*97dc5e69SMatthias Ringwald   strncpy(NETIFAPI_VAR_REF(msg).msg.ifs.name, name, NETIF_NAMESIZE - 1);
337*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0';
338*97dc5e69SMatthias Ringwald #else
339*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.ifs.name = LWIP_CONST_CAST(char *, name);
340*97dc5e69SMatthias Ringwald #endif /* LWIP_MPU_COMPATIBLE */
341*97dc5e69SMatthias Ringwald   err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call);
342*97dc5e69SMatthias Ringwald   if (!err) {
343*97dc5e69SMatthias Ringwald     *idx = NETIFAPI_VAR_REF(msg).msg.ifs.index;
344*97dc5e69SMatthias Ringwald   }
345*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_FREE(msg);
346*97dc5e69SMatthias Ringwald   return err;
347*97dc5e69SMatthias Ringwald }
348*97dc5e69SMatthias Ringwald 
349*97dc5e69SMatthias Ringwald /**
350*97dc5e69SMatthias Ringwald * @ingroup netifapi_netif
351*97dc5e69SMatthias Ringwald * Call netif_index_to_name() in a thread-safe way by running that function inside the
352*97dc5e69SMatthias Ringwald * tcpip_thread context.
353*97dc5e69SMatthias Ringwald *
354*97dc5e69SMatthias Ringwald * @param idx the interface index of the netif
355*97dc5e69SMatthias Ringwald * @param name output name of the found netif, empty '\0' string if netif not found.
356*97dc5e69SMatthias Ringwald *             name should be of at least NETIF_NAMESIZE bytes
357*97dc5e69SMatthias Ringwald */
358*97dc5e69SMatthias Ringwald err_t
netifapi_netif_index_to_name(u8_t idx,char * name)359*97dc5e69SMatthias Ringwald netifapi_netif_index_to_name(u8_t idx, char *name)
360*97dc5e69SMatthias Ringwald {
361*97dc5e69SMatthias Ringwald   err_t err;
362*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_DECLARE(msg);
363*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_ALLOC(msg);
364*97dc5e69SMatthias Ringwald 
365*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.ifs.index = idx;
366*97dc5e69SMatthias Ringwald #if !LWIP_MPU_COMPATIBLE
367*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_REF(msg).msg.ifs.name = name;
368*97dc5e69SMatthias Ringwald #endif /* LWIP_MPU_COMPATIBLE */
369*97dc5e69SMatthias Ringwald   err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call);
370*97dc5e69SMatthias Ringwald #if LWIP_MPU_COMPATIBLE
371*97dc5e69SMatthias Ringwald   if (!err) {
372*97dc5e69SMatthias Ringwald     strncpy(name, NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE - 1);
373*97dc5e69SMatthias Ringwald     name[NETIF_NAMESIZE - 1] = '\0';
374*97dc5e69SMatthias Ringwald   }
375*97dc5e69SMatthias Ringwald #endif /* LWIP_MPU_COMPATIBLE */
376*97dc5e69SMatthias Ringwald   NETIFAPI_VAR_FREE(msg);
377*97dc5e69SMatthias Ringwald   return err;
378*97dc5e69SMatthias Ringwald }
379*97dc5e69SMatthias Ringwald 
380*97dc5e69SMatthias Ringwald #endif /* LWIP_NETIF_API */
381