xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.0.2/src/api/netifapi.c (revision 167494296f0543431a51b6b1b83e957045294e05)
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 #include "lwip/opt.h"
42 
43 #if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
44 
45 #include "lwip/netifapi.h"
46 #include "lwip/memp.h"
47 #include "lwip/priv/tcpip_priv.h"
48 
49 #define NETIFAPI_VAR_REF(name)      API_VAR_REF(name)
50 #define NETIFAPI_VAR_DECLARE(name)  API_VAR_DECLARE(struct netifapi_msg, name)
51 #define NETIFAPI_VAR_ALLOC(name)    API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
52 #define NETIFAPI_VAR_FREE(name)     API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
53 
54 /**
55  * Call netif_add() inside the tcpip_thread context.
56  */
57 static err_t
58 netifapi_do_netif_add(struct tcpip_api_call_data *m)
59 {
60   /* cast through void* to silence alignment warnings.
61    * We know it works because the structs have been instantiated as struct netifapi_msg */
62   struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
63 
64   if (!netif_add( msg->netif,
65 #if LWIP_IPV4
66                   API_EXPR_REF(msg->msg.add.ipaddr),
67                   API_EXPR_REF(msg->msg.add.netmask),
68                   API_EXPR_REF(msg->msg.add.gw),
69 #endif /* LWIP_IPV4 */
70                   msg->msg.add.state,
71                   msg->msg.add.init,
72                   msg->msg.add.input)) {
73     return ERR_IF;
74   } else {
75     return ERR_OK;
76   }
77 }
78 
79 #if LWIP_IPV4
80 /**
81  * Call netif_set_addr() inside the tcpip_thread context.
82  */
83 static err_t
84 netifapi_do_netif_set_addr(struct tcpip_api_call_data *m)
85 {
86   /* cast through void* to silence alignment warnings.
87    * We know it works because the structs have been instantiated as struct netifapi_msg */
88   struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
89 
90   netif_set_addr( msg->netif,
91                   API_EXPR_REF(msg->msg.add.ipaddr),
92                   API_EXPR_REF(msg->msg.add.netmask),
93                   API_EXPR_REF(msg->msg.add.gw));
94   return ERR_OK;
95 }
96 #endif /* LWIP_IPV4 */
97 
98 /**
99  * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
100  * tcpip_thread context.
101  */
102 static err_t
103 netifapi_do_netif_common(struct tcpip_api_call_data *m)
104 {
105   /* cast through void* to silence alignment warnings.
106    * We know it works because the structs have been instantiated as struct netifapi_msg */
107   struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m;
108 
109   if (msg->msg.common.errtfunc != NULL) {
110     return msg->msg.common.errtfunc(msg->netif);
111   } else {
112     msg->msg.common.voidfunc(msg->netif);
113     return ERR_OK;
114   }
115 }
116 
117 /**
118  * @ingroup netifapi_netif
119  * Call netif_add() in a thread-safe way by running that function inside the
120  * tcpip_thread context.
121  *
122  * @note for params @see netif_add()
123  */
124 err_t
125 netifapi_netif_add(struct netif *netif,
126 #if LWIP_IPV4
127                    const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
128 #endif /* LWIP_IPV4 */
129                    void *state, netif_init_fn init, netif_input_fn input)
130 {
131   err_t err;
132   NETIFAPI_VAR_DECLARE(msg);
133   NETIFAPI_VAR_ALLOC(msg);
134 
135 #if LWIP_IPV4
136   if (ipaddr == NULL) {
137     ipaddr = IP4_ADDR_ANY4;
138   }
139   if (netmask == NULL) {
140     netmask = IP4_ADDR_ANY4;
141   }
142   if (gw == NULL) {
143     gw = IP4_ADDR_ANY4;
144   }
145 #endif /* LWIP_IPV4 */
146 
147   NETIFAPI_VAR_REF(msg).netif = netif;
148 #if LWIP_IPV4
149   NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
150   NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
151   NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
152 #endif /* LWIP_IPV4 */
153   NETIFAPI_VAR_REF(msg).msg.add.state   = state;
154   NETIFAPI_VAR_REF(msg).msg.add.init    = init;
155   NETIFAPI_VAR_REF(msg).msg.add.input   = input;
156   err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
157   NETIFAPI_VAR_FREE(msg);
158   return err;
159 }
160 
161 #if LWIP_IPV4
162 /**
163  * @ingroup netifapi_netif
164  * Call netif_set_addr() in a thread-safe way by running that function inside the
165  * tcpip_thread context.
166  *
167  * @note for params @see netif_set_addr()
168  */
169 err_t
170 netifapi_netif_set_addr(struct netif *netif,
171                         const ip4_addr_t *ipaddr,
172                         const ip4_addr_t *netmask,
173                         const ip4_addr_t *gw)
174 {
175   err_t err;
176   NETIFAPI_VAR_DECLARE(msg);
177   NETIFAPI_VAR_ALLOC(msg);
178 
179   if (ipaddr == NULL) {
180     ipaddr = IP4_ADDR_ANY4;
181   }
182   if (netmask == NULL) {
183     netmask = IP4_ADDR_ANY4;
184   }
185   if (gw == NULL) {
186     gw = IP4_ADDR_ANY4;
187   }
188 
189   NETIFAPI_VAR_REF(msg).netif = netif;
190   NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
191   NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
192   NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
193   err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
194   NETIFAPI_VAR_FREE(msg);
195   return err;
196 }
197 #endif /* LWIP_IPV4 */
198 
199 /**
200  * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
201  * way by running that function inside the tcpip_thread context.
202  *
203  * @note use only for functions where there is only "netif" parameter.
204  */
205 err_t
206 netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
207                        netifapi_errt_fn errtfunc)
208 {
209   err_t err;
210   NETIFAPI_VAR_DECLARE(msg);
211   NETIFAPI_VAR_ALLOC(msg);
212 
213   NETIFAPI_VAR_REF(msg).netif = netif;
214   NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
215   NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
216   err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
217   NETIFAPI_VAR_FREE(msg);
218   return err;
219 }
220 
221 #endif /* LWIP_NETIF_API */
222