1 /*
2 * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <lwip/ip_addr.h>
9 #include <lwip/sockets.h>
10
11 #include "esp_check.h"
12 #include "esp_netif_lwip_internal.h"
13 #include "lwip/esp_netif_net_stack.h"
14
15
16 #include "esp_netif.h"
17 #include "esp_netif_private.h"
18 #include "esp_random.h"
19 #include "esp_system.h"
20
21 #include "lwip/tcpip.h"
22 #include "lwip/dhcp.h"
23 #include "lwip/ip_addr.h"
24 #include "lwip/ip6_addr.h"
25 #include "lwip/mld6.h"
26 #include "lwip/prot/mld6.h"
27 #include "lwip/nd6.h"
28 #include "lwip/snmp.h"
29 #include "lwip/priv/tcpip_priv.h"
30 #include "lwip/netif.h"
31 #include "lwip/etharp.h"
32 #if CONFIG_ESP_NETIF_BRIDGE_EN
33 #include "netif/bridgeif.h"
34 #endif // CONFIG_ESP_NETIF_BRIDGE_EN
35 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
36 #include "lwip/dns.h"
37 #endif // LWIP_DNS
38
39 #if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
40 #include "lwip_default_hooks.h"
41 #endif // CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
42
43 #include "esp_netif_lwip_ppp.h"
44 #if ESP_DHCPS
45 #include "dhcpserver/dhcpserver.h"
46 #include "dhcpserver/dhcpserver_options.h"
47 #endif
48 #include "netif/dhcp_state.h"
49 #include "esp_event.h"
50 #include "esp_log.h"
51 #if IP_NAPT
52 #include "lwip/lwip_napt.h"
53 #endif
54
55
56 //
57 // This is the main module implementing lwip interaction with esp-netif
58 //
59
60 #define ESP_NETIF_HOSTNAME_MAX_SIZE 32
61
62 #define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED)
63
64 /**
65 * @brief lwip thread safe tcpip function utility macros
66 */
67 #define _RUN_IN_LWIP_TASK(function, netif, param) { return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); }
68
69 /**
70 * @brief macros to check netif related data to evaluate interface type
71 */
72 #if CONFIG_PPP_SUPPORT
73 #define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) (netif->related_data && netif->related_data->is_point2point)
74 #else
75 #define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) false
76 #endif
77 #define _RUN_IN_LWIP_TASK_IF_SUPPORTED(function, netif, param) \
78 { \
79 if (_IS_NETIF_ANY_POINT2POINT_TYPE(netif)) { \
80 return ESP_ERR_NOT_SUPPORTED; \
81 } \
82 return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); \
83 }
84
85 /**
86 * @brief Utility macros to convert esp-ip addresses (both IPv6+IPv4 versions unconditionally)
87 * and lwip-ip addresses (contain only enabled portion of the address for each IP stack)
88 */
89
90 #if LWIP_IPV4 && LWIP_IPV6
91 #define ESPIP_TO_IP(espip, ip) memcpy((ip), (espip), sizeof(ip_addr_t));
92 #define IP_TO_ESPIP(ip, espip) memcpy((espip), (ip), sizeof(ip_addr_t));
93 #elif LWIP_IPV4
94 #define ESPIP_TO_IP(espip, ip) memcpy((ip), &((espip)->u_addr.ip4), sizeof(ip_addr_t));
95 #define IP_TO_ESPIP(ip, espip) do { memcpy(&((espip)->u_addr.ip4), (ip), sizeof(ip4_addr_t)); \
96 (espip)->type = ESP_IPADDR_TYPE_V4; \
97 } while(0)
98 #elif LWIP_IPV6
99 #define ESPIP_TO_IP(espip, ip) memcpy((ip), &((espip)->u_addr.ip6), sizeof(ip_addr_t));
100 #define IP_TO_ESPIP(ip, espip) do { memcpy(&((espip)->u_addr.ip6), (ip), sizeof(ip6_addr_t)); \
101 (espip)->type = ESP_IPADDR_TYPE_V6; \
102 } while(0)
103 #endif
104
105 /**
106 * @brief If netif protocol not enabled in menuconfig, log the error and return appropriate code indicating failure
107 */
108
109 #define LOG_NETIF_DISABLED_AND_DO(proto, action) \
110 do { \
111 ESP_LOGE(TAG, "%s not supported, please enable it in lwIP component configuration", proto); \
112 action; \
113 } while(0)
114
115 //
116 // Internal types
117 //
118 typedef enum esp_netif_action {
119 ESP_NETIF_UNDEF,
120 ESP_NETIF_STARTED,
121 ESP_NETIF_STOPPED,
122 ESP_NETIF_SET_DEFAULT,
123 } esp_netif_action_t;
124
125 //
126 // Internal variables for this module
127 //
128 static const char *TAG = "esp_netif_lwip";
129
130 #if LWIP_ESP_NETIF_DATA
131 static u8_t lwip_netif_client_id = 0xff;
132 #endif
133 static esp_netif_t *s_last_default_esp_netif = NULL;
134 static bool s_is_last_default_esp_netif_overridden = false;
135 static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL };
136
137 #if LWIP_IPV4
138 static void esp_netif_internal_dhcpc_cb(struct netif *netif);
139 #endif
140 #if LWIP_IPV6
141 static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index);
142 static void netif_set_mldv6_flag(struct netif *netif);
143 static void netif_unset_mldv6_flag(struct netif *netif);
144 #endif /* LWIP_IPV6 */
145
netif_callback_fn(struct netif * netif,netif_nsc_reason_t reason,const netif_ext_callback_args_t * args)146 static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
147 {
148 #if LWIP_IPV4
149 if (reason & DHCP_CB_CHANGE) {
150 esp_netif_internal_dhcpc_cb(netif);
151 }
152 #endif /* LWIP_IPV4 */
153 #if LWIP_IPV6
154 if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) {
155 s8_t addr_idx = args->ipv6_addr_state_changed.addr_index;
156 if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) {
157 /* address is valid -> call the callback function */
158 esp_netif_internal_nd6_cb(netif, addr_idx);
159 }
160 }
161 #endif /* #if LWIP_IPV6 */
162 }
163
164 #if LWIP_ESP_NETIF_DATA
alloc_client_data_id(esp_netif_api_msg_t * msg)165 static esp_err_t alloc_client_data_id(esp_netif_api_msg_t *msg)
166 {
167 uint8_t *client_data_id = msg->data;
168 *client_data_id = netif_alloc_client_data_id();
169 return ESP_OK;
170 }
171 #endif // LWIP_ESP_NETIF_DATA
172
set_lwip_netif_callback(struct esp_netif_api_msg_s * msg)173 static esp_err_t set_lwip_netif_callback(struct esp_netif_api_msg_s *msg)
174 {
175 (void)msg;
176 netif_add_ext_callback(&netif_callback, netif_callback_fn);
177 return ESP_OK;
178 }
179
remove_lwip_netif_callback(struct esp_netif_api_msg_s * msg)180 static esp_err_t remove_lwip_netif_callback(struct esp_netif_api_msg_s *msg)
181 {
182 (void)msg;
183 netif_remove_ext_callback(&netif_callback);
184 memset(&netif_callback, 0, sizeof(netif_callback));
185 return ESP_OK;
186 }
187
188 #ifdef CONFIG_LWIP_GARP_TMR_INTERVAL
189
netif_send_garp(void * arg)190 static void netif_send_garp(void *arg)
191 {
192 struct netif *netif = arg;
193 if (!ip4_addr_cmp(netif_ip4_addr(netif), IP4_ADDR_ANY4)) { // Send GARP requests only if we have a valid IP
194 etharp_gratuitous(netif);
195 }
196 sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif);
197 }
198
netif_set_garp_flag(struct netif * netif)199 static void netif_set_garp_flag(struct netif *netif)
200 {
201 sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif);
202 }
203
netif_unset_garp_flag(struct netif * netif)204 static void netif_unset_garp_flag(struct netif *netif)
205 {
206 sys_untimeout(netif_send_garp, netif);
207 }
208
209 #endif // CONFIG_LWIP_GARP_TMR_INTERVAL
210
211 #if !LWIP_TCPIP_CORE_LOCKING
212 static sys_sem_t api_sync_sem = NULL;
213 static sys_sem_t api_lock_sem = NULL;
214 #endif
215
216 /**
217 * @brief Api callback from tcpip thread used to call esp-netif
218 * function in lwip task context
219 */
esp_netif_api_cb(void * api_msg)220 static void esp_netif_api_cb(void *api_msg)
221 {
222 esp_netif_api_msg_t *msg = (esp_netif_api_msg_t *)api_msg;
223
224 if (!msg || !msg->api_fn) {
225 ESP_LOGD(TAG, "null msg/api_fn");
226 return;
227 }
228
229 msg->ret = msg->api_fn(msg);
230 ESP_LOGD(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret);
231 #if !LWIP_TCPIP_CORE_LOCKING
232 sys_sem_signal(&api_sync_sem);
233 #endif
234 }
235
236
237 /**
238 * @brief Initiates a tcpip remote call if called from another task
239 * or calls the function directly if executed from lwip task
240 */
esp_netif_lwip_ipc_call_msg(esp_netif_api_msg_t * msg)241 static inline esp_err_t esp_netif_lwip_ipc_call_msg(esp_netif_api_msg_t *msg)
242 {
243 if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) {
244 ESP_LOGD(TAG, "check: remote, if=%p fn=%p\n", msg->esp_netif, msg->api_fn);
245 #if LWIP_TCPIP_CORE_LOCKING
246 tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, msg, NULL);
247 #else
248 sys_arch_sem_wait(&api_lock_sem, 0);
249 tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, msg, &api_sync_sem);
250 sys_sem_signal(&api_lock_sem);
251 #endif /* LWIP_TCPIP_CORE_LOCKING */
252 return msg->ret;
253 }
254 ESP_LOGD(TAG, "check: local, if=%p fn=%p\n", msg->esp_netif, msg->api_fn);
255 return msg->api_fn(msg);
256 }
257
esp_netif_lwip_ipc_call(esp_netif_api_fn fn,esp_netif_t * netif,void * data)258 static inline esp_err_t esp_netif_lwip_ipc_call(esp_netif_api_fn fn, esp_netif_t* netif, void *data)
259 {
260 esp_netif_api_msg_t msg = {
261 .esp_netif = netif,
262 .data = data,
263 .api_fn = fn
264 };
265 return esp_netif_lwip_ipc_call_msg(&msg);
266 }
267
esp_netif_lwip_ipc_call_fn(esp_netif_api_fn fn,esp_netif_callback_fn user_fn,void * ctx)268 static inline esp_err_t esp_netif_lwip_ipc_call_fn(esp_netif_api_fn fn, esp_netif_callback_fn user_fn, void *ctx)
269 {
270 esp_netif_api_msg_t msg = {
271 .user_fn = user_fn,
272 .data = ctx,
273 .api_fn = fn
274 };
275 return esp_netif_lwip_ipc_call_msg(&msg);
276 }
277
esp_netif_lwip_ipc_no_args(esp_netif_api_fn fn)278 static inline esp_err_t esp_netif_lwip_ipc_no_args(esp_netif_api_fn fn)
279 {
280 esp_netif_api_msg_t msg = {
281 .api_fn = fn
282 };
283 return esp_netif_lwip_ipc_call_msg(&msg);
284 }
285
286 /**
287 * @brief Check if supplied esp_netif handle is active, i.e. available within registered interfaces
288 * as it might have already been destroyed. Returns the supplied handle if active, nullptr otherwise
289 *
290 * @param esp_netif handle to check if available in the list of registered interfaces
291 * @return esp_netif handle if available, or NULL if it wasn't found
292 */
esp_netif_is_active(esp_netif_t * arg)293 static esp_netif_t* esp_netif_is_active(esp_netif_t *arg)
294 {
295 // looking for the netif in the list of registered interfaces
296 // as it might have already been destroyed
297 if (esp_netif_is_netif_listed(arg)) {
298 return arg;
299 }
300 return NULL;
301 }
302
303 /**
304 * @brief This function sets default netif no matter which implementation used
305 *
306 * @param esp_netif handle to network interface
307 *
308 * @note: This function must be called from lwip thread
309 */
esp_netif_set_default_netif_internal(esp_netif_t * esp_netif)310 static void esp_netif_set_default_netif_internal(esp_netif_t *esp_netif)
311 {
312 if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
313 #if CONFIG_PPP_SUPPORT
314 esp_netif_ppp_set_default_netif(esp_netif->netif_handle);
315 #endif
316 } else {
317 netif_set_default(esp_netif->lwip_netif);
318 }
319 }
320
321 /**
322 * @brief tcpip thread version of esp_netif_update_default_netif
323 *
324 * @note This function and all functions called from this must be called from lwip task context
325 */
esp_netif_update_default_netif_lwip(esp_netif_api_msg_t * msg)326 static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg)
327 {
328 esp_netif_t *esp_netif = msg->esp_netif;
329 esp_netif_action_t action = (esp_netif_action_t)msg->data;
330
331 ESP_LOGD(TAG, "%s %p", __func__, esp_netif);
332
333 if (s_is_last_default_esp_netif_overridden && action != ESP_NETIF_SET_DEFAULT) {
334 // check if manually configured default interface hasn't been destroyed
335 s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif);
336 if (s_last_default_esp_netif != NULL) {
337 return ESP_OK; // still valid -> don't update default netif
338 }
339 // invalid -> reset the manual override and perform auto update
340 s_is_last_default_esp_netif_overridden = false;
341 }
342 switch (action) {
343 case ESP_NETIF_SET_DEFAULT:
344 s_last_default_esp_netif = esp_netif;
345 s_is_last_default_esp_netif_overridden = true;
346 esp_netif_set_default_netif_internal(s_last_default_esp_netif);
347 break;
348 case ESP_NETIF_STARTED:
349 {
350 // check if previously default interface hasn't been destroyed in the meantime
351 s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif);
352 if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)
353 && (s_last_default_esp_netif->route_prio > esp_netif->route_prio)) {
354 esp_netif_set_default_netif_internal(s_last_default_esp_netif);
355 } else if (esp_netif_is_netif_up(esp_netif)) {
356 s_last_default_esp_netif = esp_netif;
357 esp_netif_set_default_netif_internal(s_last_default_esp_netif);
358 }
359 }
360 break;
361
362 default:
363 case ESP_NETIF_STOPPED:
364 {
365 s_last_default_esp_netif = NULL;
366 esp_netif_list_lock();
367 esp_netif_t *netif = esp_netif_next_unsafe(NULL);
368 while (netif) {
369 if (esp_netif_is_netif_up(netif)) {
370 if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) {
371 if (netif->route_prio > s_last_default_esp_netif->route_prio) {
372 s_last_default_esp_netif = netif;
373 } // else not needed, as the s_last_default_esp_netif is correct
374 } else {
375 // s_last_default is either not set or down, current netif is up
376 s_last_default_esp_netif = netif;
377 }
378 }
379 netif = esp_netif_next_unsafe(netif);
380 }
381 esp_netif_list_unlock();
382 if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) {
383 esp_netif_set_default_netif_internal(s_last_default_esp_netif);
384 }
385 }
386 break;
387 }
388 return ESP_OK;
389 }
390
391 /**
392 * @brief This function sets default routing netif based on priorities of all interfaces which are up
393 *
394 * @param esp_netif current interface which just updated state
395 * @param action updating action (on-off)
396 */
esp_netif_update_default_netif(esp_netif_t * esp_netif,esp_netif_action_t action)397 static esp_err_t esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_action_t action)
398 {
399 return esp_netif_lwip_ipc_call(esp_netif_update_default_netif_lwip, esp_netif, (void*)action);
400 }
401
esp_netif_set_default_netif(esp_netif_t * esp_netif)402 esp_err_t esp_netif_set_default_netif(esp_netif_t *esp_netif)
403 {
404 return esp_netif_update_default_netif(esp_netif, ESP_NETIF_SET_DEFAULT);
405 }
406
esp_netif_get_default_netif(void)407 esp_netif_t *esp_netif_get_default_netif(void)
408 {
409 return s_last_default_esp_netif;
410 }
411
lwip_get_esp_netif(struct netif * netif)412 static inline esp_netif_t* lwip_get_esp_netif(struct netif *netif)
413 {
414 #if LWIP_ESP_NETIF_DATA
415 return (esp_netif_t*)netif_get_client_data(netif, lwip_netif_client_id);
416 #else
417 return (esp_netif_t*)netif->state;
418 #endif
419 }
420
lwip_set_esp_netif(struct netif * netif,esp_netif_t * esp_netif)421 static inline void lwip_set_esp_netif(struct netif *netif, esp_netif_t* esp_netif)
422 {
423 #if LWIP_ESP_NETIF_DATA
424 netif_set_client_data(netif, lwip_netif_client_id, esp_netif);
425 #else
426 netif->state = esp_netif;
427 #endif
428 }
429
430 #if CONFIG_ESP_NETIF_BRIDGE_EN
esp_netif_bridge_add_port(esp_netif_t * esp_netif_br,esp_netif_t * esp_netif_port)431 esp_err_t esp_netif_bridge_add_port(esp_netif_t *esp_netif_br, esp_netif_t *esp_netif_port)
432 {
433 if (ERR_OK != bridgeif_add_port(esp_netif_br->lwip_netif, esp_netif_port->lwip_netif)) {
434 return ESP_FAIL;
435 }
436 return ESP_OK;
437 }
438
esp_netif_bridge_fdb_add(esp_netif_t * esp_netif_br,uint8_t * addr,uint64_t ports_mask)439 esp_err_t esp_netif_bridge_fdb_add(esp_netif_t *esp_netif_br, uint8_t *addr, uint64_t ports_mask)
440 {
441 bridgeif_portmask_t ports = (bridgeif_portmask_t)ports_mask;
442 if (ports_mask & ESP_NETIF_BR_FDW_CPU) {
443 ports |= 1 << BRIDGEIF_MAX_PORTS;
444 }
445
446 if (ERR_OK != bridgeif_fdb_add(esp_netif_br->lwip_netif, (const struct eth_addr *)addr, ports)) {
447 return ESP_FAIL;
448 }
449 return ESP_OK;
450 }
451
esp_netif_bridge_fdb_remove(esp_netif_t * esp_netif_br,uint8_t * addr)452 esp_err_t esp_netif_bridge_fdb_remove(esp_netif_t *esp_netif_br, uint8_t *addr)
453 {
454 if (ERR_OK != bridgeif_fdb_remove(esp_netif_br->lwip_netif, (const struct eth_addr *)addr)) {
455 return ESP_FAIL;
456 }
457 return ESP_OK;
458 }
459 #endif // CONFIG_ESP_NETIF_BRIDGE_EN
460
461 #if CONFIG_LWIP_IPV4
esp_netif_set_ip4_addr(esp_ip4_addr_t * addr,uint8_t a,uint8_t b,uint8_t c,uint8_t d)462 void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
463 {
464 ip4_addr_t *address = (ip4_addr_t*)addr;
465 IP4_ADDR(address, a, b, c, d);
466 }
467
esp_ip4addr_ntoa(const esp_ip4_addr_t * addr,char * buf,int buflen)468 char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen)
469 {
470 return ip4addr_ntoa_r((ip4_addr_t *)addr, buf, buflen);
471 }
472
esp_ip4addr_aton(const char * addr)473 uint32_t esp_ip4addr_aton(const char *addr)
474 {
475 return ipaddr_addr(addr);
476 }
477 #endif
478
esp_netif_str_to_ip4(const char * src,esp_ip4_addr_t * dst)479 esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst)
480 {
481 if (src == NULL || dst == NULL) {
482 return ESP_ERR_INVALID_ARG;
483 }
484 int err = inet_pton(AF_INET, src, dst);
485 return err == 1 ? ESP_OK : ESP_FAIL;
486 }
487
esp_netif_str_to_ip6(const char * src,esp_ip6_addr_t * dst)488 esp_err_t esp_netif_str_to_ip6(const char *src, esp_ip6_addr_t *dst)
489 {
490 if (src == NULL || dst == NULL) {
491 return ESP_ERR_INVALID_ARG;
492 }
493 int err = inet_pton(AF_INET6, src, dst);
494 return err == 1 ? ESP_OK : ESP_FAIL;
495 }
496
esp_netif_get_io_driver(esp_netif_t * esp_netif)497 esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif)
498 {
499 return esp_netif->driver_handle;
500 }
501
esp_netif_get_handle_from_netif_impl(void * dev)502 esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev)
503 {
504 // ppp_pcb ptr would never get to app code, so this function only works with vanilla lwip impl
505 struct netif *lwip_netif = dev;
506 return lwip_get_esp_netif(lwip_netif);
507 }
508
esp_netif_get_netif_impl(esp_netif_t * esp_netif)509 void* esp_netif_get_netif_impl(esp_netif_t *esp_netif)
510 {
511 // get impl ptr only for vanilla lwip impl (ppp_pcb not supported)
512 if (esp_netif && !ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
513 return esp_netif->lwip_netif;
514 }
515 return NULL;
516 }
517
tcpip_init_done(void * arg)518 static void tcpip_init_done(void *arg)
519 {
520 sys_sem_t *init_sem = arg;
521 sys_sem_signal(init_sem);
522 }
523
esp_netif_init(void)524 esp_err_t esp_netif_init(void)
525 {
526 if (!sys_thread_tcpip(LWIP_CORE_IS_TCPIP_INITIALIZED)) {
527 #if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
528 uint8_t rand_buf[16];
529 /*
530 * This is early startup code where WiFi/BT is yet to be enabled and hence
531 * relevant entropy source is not available. However, bootloader enables
532 * SAR ADC based entropy source at its initialization, and our requirement
533 * of random bytes is pretty small (16), so we can assume that following
534 * API will provide sufficiently random data.
535 */
536 esp_fill_random(rand_buf, sizeof(rand_buf));
537 lwip_init_tcp_isn(esp_log_timestamp(), rand_buf);
538 #endif
539 sys_sem_t init_sem;
540 if (sys_sem_new(&init_sem, 0) != ERR_OK) {
541 ESP_LOGE(TAG, "esp netif cannot create tcpip_init semaphore");
542 return ESP_FAIL;
543 }
544 #if LWIP_TCPIP_CORE_LOCKING
545 /* TCPIP thread is not initialized yet,
546 * pretend that the calling thread is holder
547 * to correctly set up the TCPIP task */
548 sys_thread_tcpip(LWIP_CORE_LOCK_MARK_HOLDER);
549 #endif
550 tcpip_init(tcpip_init_done, &init_sem);
551 sys_sem_wait(&init_sem);
552 sys_sem_free(&init_sem);
553 ESP_LOGD(TAG, "LwIP stack has been initialized");
554 }
555
556 #if !LWIP_TCPIP_CORE_LOCKING
557 if (!api_sync_sem) {
558 if (ERR_OK != sys_sem_new(&api_sync_sem, 0)) {
559 ESP_LOGE(TAG, "esp netif api sync sem init fail");
560 return ESP_FAIL;
561 }
562 }
563
564 if (!api_lock_sem) {
565 if (ERR_OK != sys_sem_new(&api_lock_sem, 1)) {
566 ESP_LOGE(TAG, "esp netif api lock sem init fail");
567 return ESP_FAIL;
568 }
569 }
570 #endif
571
572 #if LWIP_ESP_NETIF_DATA
573 if (lwip_netif_client_id == 0xFF) {
574 esp_netif_lwip_ipc_call(alloc_client_data_id, NULL, &lwip_netif_client_id);
575 }
576 #endif
577 ESP_LOGD(TAG, "esp-netif has been successfully initialized");
578 return ESP_OK;
579 }
580
esp_netif_deinit(void)581 esp_err_t esp_netif_deinit(void)
582 {
583 if (sys_thread_tcpip(LWIP_CORE_IS_TCPIP_INITIALIZED)) {
584 /* deinit of LwIP not supported:
585 * do not deinit semaphores and states,
586 * so init could be called multiple times
587 *
588 sys_sem_free(&api_sync_sem);
589 sys_sem_free(&api_lock_sem);
590 */
591 return ESP_ERR_NOT_SUPPORTED;
592
593 }
594 return ESP_ERR_INVALID_STATE;
595 }
596
esp_netif_init_configuration(esp_netif_t * esp_netif,const esp_netif_config_t * cfg)597 static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_netif_config_t *cfg)
598 {
599 // Basic esp_netif and lwip is a mandatory configuration and cannot be updated after esp_netif_new()
600 if (cfg == NULL || cfg->base == NULL || cfg->stack == NULL) {
601 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
602 }
603
604 // Configure general esp-netif properties
605 memcpy(esp_netif->mac, cfg->base->mac, NETIF_MAX_HWADDR_LEN);
606 #if CONFIG_LWIP_IPV4
607 if (cfg->base->ip_info == NULL) {
608 ip4_addr_set_zero(&esp_netif->ip_info->ip);
609 ip4_addr_set_zero(&esp_netif->ip_info->gw);
610 ip4_addr_set_zero(&esp_netif->ip_info->netmask);
611 } else {
612 memcpy(esp_netif->ip_info, cfg->base->ip_info, sizeof(esp_netif_ip_info_t));
613 }
614 memcpy(esp_netif->ip_info_old, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
615 #endif
616 // Setup main config parameters
617 esp_netif->lost_ip_event = cfg->base->lost_ip_event;
618 esp_netif->get_ip_event = cfg->base->get_ip_event;
619 esp_netif->flags = cfg->base->flags;
620
621 if (cfg->base->if_key) {
622 esp_netif->if_key = strdup(cfg->base->if_key);
623 }
624 if (cfg->base->if_desc) {
625 esp_netif->if_desc = strdup(cfg->base->if_desc);
626 }
627 if (cfg->base->route_prio) {
628 esp_netif->route_prio = cfg->base->route_prio;
629 }
630
631 #if CONFIG_ESP_NETIF_BRIDGE_EN
632 // Setup bridge configuration if the interface is to be bridge
633 if (cfg->base->flags & ESP_NETIF_FLAG_IS_BRIDGE) {
634 if (cfg->base->bridge_info != NULL) {
635 esp_netif->max_fdb_dyn_entries = cfg->base->bridge_info->max_fdb_dyn_entries;
636 esp_netif->max_fdb_sta_entries = cfg->base->bridge_info->max_fdb_sta_entries;
637 esp_netif->max_ports = cfg->base->bridge_info->max_ports;
638 } else {
639 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
640 }
641 }
642 #endif // CONFIG_ESP_NETIF_BRIDGE_EN
643
644 // Install network stack functions -- connects netif and L3 stack
645 const esp_netif_netstack_config_t *esp_netif_stack_config = cfg->stack;
646 if (cfg->base->flags & ESP_NETIF_FLAG_IS_PPP) {
647 #if CONFIG_PPP_SUPPORT
648 esp_netif->related_data = esp_netif_new_ppp(esp_netif, esp_netif_stack_config);
649 if (esp_netif->related_data == NULL) {
650 return ESP_ERR_ESP_NETIF_INIT_FAILED;
651 }
652 esp_netif->lwip_input_fn = esp_netif_stack_config->lwip_ppp.input_fn;
653 // Make the netif handle (used for tcpip input function) the ppp_netif
654 esp_netif->netif_handle = esp_netif->related_data;
655 #else
656 LOG_NETIF_DISABLED_AND_DO("PPP", return ESP_ERR_NOT_SUPPORTED);
657 #endif
658 } else {
659 if (esp_netif_stack_config-> lwip.init_fn) {
660 esp_netif->lwip_init_fn = esp_netif_stack_config->lwip.init_fn;
661 }
662 if (esp_netif_stack_config->lwip.input_fn) {
663 esp_netif->lwip_input_fn = esp_netif_stack_config->lwip.input_fn;
664 }
665 // Make the netif handle (used for tcpip input function) the lwip_netif itself
666 esp_netif->netif_handle = esp_netif->lwip_netif;
667
668 }
669
670 // Install IO functions only if provided -- connects driver and netif
671 // this configuration could be updated after esp_netif_new(), typically in post_attach callback
672 if (cfg->driver) {
673 const esp_netif_driver_ifconfig_t *esp_netif_driver_config = cfg->driver;
674 if (esp_netif_driver_config->handle) {
675 esp_netif->driver_handle = esp_netif_driver_config->handle;
676 }
677 if (esp_netif_driver_config->transmit) {
678 esp_netif->driver_transmit = esp_netif_driver_config->transmit;
679 }
680 if (esp_netif_driver_config->transmit_wrap) {
681 esp_netif->driver_transmit_wrap = esp_netif_driver_config->transmit_wrap;
682 }
683 if (esp_netif_driver_config->driver_free_rx_buffer) {
684 esp_netif->driver_free_rx_buffer = esp_netif_driver_config->driver_free_rx_buffer;
685 }
686 }
687 return ESP_OK;
688 }
689
tcpip_exec_api(esp_netif_api_msg_t * msg)690 static esp_err_t tcpip_exec_api(esp_netif_api_msg_t *msg)
691 {
692 return msg->user_fn(msg->data);
693 }
694
esp_netif_tcpip_exec(esp_netif_callback_fn fn,void * ctx)695 esp_err_t esp_netif_tcpip_exec(esp_netif_callback_fn fn, void*ctx)
696 {
697 return esp_netif_lwip_ipc_call_fn(tcpip_exec_api, fn, ctx);
698 }
699
esp_netif_new(const esp_netif_config_t * esp_netif_config)700 esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
701 {
702 // mandatory configuration must be provided when creating esp_netif object
703 if (esp_netif_config == NULL ||
704 esp_netif_config->base->if_key == NULL ||
705 NULL != esp_netif_get_handle_from_ifkey(esp_netif_config->base->if_key)) {
706 ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (config or if_key is NULL or duplicate key)",
707 __func__, esp_netif_config);
708 return NULL;
709 }
710
711 #if ESP_DHCPS
712 // DHCP server and client cannot be configured together
713 if((esp_netif_config->base->flags & ESP_NETIF_DHCP_SERVER) &&
714 (esp_netif_config->base->flags & ESP_NETIF_DHCP_CLIENT)) {
715 ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (DHCP server and client cannot be configured together)",
716 __func__, esp_netif_config);
717 return NULL;
718 }
719 #endif
720
721 // Create parent esp-netif object
722 esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj));
723 if (!esp_netif) {
724 ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct esp_netif_obj),
725 esp_get_free_heap_size());
726 return NULL;
727 }
728
729 // Create ip info
730 esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
731 if (!ip_info) {
732 ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(esp_netif_ip_info_t),
733 esp_get_free_heap_size());
734 free(esp_netif);
735 return NULL;
736 }
737 esp_netif->ip_info = ip_info;
738
739 // creating another ip info (to store old ip)
740 ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
741 if (!ip_info) {
742 ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(esp_netif_ip_info_t),
743 esp_get_free_heap_size());
744 free(esp_netif->ip_info);
745 free(esp_netif);
746 return NULL;
747 }
748 esp_netif->ip_info_old = ip_info;
749
750 // Create underlying lwip netif
751 #if LWIP_ESP_NETIF_DATA
752 // Optionally allocate netif client data for esp-netif ptr
753 // to allow for running esp_netif_new() before esp_netif_init()
754 if (lwip_netif_client_id == 0xFF) {
755 esp_netif_lwip_ipc_call(alloc_client_data_id, NULL, &lwip_netif_client_id);
756 }
757 #endif
758
759 struct netif * lwip_netif = calloc(1, sizeof(struct netif));
760 if (!lwip_netif) {
761 ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct netif),
762 esp_get_free_heap_size());
763 free(esp_netif->ip_info_old);
764 free(esp_netif->ip_info);
765 free(esp_netif);
766 return NULL;
767 }
768
769 esp_netif->lwip_netif = lwip_netif;
770
771 esp_netif_add_to_list(esp_netif);
772
773 #if ESP_DHCPS
774 // Create DHCP server structure
775 if (esp_netif_config->base->flags & ESP_NETIF_DHCP_SERVER) {
776 esp_netif->dhcps = dhcps_new();
777 if (esp_netif->dhcps == NULL) {
778 ESP_LOGE(TAG, "Failed to create dhcp server handle");
779 esp_netif_destroy(esp_netif);
780 return NULL;
781 }
782 }
783 #endif
784
785 // Configure the created object with provided configuration
786 esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config);
787 if (ret != ESP_OK) {
788 ESP_LOGE(TAG, "Initial configuration of esp_netif failed with %d", ret);
789 esp_netif_destroy(esp_netif);
790 return NULL;
791 }
792 lwip_set_esp_netif(lwip_netif, esp_netif);
793
794 if (netif_callback.callback_fn == NULL ) {
795 esp_netif_lwip_ipc_no_args(set_lwip_netif_callback);
796 }
797
798 return esp_netif;
799 }
800
esp_netif_lwip_remove(esp_netif_t * esp_netif)801 static void esp_netif_lwip_remove(esp_netif_t *esp_netif)
802 {
803 if (esp_netif->lwip_netif) {
804 if (netif_is_up(esp_netif->lwip_netif)) {
805 netif_set_down(esp_netif->lwip_netif);
806 }
807 netif_remove(esp_netif->lwip_netif);
808 #if ESP_GRATUITOUS_ARP
809 if (esp_netif->flags & ESP_NETIF_FLAG_GARP) {
810 netif_unset_garp_flag(esp_netif->lwip_netif);
811 }
812 #endif
813 #if ESP_MLDV6_REPORT && LWIP_IPV6
814 if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) {
815 netif_unset_mldv6_flag(esp_netif->lwip_netif);
816 }
817 #endif
818 if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
819 #if CONFIG_LWIP_IPV4
820 dhcp_cleanup(esp_netif->lwip_netif);
821 #endif
822 }
823
824 }
825 }
826
esp_netif_lwip_add(esp_netif_t * esp_netif)827 static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif)
828 {
829 if (esp_netif->lwip_netif == NULL) {
830 esp_netif->lwip_netif = calloc(1, sizeof(struct netif));
831 if (esp_netif->lwip_netif == NULL) {
832 return ESP_ERR_NO_MEM;
833 }
834 }
835 if (esp_netif->flags & ESP_NETIF_FLAG_IS_PPP) {
836 #if CONFIG_PPP_SUPPORT
837 err_t err = esp_netif->lwip_init_fn(NULL);
838 if (err != ERR_OK) {
839 ESP_LOGE(TAG, "Init netif failed with %d", err);
840 return ESP_ERR_ESP_NETIF_INIT_FAILED;
841 }
842 #else
843 LOG_NETIF_DISABLED_AND_DO("PPP", return ESP_ERR_NOT_SUPPORTED);
844 #endif
845 }
846
847 #if CONFIG_ESP_NETIF_BRIDGE_EN
848 if (esp_netif->flags & ESP_NETIF_FLAG_IS_BRIDGE) {
849 bridgeif_initdata_t bridge_initdata = {
850 .max_fdb_dynamic_entries = esp_netif->max_fdb_dyn_entries,
851 .max_fdb_static_entries = esp_netif->max_fdb_sta_entries,
852 .max_ports = esp_netif->max_ports
853 };
854 memcpy(&bridge_initdata.ethaddr, esp_netif->mac, ETH_HWADDR_LEN);
855 if (NULL == netif_add(esp_netif->lwip_netif, (struct ip4_addr*)&esp_netif->ip_info->ip,
856 (struct ip4_addr*)&esp_netif->ip_info->netmask, (struct ip4_addr*)&esp_netif->ip_info->gw,
857 &bridge_initdata, esp_netif->lwip_init_fn, tcpip_input)) {
858 esp_netif_lwip_remove(esp_netif);
859 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
860 }
861 } else {
862 #endif // CONFIG_ESP_NETIF_BRIDGE_EN
863 if (NULL == netif_add(esp_netif->lwip_netif,
864 #if CONFIG_LWIP_IPV4
865 (struct ip4_addr*)&esp_netif->ip_info->ip,
866 (struct ip4_addr*)&esp_netif->ip_info->netmask,
867 (struct ip4_addr*)&esp_netif->ip_info->gw,
868 #endif
869 esp_netif, esp_netif->lwip_init_fn, tcpip_input)) {
870 esp_netif_lwip_remove(esp_netif);
871 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
872 }
873 #if CONFIG_ESP_NETIF_BRIDGE_EN
874 }
875 #endif // CONFIG_ESP_NETIF_BRIDGE_EN
876 lwip_set_esp_netif(esp_netif->lwip_netif, esp_netif);
877 return ESP_OK;
878 }
879
esp_netif_destroy_related(esp_netif_t * esp_netif)880 static void esp_netif_destroy_related(esp_netif_t *esp_netif)
881 {
882 if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
883 #if CONFIG_PPP_SUPPORT
884 esp_netif_destroy_ppp(esp_netif->related_data);
885 #endif
886 }
887 }
888
esp_netif_lwip_remove_api(esp_netif_api_msg_t * msg)889 static esp_err_t esp_netif_lwip_remove_api(esp_netif_api_msg_t *msg)
890 {
891 esp_netif_lwip_remove(msg->esp_netif);
892 return ESP_OK;
893 }
894
esp_netif_destroy(esp_netif_t * esp_netif)895 void esp_netif_destroy(esp_netif_t *esp_netif)
896 {
897 if (esp_netif) {
898 esp_netif_remove_from_list(esp_netif);
899 if (esp_netif_get_nr_of_ifs() == 0) {
900 esp_netif_lwip_ipc_no_args(remove_lwip_netif_callback);
901 }
902 free(esp_netif->ip_info);
903 free(esp_netif->ip_info_old);
904 free(esp_netif->if_key);
905 free(esp_netif->if_desc);
906 esp_netif_lwip_ipc_call(esp_netif_lwip_remove_api, esp_netif, NULL);
907 esp_netif_destroy_related(esp_netif);
908 free(esp_netif->lwip_netif);
909 free(esp_netif->hostname);
910 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
911 #if ESP_DHCPS
912 dhcps_delete(esp_netif->dhcps);
913 #endif
914 free(esp_netif);
915 }
916 }
917
esp_netif_attach(esp_netif_t * esp_netif,esp_netif_iodriver_handle driver_handle)918 esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle)
919 {
920 esp_netif_driver_base_t *base_driver = driver_handle;
921
922 esp_netif->driver_handle = driver_handle;
923 if (base_driver->post_attach) {
924 esp_err_t ret = base_driver->post_attach(esp_netif, driver_handle);
925 if (ret != ESP_OK) {
926 ESP_LOGE(TAG, "Post-attach callback of driver(%p) failed with %d", driver_handle, ret);
927 return ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED;
928 }
929 }
930 return ESP_OK;
931 }
932
esp_netif_set_driver_config(esp_netif_t * esp_netif,const esp_netif_driver_ifconfig_t * driver_config)933 esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif,
934 const esp_netif_driver_ifconfig_t *driver_config)
935 {
936 if (esp_netif == NULL || driver_config == NULL) {
937 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
938 }
939 esp_netif->driver_handle = driver_config->handle;
940 esp_netif->driver_transmit = driver_config->transmit;
941 esp_netif->driver_transmit_wrap = driver_config->transmit_wrap;
942 esp_netif->driver_free_rx_buffer = driver_config->driver_free_rx_buffer;
943 return ESP_OK;
944 }
945
946 #if CONFIG_LWIP_IPV4
esp_netif_reset_ip_info(esp_netif_t * esp_netif)947 static esp_err_t esp_netif_reset_ip_info(esp_netif_t *esp_netif)
948 {
949 ip4_addr_set_zero(&(esp_netif->ip_info->ip));
950 ip4_addr_set_zero(&(esp_netif->ip_info->gw));
951 ip4_addr_set_zero(&(esp_netif->ip_info->netmask));
952 return ESP_OK;
953 }
954 #endif
955
esp_netif_set_mac_api(esp_netif_api_msg_t * msg)956 esp_err_t esp_netif_set_mac_api(esp_netif_api_msg_t *msg)
957 {
958 uint8_t *mac = msg->data;
959 esp_netif_t* esp_netif = msg->esp_netif;
960 memcpy(esp_netif->mac, mac, NETIF_MAX_HWADDR_LEN);
961 memcpy(esp_netif->lwip_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
962 return ESP_OK;
963 }
964
esp_netif_set_mac(esp_netif_t * esp_netif,uint8_t mac[])965 esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[])
966 {
967 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
968 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
969 }
970 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
971 return ESP_ERR_NOT_SUPPORTED;
972 }
973 return esp_netif_lwip_ipc_call(esp_netif_set_mac_api, esp_netif, mac);
974 }
975
esp_netif_get_mac(esp_netif_t * esp_netif,uint8_t mac[])976 esp_err_t esp_netif_get_mac(esp_netif_t *esp_netif, uint8_t mac[])
977 {
978 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
979 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
980 }
981 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
982 return ESP_ERR_NOT_SUPPORTED;
983 }
984 if (esp_netif_is_netif_up(esp_netif)) {
985 memcpy(mac, esp_netif->lwip_netif->hwaddr, NETIF_MAX_HWADDR_LEN);
986 return ESP_OK;
987 }
988 memcpy(mac, esp_netif->mac, NETIF_MAX_HWADDR_LEN);
989 return ESP_OK;
990 }
991
992 #if ESP_DHCPS
esp_netif_dhcps_cb(void * arg,uint8_t ip[4],uint8_t mac[6])993 static void esp_netif_dhcps_cb(void* arg, uint8_t ip[4], uint8_t mac[6])
994 {
995 esp_netif_t *esp_netif = arg;
996 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
997 ip_event_ap_staipassigned_t evt = { .esp_netif = esp_netif };
998 memcpy((char *)&evt.ip.addr, (char *)ip, sizeof(evt.ip.addr));
999 memcpy((char *)&evt.mac, mac, sizeof(evt.mac));
1000 ESP_LOGI(TAG, "DHCP server assigned IP to a client, IP is: " IPSTR, IP2STR(&evt.ip));
1001 ESP_LOGD(TAG, "Client's MAC: %x:%x:%x:%x:%x:%x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1002
1003 int ret = esp_event_post(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &evt, sizeof(evt), 0);
1004 if (ESP_OK != ret) {
1005 ESP_LOGE(TAG, "dhcps cb: failed to post IP_EVENT_AP_STAIPASSIGNED (%x)", ret);
1006 }
1007 }
1008 #endif
1009
esp_netif_config_sanity_check(const esp_netif_t * esp_netif)1010 static esp_err_t esp_netif_config_sanity_check(const esp_netif_t * esp_netif)
1011 {
1012 if (esp_netif == NULL) {
1013 ESP_LOGE(TAG, "Cannot start esp_netif: esp_netif must not be null");
1014 return ESP_ERR_INVALID_STATE;
1015 }
1016
1017 if ((!(esp_netif->flags & ESP_NETIF_FLAG_IS_BRIDGE) && (esp_netif->driver_transmit == NULL ||
1018 esp_netif->driver_handle == NULL || esp_netif->lwip_input_fn == NULL)) ||
1019 esp_netif->lwip_init_fn == NULL) {
1020 ESP_LOGE(TAG, "Cannot start esp_netif: Missing mandatory configuration:\n"
1021 "esp_netif->driver_transmit: %p, esp_netif->driver_handle:%p, "
1022 "esp_netif->lwip_input_fn: %p, esp_netif->lwip_init_fn:%p",
1023 esp_netif->driver_transmit, esp_netif->driver_handle,
1024 esp_netif->lwip_input_fn, esp_netif->lwip_init_fn);
1025
1026 return ESP_ERR_INVALID_STATE;
1027 }
1028 return ESP_OK;
1029 }
1030
esp_netif_start_api(esp_netif_api_msg_t * msg)1031 static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg)
1032 {
1033 esp_netif_t * esp_netif = msg->esp_netif;
1034
1035 ESP_LOGD(TAG, "%s %p", __func__, esp_netif);
1036
1037 ESP_ERROR_CHECK(esp_netif_config_sanity_check(esp_netif));
1038
1039 ESP_ERROR_CHECK(esp_netif_lwip_add(esp_netif));
1040
1041 #if ESP_IPV6_AUTOCONFIG
1042 esp_netif->lwip_netif->ip6_autoconfig_enabled = 1;
1043 #endif
1044 if (esp_netif->flags&ESP_NETIF_FLAG_GARP) {
1045 #if ESP_GRATUITOUS_ARP
1046 netif_set_garp_flag(esp_netif->lwip_netif);
1047 #else
1048 ESP_LOGW(TAG,"CONFIG_LWIP_ESP_GRATUITOUS_ARP not enabled, but esp-netif configured with ESP_NETIF_FLAG_GARP");
1049 #endif
1050 }
1051 struct netif *p_netif = esp_netif->lwip_netif;
1052
1053 if (esp_netif->flags&ESP_NETIF_FLAG_AUTOUP) {
1054 ESP_LOGD(TAG, "%s Setting the lwip netif%p UP", __func__, p_netif);
1055 netif_set_up(p_netif);
1056 netif_set_link_up(p_netif);
1057 }
1058 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1059 #if ESP_DHCPS
1060 if (esp_netif->dhcps_status == ESP_NETIF_DHCP_INIT) {
1061 if (p_netif != NULL && netif_is_up(p_netif)) {
1062 esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
1063 ip4_addr_t lwip_ip;
1064 ip4_addr_t lwip_netmask;
1065 memcpy(&lwip_ip, &default_ip->ip, sizeof(struct ip4_addr));
1066 memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
1067 dhcps_set_new_lease_cb(esp_netif->dhcps, esp_netif_dhcps_cb, esp_netif);
1068 dhcps_set_option_info(esp_netif->dhcps, SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
1069 if (dhcps_start(esp_netif->dhcps, p_netif, lwip_ip) != ERR_OK) {
1070 ESP_LOGE(TAG, "DHCP server cannot be started");
1071 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
1072 return ESP_ERR_ESP_NETIF_DHCPS_START_FAILED;
1073 }
1074 esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
1075 ESP_LOGI(TAG, "DHCP server started on interface %s with IP: " IPSTR, esp_netif->if_key, IP2STR(&lwip_ip));
1076 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
1077 return ESP_OK;
1078 } else {
1079 ESP_LOGD(TAG, "DHCP server re init");
1080 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
1081 return ESP_OK;
1082 }
1083 } else if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
1084 ESP_LOGD(TAG, "DHCP server already started");
1085 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1086 }
1087 return ESP_OK;
1088 #else
1089 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
1090 #endif
1091 } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
1092 #if CONFIG_LWIP_IPV4
1093 if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STARTED) {
1094 if (p_netif != NULL) {
1095 struct dhcp *dhcp_data = NULL;
1096 dhcp_data = netif_dhcp_data(p_netif);
1097 if (dhcp_data == NULL) {
1098 dhcp_data = (struct dhcp *)malloc(sizeof(struct dhcp));
1099 if (dhcp_data == NULL) {
1100 return ESP_ERR_NO_MEM;
1101 }
1102 dhcp_set_struct(p_netif, dhcp_data);
1103 }
1104 }
1105 }
1106 #else
1107 LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED);
1108 #endif
1109 }
1110
1111 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
1112
1113 return ESP_OK;
1114 }
1115
esp_netif_start(esp_netif_t * esp_netif)1116 esp_err_t esp_netif_start(esp_netif_t *esp_netif)
1117 {
1118 if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
1119 #if CONFIG_PPP_SUPPORT
1120 // No need to start PPP interface in lwip thread
1121 esp_err_t ret = esp_netif_start_ppp(esp_netif);
1122 if (ret == ESP_OK) {
1123 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
1124 }
1125 return ret;
1126 #endif
1127 }
1128 return esp_netif_lwip_ipc_call(esp_netif_start_api, esp_netif, NULL);
1129 }
1130
esp_netif_stop_api(esp_netif_api_msg_t * msg)1131 static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg)
1132 {
1133 esp_netif_t *esp_netif = msg->esp_netif;
1134
1135 struct netif *lwip_netif = esp_netif->lwip_netif;
1136 if (lwip_netif == NULL) {
1137 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1138 }
1139
1140 if (!netif_is_up(lwip_netif)) {
1141 esp_netif_lwip_remove(esp_netif);
1142 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1143 }
1144
1145 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1146 #if ESP_DHCPS
1147 if (dhcps_stop(esp_netif->dhcps, lwip_netif) != ERR_OK ||
1148 esp_netif->dhcps_status != ESP_NETIF_DHCP_STOPPED) {
1149 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
1150 }
1151 #else
1152 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
1153 #endif
1154 } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
1155 #if CONFIG_LWIP_IPV4
1156 dhcp_release(lwip_netif);
1157 dhcp_stop(lwip_netif);
1158 dhcp_cleanup(lwip_netif);
1159
1160 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1161
1162 esp_netif_reset_ip_info(esp_netif);
1163 #else
1164 LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED);
1165 #endif
1166 }
1167
1168 netif_set_down(lwip_netif);
1169 esp_netif_lwip_remove(esp_netif);
1170 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
1171
1172 return ESP_OK;
1173 }
1174
esp_netif_stop(esp_netif_t * esp_netif)1175 esp_err_t esp_netif_stop(esp_netif_t *esp_netif)
1176 {
1177 if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
1178 #if CONFIG_PPP_SUPPORT
1179 // No need to stop PPP interface in lwip thread
1180 esp_err_t ret = esp_netif_stop_ppp(esp_netif->related_data);
1181 if (ret == ESP_OK) {
1182 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
1183 }
1184 return ret;
1185 #endif
1186 }
1187 return esp_netif_lwip_ipc_call(esp_netif_stop_api, esp_netif, NULL);
1188 }
1189
esp_netif_netstack_buf_ref(void * pbuf)1190 void esp_netif_netstack_buf_ref(void *pbuf)
1191 {
1192 pbuf_ref(pbuf);
1193 }
1194
esp_netif_netstack_buf_free(void * pbuf)1195 void esp_netif_netstack_buf_free(void *pbuf)
1196 {
1197 pbuf_free(pbuf);
1198 }
1199
1200 //
1201 // IO translate functions
1202 //
esp_netif_free_rx_buffer(void * h,void * buffer)1203 void esp_netif_free_rx_buffer(void *h, void* buffer)
1204 {
1205 esp_netif_t *esp_netif = h;
1206 esp_netif->driver_free_rx_buffer(esp_netif->driver_handle, buffer);
1207 }
1208
esp_netif_transmit(esp_netif_t * esp_netif,void * data,size_t len)1209 esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len)
1210 {
1211 return (esp_netif->driver_transmit)(esp_netif->driver_handle, data, len);
1212 }
1213
esp_netif_transmit_wrap(esp_netif_t * esp_netif,void * data,size_t len,void * pbuf)1214 esp_err_t esp_netif_transmit_wrap(esp_netif_t *esp_netif, void *data, size_t len, void *pbuf)
1215 {
1216 return (esp_netif->driver_transmit_wrap)(esp_netif->driver_handle, data, len, pbuf);
1217 }
1218
esp_netif_receive(esp_netif_t * esp_netif,void * buffer,size_t len,void * eb)1219 esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
1220 {
1221 #ifdef CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS
1222 return esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb);
1223 #else
1224 esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb);
1225 return ESP_OK;
1226 #endif
1227 }
1228
1229 #if CONFIG_LWIP_IPV4
1230 static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif);
1231
1232 //
1233 // DHCP:
1234 //
esp_netif_internal_dhcpc_cb(struct netif * netif)1235 static void esp_netif_internal_dhcpc_cb(struct netif *netif)
1236 {
1237 esp_netif_t *esp_netif;
1238 ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, netif);
1239 if (netif == NULL || (esp_netif = lwip_get_esp_netif(netif)) == NULL) {
1240 // internal pointer hasn't been configured yet (probably in the interface init_fn())
1241 return;
1242 }
1243
1244 esp_netif_ip_info_t *ip_info = esp_netif->ip_info;
1245 esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info_old;
1246
1247 if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4) ) {
1248
1249 //check whether IP is changed (or if we're an PPP interface)
1250 if ( (!ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), (&ip_info->ip)) ||
1251 !ip4_addr_cmp(ip_2_ip4(&netif->netmask), (&ip_info->netmask)) ||
1252 !ip4_addr_cmp(ip_2_ip4(&netif->gw), (&ip_info->gw)))
1253 // post IP event for PPP interfaces even if IP hasn't changed
1254 || (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif))) {
1255 ip_event_got_ip_t evt = {
1256 .esp_netif = esp_netif,
1257 .ip_changed = false,
1258 };
1259 ip_event_t evt_id = esp_netif_get_event_id(esp_netif, ESP_NETIF_IP_EVENT_GOT_IP);
1260 int ret;
1261
1262 ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr));
1263 ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask));
1264 ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
1265
1266 //notify event
1267 if (memcmp(ip_info, ip_info_old, sizeof(esp_netif_ip_info_t))) {
1268 evt.ip_changed = true;
1269 }
1270
1271 memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t));
1272 memcpy(ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
1273 ESP_LOGD(TAG, "if%p ip changed=%d", esp_netif, evt.ip_changed);
1274 ret = esp_event_post(IP_EVENT, evt_id, &evt, sizeof(evt), 0);
1275 if (ESP_OK != ret) {
1276 ESP_LOGE(TAG, "dhcpc cb: failed to post got ip event (%x)", ret);
1277 }
1278 #ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
1279 dhcp_ip_addr_store(netif);
1280 #endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */
1281 } else {
1282 ESP_LOGD(TAG, "if%p ip unchanged", esp_netif);
1283 }
1284 } else {
1285 if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY4)) {
1286 esp_netif_start_ip_lost_timer(esp_netif);
1287 }
1288 }
1289 }
1290
esp_netif_ip_lost_timer(void * arg)1291 static void esp_netif_ip_lost_timer(void *arg)
1292 {
1293 esp_netif_t *esp_netif = esp_netif_is_active(arg);
1294
1295 if (esp_netif == NULL) {
1296 ESP_LOGD(TAG, "%s esp_netif=%p not active any more", __func__, arg);
1297 return;
1298 }
1299
1300 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1301
1302 esp_netif->timer_running = false;
1303
1304 struct netif *netif = esp_netif->lwip_netif;
1305
1306 if ( (!netif) || (netif && ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4))) {
1307 ip_event_got_ip_t evt = {
1308 .esp_netif = esp_netif,
1309 };
1310 int ret;
1311
1312 ESP_LOGD(TAG, "if%p ip lost tmr: raise ip lost event", esp_netif);
1313 memset(esp_netif->ip_info_old, 0, sizeof(esp_netif_ip_info_t));
1314 if (esp_netif->lost_ip_event) {
1315 ret = esp_event_post(IP_EVENT, esp_netif->lost_ip_event,
1316 &evt, sizeof(evt), 0);
1317 if (ESP_OK != ret) {
1318 ESP_LOGE(TAG, "ip lost timer: failed to post lost ip event (%x)", ret);
1319 }
1320 }
1321 } else {
1322 ESP_LOGD(TAG, "if%p ip lost tmr: no need raise ip lost event", esp_netif);
1323 }
1324 }
1325
esp_netif_start_ip_lost_timer(esp_netif_t * esp_netif)1326 static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif)
1327 {
1328 esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info;
1329 struct netif *netif = esp_netif->lwip_netif;
1330
1331 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1332
1333 if (esp_netif->timer_running) {
1334 ESP_LOGD(TAG, "if%p start ip lost tmr: already started", esp_netif);
1335 return ESP_OK;
1336 }
1337
1338 if ( netif && (CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL > 0) && !ip4_addr_isany_val(ip_info_old->ip)) {
1339 esp_netif->timer_running = true;
1340 sys_timeout(CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL * 1000, esp_netif_ip_lost_timer, (void *)esp_netif);
1341 ESP_LOGD(TAG, "if%p start ip lost tmr: interval=%d", esp_netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL);
1342 return ESP_OK;
1343 }
1344
1345 ESP_LOGD(TAG, "if%p start ip lost tmr: no need start because netif=%p interval=%d ip=%x",
1346 esp_netif, netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL, ip_info_old->ip.addr);
1347
1348 return ESP_OK;
1349 }
1350
esp_netif_dhcpc_stop_api(esp_netif_api_msg_t * msg)1351 static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg)
1352 {
1353 esp_netif_t *esp_netif = msg->esp_netif;
1354
1355 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1356
1357 if (esp_netif == NULL) {
1358 ESP_LOGE(TAG, "dhcp client stop called with NULL api");
1359 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1360 }
1361
1362 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1363 struct netif *p_netif = esp_netif->lwip_netif;
1364
1365 if (p_netif != NULL) {
1366 dhcp_stop(p_netif);
1367 esp_netif_reset_ip_info(esp_netif);
1368 esp_netif_start_ip_lost_timer(esp_netif);
1369 } else {
1370 ESP_LOGD(TAG, "dhcp client if not ready");
1371 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1372 }
1373 } else if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) {
1374 ESP_LOGD(TAG, "dhcp client already stoped");
1375 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
1376 }
1377
1378 ESP_LOGD(TAG, "dhcp client stop successfully");
1379 esp_netif->dhcpc_status = ESP_NETIF_DHCP_STOPPED;
1380
1381 #ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
1382 dhcp_ip_addr_erase(esp_netif->lwip_netif);
1383 #endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */
1384
1385 return ESP_OK;
1386 }
1387
esp_netif_dhcpc_stop(esp_netif_t * esp_netif)1388 esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_stop_api, esp_netif, NULL)
1389
1390 static void dns_clear_servers(bool keep_fallback)
1391 {
1392 u8_t numdns = 0;
1393
1394 for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) {
1395 if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) {
1396 continue;
1397 }
1398
1399 dns_setserver(numdns, NULL);
1400 }
1401 }
1402
esp_netif_dhcpc_start_api(esp_netif_api_msg_t * msg)1403 static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg)
1404 {
1405 esp_netif_t *esp_netif = msg->esp_netif;
1406
1407 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1408
1409 if (!esp_netif) {
1410 return ESP_ERR_INVALID_ARG;
1411 }
1412
1413 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1414 ESP_LOGD(TAG, "dhcp client already started");
1415 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1416 }
1417
1418 struct netif *p_netif = esp_netif->lwip_netif;
1419
1420 esp_netif_reset_ip_info(esp_netif);
1421
1422 #if LWIP_DNS
1423 dns_clear_servers(true);
1424 #endif
1425
1426 if (p_netif != NULL) {
1427 if (netif_is_up(p_netif)) {
1428 ip_addr_set_zero(&p_netif->ip_addr);
1429 ip_addr_set_zero(&p_netif->netmask);
1430 ip_addr_set_zero(&p_netif->gw);
1431 esp_netif_start_ip_lost_timer(esp_netif);
1432 } else {
1433 ESP_LOGD(TAG, "dhcp client re init");
1434 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1435 return ESP_OK;
1436 }
1437 ESP_LOGD(TAG, "starting dhcp client");
1438
1439 if (dhcp_start(p_netif) != ERR_OK) {
1440 ESP_LOGE(TAG, "dhcp client start failed");
1441 return ESP_ERR_ESP_NETIF_DHCPC_START_FAILED;
1442 }
1443
1444 esp_netif->dhcpc_status = ESP_NETIF_DHCP_STARTED;
1445 return ESP_OK;
1446 } else {
1447 ESP_LOGD(TAG, "dhcp client re init");
1448 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1449 return ESP_OK;
1450 }
1451 }
1452
esp_netif_dhcpc_start(esp_netif_t * esp_netif)1453 esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_start_api, esp_netif, NULL)
1454 #endif /* CONFIG_LWIP_IPV4 */
1455
1456 #if ESP_DHCPS
1457 esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
1458 {
1459 if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1460 return ESP_ERR_INVALID_ARG;
1461 }
1462
1463 *status = esp_netif->dhcps_status;
1464 return ESP_OK;
1465 }
1466 #endif
1467
esp_netif_dhcpc_get_status(esp_netif_t * esp_netif,esp_netif_dhcp_status_t * status)1468 esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
1469 {
1470 if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_SERVER) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1471 return ESP_ERR_INVALID_ARG;
1472 }
1473
1474 *status = esp_netif->dhcpc_status;
1475 return ESP_OK;
1476 }
1477
1478 #if ESP_DHCPS
esp_netif_dhcps_start_api(esp_netif_api_msg_t * msg)1479 static esp_err_t esp_netif_dhcps_start_api(esp_netif_api_msg_t *msg)
1480 {
1481 esp_netif_t *esp_netif = msg->esp_netif;
1482
1483 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1484
1485 if (!esp_netif) {
1486 return ESP_ERR_INVALID_ARG;
1487 }
1488
1489 if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
1490 ESP_LOGD(TAG, "dhcp server already started");
1491 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1492 }
1493
1494 struct netif *p_netif = esp_netif->lwip_netif;
1495 if (p_netif != NULL && netif_is_up(p_netif)) {
1496 esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
1497 ip4_addr_t lwip_ip;
1498 ip4_addr_t lwip_netmask;
1499 memcpy(&lwip_ip, &default_ip->ip, sizeof(struct ip4_addr));
1500 memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
1501 dhcps_set_new_lease_cb(esp_netif->dhcps, esp_netif_dhcps_cb, esp_netif);
1502 dhcps_set_option_info(esp_netif->dhcps, SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
1503 if (dhcps_start(esp_netif->dhcps, p_netif, lwip_ip) != ERR_OK) {
1504 ESP_LOGE(TAG, "DHCP server cannot be started");
1505 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
1506 return ESP_ERR_ESP_NETIF_DHCPS_START_FAILED;
1507 }
1508 esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
1509 ESP_LOGD(TAG, "DHCP server started successfully");
1510 return ESP_OK;
1511 } else {
1512 ESP_LOGD(TAG, "dhcp server re init");
1513 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
1514 return ESP_OK;
1515 }
1516 }
1517
esp_netif_dhcps_start(esp_netif_t * esp_netif)1518 esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_start_api, esp_netif, NULL)
1519
1520 static esp_err_t esp_netif_dhcps_stop_api(esp_netif_api_msg_t *msg)
1521 {
1522 esp_netif_t *esp_netif = msg->esp_netif;
1523
1524 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1525
1526 if (!esp_netif) {
1527 return ESP_ERR_INVALID_ARG;
1528 }
1529
1530 struct netif *p_netif = esp_netif->lwip_netif;
1531 if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
1532 if (dhcps_stop(esp_netif->dhcps, p_netif) != ERR_OK) {
1533 ESP_LOGD(TAG, "dhcp server if not ready");
1534 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1535 }
1536 } else if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STOPPED) {
1537 ESP_LOGD(TAG, "dhcp server already stoped");
1538 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
1539 }
1540
1541 ESP_LOGD(TAG, "dhcp server stop successfully");
1542 esp_netif->dhcps_status = ESP_NETIF_DHCP_STOPPED;
1543 return ESP_OK;
1544 }
1545
esp_netif_dhcps_stop(esp_netif_t * esp_netif)1546 esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_stop_api, esp_netif, NULL)
1547 #endif
1548
1549 static esp_err_t esp_netif_set_hostname_api(esp_netif_api_msg_t *msg)
1550 {
1551 esp_netif_t *esp_netif = msg->esp_netif;
1552 const char *hostname = msg->data;
1553
1554 ESP_LOGD(TAG, "%s esp_netif:%p hostname %s", __func__, esp_netif, hostname);
1555
1556 if (!esp_netif) {
1557 return ESP_ERR_INVALID_ARG;
1558 }
1559
1560 #if LWIP_NETIF_HOSTNAME
1561
1562 struct netif *p_netif = esp_netif->lwip_netif;
1563
1564 if (strlen(hostname) > ESP_NETIF_HOSTNAME_MAX_SIZE) {
1565 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1566 }
1567
1568 if (p_netif != NULL) {
1569 if (esp_netif->hostname) {
1570 free(esp_netif->hostname);
1571 }
1572 esp_netif->hostname = strdup(hostname);
1573 if (esp_netif->hostname == NULL) {
1574 p_netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
1575 return ESP_ERR_NO_MEM;
1576 }
1577 p_netif->hostname = esp_netif->hostname;
1578 return ESP_OK;
1579 } else {
1580 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1581 }
1582 #else
1583 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1584 #endif
1585 }
1586
esp_netif_set_hostname(esp_netif_t * esp_netif,const char * hostname)1587 esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_hostname_api, esp_netif, hostname)
1588
1589 esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname)
1590 {
1591 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1592
1593 if (!esp_netif || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1594 return ESP_ERR_INVALID_ARG;
1595 }
1596
1597 #if LWIP_NETIF_HOSTNAME
1598 struct netif *p_netif = esp_netif->lwip_netif;
1599
1600 if (p_netif != NULL && p_netif->hostname != NULL) {
1601 *hostname = p_netif->hostname;
1602 return ESP_OK;
1603 } else {
1604 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1605 }
1606 #else
1607 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1608 #endif
1609 }
1610
esp_netif_up_api(esp_netif_api_msg_t * msg)1611 static esp_err_t esp_netif_up_api(esp_netif_api_msg_t *msg)
1612 {
1613 esp_netif_t *esp_netif = msg->esp_netif;
1614
1615 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1616
1617 if (!esp_netif) {
1618 return ESP_ERR_INVALID_STATE;
1619 }
1620
1621 struct netif *lwip_netif = esp_netif->lwip_netif;
1622
1623 #if CONFIG_LWIP_IPV4
1624 /* use last obtained ip, or static ip */
1625 netif_set_addr(lwip_netif, (ip4_addr_t*)&esp_netif->ip_info->ip, (ip4_addr_t*)&esp_netif->ip_info->netmask, (ip4_addr_t*)&esp_netif->ip_info->gw);
1626 #endif
1627 netif_set_up(lwip_netif);
1628 netif_set_link_up(lwip_netif);
1629
1630 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
1631
1632 return ESP_OK;
1633 }
1634
esp_netif_up(esp_netif_t * esp_netif)1635 esp_err_t esp_netif_up(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK(esp_netif_up_api, esp_netif, NULL)
1636
1637 static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg)
1638 {
1639 esp_netif_t *esp_netif = msg->esp_netif;
1640
1641 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1642
1643 if (!esp_netif) {
1644 return ESP_ERR_INVALID_STATE;
1645 }
1646
1647 struct netif *lwip_netif = esp_netif->lwip_netif;
1648
1649 if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT && esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1650 #if CONFIG_LWIP_IPV4
1651 dhcp_stop(esp_netif->lwip_netif);
1652
1653 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1654
1655 esp_netif_reset_ip_info(esp_netif);
1656 #endif
1657 }
1658 #if CONFIG_LWIP_IPV6
1659 #if ESP_MLDV6_REPORT
1660 if (esp_netif->flags & ESP_NETIF_FLAG_MLDV6_REPORT) {
1661 netif_unset_mldv6_flag(esp_netif->lwip_netif);
1662 }
1663 #endif
1664 for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) {
1665 netif_ip6_addr_set(lwip_netif, i, IP6_ADDR_ANY6);
1666 netif_ip6_addr_set_valid_life(lwip_netif, i, 0);
1667 netif_ip6_addr_set_pref_life(lwip_netif, i, 0);
1668 netif_ip6_addr_set_state(lwip_netif, i, IP6_ADDR_INVALID);
1669 }
1670 #endif
1671 #if CONFIG_LWIP_IPV4
1672 netif_set_addr(lwip_netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
1673 #endif
1674 netif_set_down(lwip_netif);
1675 netif_set_link_down(lwip_netif);
1676
1677 if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
1678 #if CONFIG_LWIP_IPV4
1679 esp_netif_start_ip_lost_timer(esp_netif);
1680 #endif
1681 }
1682
1683 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
1684
1685 return ESP_OK;
1686 }
1687
esp_netif_down(esp_netif_t * esp_netif)1688 esp_err_t esp_netif_down(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK(esp_netif_down_api, esp_netif, NULL)
1689
1690 bool esp_netif_is_netif_up(esp_netif_t *esp_netif)
1691 {
1692 ESP_LOGV(TAG, "%s esp_netif:%p", __func__, esp_netif);
1693
1694 if (esp_netif != NULL && esp_netif->lwip_netif != NULL) {
1695 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1696 // ppp implementation uses netif_set_link_up/down to update link state
1697 return netif_is_link_up(esp_netif->lwip_netif);
1698 }
1699 // esp-netif handlers and drivers take care to set_netif_up/down on link state update
1700 return netif_is_up(esp_netif->lwip_netif);
1701 } else {
1702 return false;
1703 }
1704 }
1705
1706 #if CONFIG_LWIP_IPV4
esp_netif_get_old_ip_info(esp_netif_t * esp_netif,esp_netif_ip_info_t * ip_info)1707 esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
1708 {
1709 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1710
1711 if (esp_netif == NULL || ip_info == NULL) {
1712 return ESP_ERR_INVALID_ARG;
1713 }
1714 memcpy(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t));
1715 return ESP_OK;
1716 }
1717
esp_netif_get_ip_info(esp_netif_t * esp_netif,esp_netif_ip_info_t * ip_info)1718 esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
1719 {
1720 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1721
1722 if (esp_netif == NULL || ip_info == NULL) {
1723 return ESP_ERR_INVALID_ARG;
1724 }
1725
1726 struct netif *p_netif = esp_netif->lwip_netif;
1727
1728 if (p_netif != NULL && netif_is_up(p_netif)) {
1729 ip4_addr_set(&ip_info->ip, ip_2_ip4(&p_netif->ip_addr));
1730 ip4_addr_set(&ip_info->netmask, ip_2_ip4(&p_netif->netmask));
1731 ip4_addr_set(&ip_info->gw, ip_2_ip4(&p_netif->gw));
1732
1733 return ESP_OK;
1734 }
1735
1736 memcpy(ip_info, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
1737
1738 return ESP_OK;
1739 }
1740
1741
esp_netif_is_valid_static_ip(esp_netif_ip_info_t * ip_info)1742 bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info)
1743 {
1744 if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask))) {
1745 // let's assume valid ip_info is when none of ip and netmask is 'any' address (zeros)
1746 return true;
1747 }
1748 return false;
1749 }
1750
esp_netif_set_ip_old_info_api(esp_netif_api_msg_t * msg)1751 static esp_err_t esp_netif_set_ip_old_info_api(esp_netif_api_msg_t *msg)
1752 {
1753 esp_netif_t *esp_netif = msg->esp_netif;
1754 const esp_netif_ip_info_t *ip_info = msg->data;
1755
1756 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1757
1758 if (esp_netif == NULL || ip_info == NULL) {
1759 return ESP_ERR_INVALID_STATE;
1760 }
1761
1762 memcpy(msg->esp_netif->ip_info_old, msg->data, sizeof(esp_netif_ip_info_t));
1763 return ESP_OK;
1764 }
1765
esp_netif_set_old_ip_info(esp_netif_t * esp_netif,const esp_netif_ip_info_t * ip_info)1766 esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_old_info_api, esp_netif, ip_info)
1767
1768 static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg)
1769 {
1770 esp_netif_t *esp_netif = msg->esp_netif;
1771 const esp_netif_ip_info_t *ip_info = msg->data;
1772
1773 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1774
1775 if (esp_netif == NULL || ip_info == NULL) {
1776 return ESP_ERR_INVALID_STATE;
1777 }
1778
1779 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1780 if (esp_netif->dhcps_status != ESP_NETIF_DHCP_STOPPED) {
1781 return ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED;
1782 }
1783 } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
1784 if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED) {
1785 return ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED;
1786 }
1787 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
1788 dns_clear_servers(true);
1789 #endif
1790 }
1791
1792 ip4_addr_copy(esp_netif->ip_info->ip, ip_info->ip);
1793 ip4_addr_copy(esp_netif->ip_info->gw, ip_info->gw);
1794 ip4_addr_copy(esp_netif->ip_info->netmask, ip_info->netmask);
1795
1796 struct netif *p_netif = esp_netif->lwip_netif;
1797
1798 if (p_netif != NULL && netif_is_up(p_netif)) {
1799 netif_set_addr(p_netif, (ip4_addr_t*)&ip_info->ip, (ip4_addr_t*)&ip_info->netmask, (ip4_addr_t*)&ip_info->gw);
1800 if (ESP_NETIF_FLAG_EVENT_IP_MODIFIED & esp_netif->flags) {
1801 if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask) || ip4_addr_isany_val(ip_info->gw))) {
1802
1803 ip_event_t evt_id = esp_netif->get_ip_event;
1804 ip_event_got_ip_t evt = { .esp_netif = esp_netif, .ip_changed = false};
1805 int ret;
1806 if (memcmp(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t))) {
1807 evt.ip_changed = true;
1808 }
1809
1810 memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t));
1811 memcpy(esp_netif->ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
1812 ret = esp_event_post(IP_EVENT, evt_id, &evt, sizeof(evt), 0);
1813 if (ESP_OK != ret) {
1814 ESP_LOGE(TAG, "set ip info: failed to post got ip event (%x)", ret);
1815 }
1816
1817 ESP_LOGD(TAG, "if%p netif set static ip: ip changed=%d", esp_netif, evt.ip_changed);
1818
1819 }
1820 }
1821 }
1822
1823 return ESP_OK;
1824 }
1825
1826 esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_info_api, esp_netif, ip_info)
1827 #endif /* CONFIG_LWIP_IPV4 */
1828
1829 struct array_mac_ip_t {
1830 int num;
1831 esp_netif_pair_mac_ip_t *mac_ip_pair;
1832 };
1833
1834 #if CONFIG_LWIP_DHCPS
esp_netif_dhcps_get_clients_by_mac_api(esp_netif_api_msg_t * msg)1835 static esp_err_t esp_netif_dhcps_get_clients_by_mac_api(esp_netif_api_msg_t *msg)
1836 {
1837 esp_netif_t *netif = msg->esp_netif;
1838 struct array_mac_ip_t *mac_ip_list = msg->data;
1839 for (int i = 0; i < mac_ip_list->num; i++) {
1840 dhcp_search_ip_on_mac(netif->dhcps, mac_ip_list->mac_ip_pair[i].mac, (ip4_addr_t*)&mac_ip_list->mac_ip_pair[i].ip);
1841 }
1842 return ESP_OK;
1843 }
1844 #endif // CONFIG_LWIP_DHCPS
1845
esp_netif_dhcps_get_clients_by_mac(esp_netif_t * esp_netif,int num,esp_netif_pair_mac_ip_t * mac_ip_pair)1846 esp_err_t esp_netif_dhcps_get_clients_by_mac(esp_netif_t *esp_netif, int num, esp_netif_pair_mac_ip_t *mac_ip_pair)
1847 {
1848 #if CONFIG_LWIP_DHCPS
1849 if (esp_netif == NULL || esp_netif->dhcps == NULL || num < 0 || mac_ip_pair == NULL) {
1850 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1851 }
1852 struct array_mac_ip_t array_mac_ip = { num, mac_ip_pair };
1853 return esp_netif_lwip_ipc_call(esp_netif_dhcps_get_clients_by_mac_api, esp_netif, (void *)&array_mac_ip);
1854 #else
1855 return ESP_ERR_NOT_SUPPORTED;
1856 #endif // CONFIG_LWIP_DHCPS
1857 }
1858
esp_netif_set_dns_info_api(esp_netif_api_msg_t * msg)1859 static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg)
1860 {
1861 esp_netif_t *esp_netif = msg->esp_netif;
1862 esp_netif_dns_param_t *dns_param = msg->data;
1863 esp_netif_dns_type_t type = dns_param->dns_type;
1864 esp_netif_dns_info_t *dns = dns_param->dns_info;
1865
1866 ESP_LOGD(TAG, "esp_netif_set_dns_info: if=%p type=%d dns=%x", esp_netif, type, dns->ip.u_addr.ip4.addr);
1867
1868 ip_addr_t lwip_ip = {};
1869 ESPIP_TO_IP(&dns->ip, &lwip_ip);
1870 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1871 #if ESP_DHCPS
1872 // if DHCP server configured to set DNS in dhcps API
1873 if (type != ESP_NETIF_DNS_MAIN) {
1874 ESP_LOGD(TAG, "set dns invalid type");
1875 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1876 } else {
1877 dhcps_dns_setserver(esp_netif->dhcps, &lwip_ip);
1878 }
1879 #else
1880 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
1881 #endif
1882 } else {
1883 dns_setserver(type, &lwip_ip);
1884 }
1885
1886 return ESP_OK;
1887 }
1888
esp_netif_set_dns_info(esp_netif_t * esp_netif,esp_netif_dns_type_t type,esp_netif_dns_info_t * dns)1889 esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
1890 {
1891 if (esp_netif == NULL) {
1892 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1893 }
1894
1895 if (dns == NULL) {
1896 ESP_LOGD(TAG, "set dns null dns");
1897 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1898 }
1899
1900 if (ESP_IP_IS_ANY(dns->ip)) {
1901 ESP_LOGD(TAG, "set dns invalid dns");
1902 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1903 }
1904
1905 esp_netif_dns_param_t dns_param = {
1906 .dns_type = type,
1907 .dns_info = dns
1908 };
1909 return esp_netif_lwip_ipc_call(esp_netif_set_dns_info_api, esp_netif, (void *)&dns_param);
1910 }
1911
esp_netif_get_dns_info_api(esp_netif_api_msg_t * msg)1912 static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg)
1913 {
1914 esp_netif_t *esp_netif = msg->esp_netif;
1915 esp_netif_dns_param_t *dns_param = msg->data;
1916 esp_netif_dns_type_t type = dns_param->dns_type;
1917 esp_netif_dns_info_t *dns = dns_param->dns_info;
1918
1919 ESP_LOGD(TAG, "esp_netif_get_dns_info: esp_netif=%p type=%d", esp_netif, type);
1920
1921 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1922 #if ESP_DHCPS
1923 ip4_addr_t dns_ip;
1924 dhcps_dns_getserver(esp_netif->dhcps, &dns_ip);
1925 memcpy(&dns->ip.u_addr.ip4, &dns_ip, sizeof(ip4_addr_t));
1926 dns->ip.type = ESP_IPADDR_TYPE_V4;
1927 #else
1928 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
1929 #endif
1930 } else {
1931 const ip_addr_t* dns_ip = NULL;
1932 dns_ip = dns_getserver(type);
1933 if(dns_ip != NULL) {
1934 IP_TO_ESPIP(dns_ip, &dns->ip);
1935 }
1936 }
1937
1938 return ESP_OK;
1939 }
1940
esp_netif_get_dns_info(esp_netif_t * esp_netif,esp_netif_dns_type_t type,esp_netif_dns_info_t * dns)1941 esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
1942 {
1943 if (esp_netif == NULL) {
1944 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1945 }
1946
1947 if (dns == NULL) {
1948 ESP_LOGE(TAG, "%s: dns_info cannot be NULL", __func__);
1949 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1950 }
1951
1952 esp_netif_dns_param_t dns_param = {
1953 .dns_type = type,
1954 .dns_info = dns
1955 };
1956 return esp_netif_lwip_ipc_call(esp_netif_get_dns_info_api, esp_netif, (void *)&dns_param);
1957 }
1958
1959 #if CONFIG_LWIP_IPV6
1960
1961 #ifdef CONFIG_LWIP_MLDV6_TMR_INTERVAL
1962
netif_send_mldv6(void * arg)1963 static void netif_send_mldv6(void *arg)
1964 {
1965 struct netif *netif = arg;
1966 if (!netif_is_up(netif)) {
1967 return;
1968 }
1969 mld6_report_groups(netif);
1970 sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, netif);
1971 }
1972
netif_set_mldv6_flag(struct netif * netif)1973 static void netif_set_mldv6_flag(struct netif *netif)
1974 {
1975 if (!netif_is_up(netif)) {
1976 return;
1977 }
1978 sys_timeout(CONFIG_LWIP_MLDV6_TMR_INTERVAL*1000, netif_send_mldv6, netif);
1979 }
1980
netif_unset_mldv6_flag(struct netif * netif)1981 static void netif_unset_mldv6_flag(struct netif *netif)
1982 {
1983 sys_untimeout(netif_send_mldv6, netif);
1984 }
1985
1986 #endif
1987
esp_netif_ip6_get_addr_type(esp_ip6_addr_t * ip6_addr)1988 esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr)
1989 {
1990 ip6_addr_t* lwip_ip6_info = (ip6_addr_t*)ip6_addr;
1991
1992 if (ip6_addr_isglobal(lwip_ip6_info)) {
1993 return ESP_IP6_ADDR_IS_GLOBAL;
1994 } else if (ip6_addr_islinklocal(lwip_ip6_info)) {
1995 return ESP_IP6_ADDR_IS_LINK_LOCAL;
1996 } else if (ip6_addr_issitelocal(lwip_ip6_info)) {
1997 return ESP_IP6_ADDR_IS_SITE_LOCAL;
1998 } else if (ip6_addr_isuniquelocal(lwip_ip6_info)) {
1999 return ESP_IP6_ADDR_IS_UNIQUE_LOCAL;
2000 } else if (ip6_addr_isipv4mappedipv6(lwip_ip6_info)) {
2001 return ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6;
2002 }
2003 return ESP_IP6_ADDR_IS_UNKNOWN;
2004
2005 }
2006
esp_netif_internal_nd6_cb(struct netif * netif,uint8_t ip_index)2007 static void esp_netif_internal_nd6_cb(struct netif *netif, uint8_t ip_index)
2008 {
2009 esp_netif_t *esp_netif;
2010 ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, netif);
2011 if (netif == NULL || (esp_netif = lwip_get_esp_netif(netif)) == NULL) {
2012 // internal pointer hasn't been configured yet (probably in the interface init_fn())
2013 return;
2014 }
2015
2016 esp_netif_ip6_info_t ip6_info;
2017 ip6_addr_t lwip_ip6_info;
2018 ip_event_got_ip6_t evt = { .esp_netif = esp_netif, .ip_index = ip_index };
2019
2020 ip6_addr_set(&lwip_ip6_info, ip_2_ip6(&netif->ip6_addr[ip_index]));
2021 #if LWIP_IPV6_SCOPES
2022 memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(esp_ip6_addr_t));
2023 #else
2024 memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(ip6_addr_t));
2025 ip6_info.ip.zone = 0; // zero out zone, as not used in lwip
2026 #endif /* LWIP_IPV6_SCOPES */
2027
2028 if (esp_netif->flags&ESP_NETIF_FLAG_MLDV6_REPORT) {
2029 #if ESP_MLDV6_REPORT
2030 netif_set_mldv6_flag(netif);
2031 #else
2032 ESP_LOGW(TAG,"CONFIG_LWIP_ESP_MLDV6_REPORT not enabled, but esp-netif configured with ESP_NETIF_FLAG_MLDV6_REPORT");
2033 #endif
2034 }
2035
2036 memcpy(&evt.ip6_info, &ip6_info, sizeof(esp_netif_ip6_info_t));
2037 int ret = esp_event_post(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0);
2038 if (ESP_OK != ret) {
2039 ESP_LOGE(TAG, "nd6 cb: failed to post IP_EVENT_GOT_IP6 (%x)", ret);
2040 }
2041 }
2042
esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t * msg)2043 static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg)
2044 {
2045 esp_netif_t *esp_netif = msg->esp_netif;
2046
2047 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
2048
2049 struct netif *p_netif = esp_netif->lwip_netif;
2050 if (p_netif != NULL && netif_is_up(p_netif)) {
2051 netif_create_ip6_linklocal_address(p_netif, 1);
2052 return ESP_OK;
2053 } else {
2054 return ESP_FAIL;
2055 }
2056 }
2057
esp_netif_create_ip6_linklocal(esp_netif_t * esp_netif)2058 esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_create_ip6_linklocal_api, esp_netif, NULL)
2059
2060 esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
2061 {
2062 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
2063
2064 if (esp_netif == NULL || if_ip6 == NULL || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
2065 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2066 }
2067 struct netif *p_netif = esp_netif->lwip_netif;
2068
2069 if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) {
2070 memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t));
2071 } else {
2072 return ESP_FAIL;
2073 }
2074 return ESP_OK;
2075 }
2076
esp_netif_get_ip6_global(esp_netif_t * esp_netif,esp_ip6_addr_t * if_ip6)2077 esp_err_t esp_netif_get_ip6_global(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
2078 {
2079 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
2080
2081 if (esp_netif == NULL || if_ip6 == NULL) {
2082 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2083 }
2084
2085 int i;
2086 struct netif *p_netif = esp_netif->lwip_netif;
2087
2088 if (p_netif != NULL && netif_is_up(p_netif)) {
2089 for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
2090 if (ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, i)) &&
2091 ip6_addr_isglobal(netif_ip6_addr(p_netif, i))) {
2092 memcpy(if_ip6, &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
2093 return ESP_OK;
2094 }
2095 }
2096 }
2097
2098 return ESP_FAIL;
2099 }
2100
esp_netif_get_all_ip6(esp_netif_t * esp_netif,esp_ip6_addr_t if_ip6[])2101 int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[])
2102 {
2103 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
2104
2105 if (esp_netif == NULL || if_ip6 == NULL) {
2106 return 0;
2107 }
2108
2109 int addr_count = 0;
2110 struct netif *p_netif = esp_netif->lwip_netif;
2111
2112 if (p_netif != NULL && netif_is_up(p_netif)) {
2113 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
2114 if (!ip_addr_cmp(&p_netif->ip6_addr[i], IP6_ADDR_ANY)) {
2115 memcpy(&if_ip6[addr_count++], &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
2116 }
2117 }
2118 }
2119 return addr_count;
2120 }
2121 #endif
2122
esp_netif_get_flags(esp_netif_t * esp_netif)2123 esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif)
2124 {
2125 return esp_netif->flags;
2126 }
2127
esp_netif_get_ifkey(esp_netif_t * esp_netif)2128 const char *esp_netif_get_ifkey(esp_netif_t *esp_netif)
2129 {
2130 return esp_netif->if_key;
2131 }
2132
esp_netif_get_desc(esp_netif_t * esp_netif)2133 const char *esp_netif_get_desc(esp_netif_t *esp_netif)
2134 {
2135 return esp_netif->if_desc;
2136 }
2137
esp_netif_get_route_prio(esp_netif_t * esp_netif)2138 int esp_netif_get_route_prio(esp_netif_t *esp_netif)
2139 {
2140 if (esp_netif == NULL) {
2141 return -1;
2142 }
2143 return esp_netif->route_prio;
2144 }
2145
esp_netif_get_event_id(esp_netif_t * esp_netif,esp_netif_ip_event_type_t event_type)2146 int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type)
2147 {
2148 switch(event_type) {
2149 case ESP_NETIF_IP_EVENT_GOT_IP:
2150 return esp_netif->get_ip_event;
2151 case ESP_NETIF_IP_EVENT_LOST_IP:
2152 return esp_netif->lost_ip_event;
2153 default:
2154 return -1;
2155 }
2156 }
2157
2158 struct dhcp_params {
2159 esp_netif_dhcp_option_mode_t op;
2160 esp_netif_dhcp_option_id_t id;
2161 void *val;
2162 uint32_t len;
2163 };
2164
2165 #if ESP_DHCPS
esp_netif_dhcps_option_api(esp_netif_api_msg_t * msg)2166 esp_err_t esp_netif_dhcps_option_api(esp_netif_api_msg_t *msg)
2167 {
2168 esp_netif_t *esp_netif = msg->esp_netif;
2169 struct dhcp_params *opt = msg->data;
2170 void *opt_info = dhcps_option_info(esp_netif->dhcps, opt->id, opt->len);
2171
2172 esp_netif_dhcp_status_t dhcps_status = esp_netif->dhcps_status;
2173 if (opt_info == NULL || opt->val == NULL) {
2174 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2175 }
2176
2177 if (opt->op == ESP_NETIF_OP_GET) {
2178 if (dhcps_status == ESP_NETIF_DHCP_STOPPED) {
2179 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
2180 }
2181
2182 switch (opt->id) {
2183 case IP_ADDRESS_LEASE_TIME: {
2184 *(uint32_t *)opt->val = *(uint32_t *)opt_info;
2185 break;
2186 }
2187 case ESP_NETIF_SUBNET_MASK:
2188 case REQUESTED_IP_ADDRESS: {
2189 memcpy(opt->val, opt_info, opt->len);
2190 break;
2191 }
2192 case ROUTER_SOLICITATION_ADDRESS: {
2193 if ((*(uint8_t *)opt_info) & OFFER_ROUTER) {
2194 *(uint8_t *)opt->val = 1;
2195 } else {
2196 *(uint8_t *)opt->val = 0;
2197 }
2198 break;
2199 }
2200 case DOMAIN_NAME_SERVER: {
2201 if ((*(uint8_t *)opt_info) & OFFER_DNS) {
2202 *(uint8_t *)opt->val = 1;
2203 } else {
2204 *(uint8_t *)opt->val = 0;
2205 }
2206 break;
2207 }
2208 default:
2209 break;
2210 }
2211 } else if (opt->op == ESP_NETIF_OP_SET) {
2212 if (dhcps_status == ESP_NETIF_DHCP_STARTED) {
2213 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
2214 }
2215
2216 switch (opt->id) {
2217 case IP_ADDRESS_LEASE_TIME: {
2218 if (*(uint32_t *)opt->val != 0) {
2219 *(uint32_t *)opt_info = *(uint32_t *)opt->val;
2220 } else {
2221 *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF;
2222 }
2223 break;
2224 }
2225 case ESP_NETIF_SUBNET_MASK: {
2226 memcpy(opt_info, opt->val, opt->len);
2227 break;
2228 }
2229 case REQUESTED_IP_ADDRESS: {
2230 esp_netif_ip_info_t info;
2231 uint32_t softap_ip = 0;
2232 uint32_t start_ip = 0;
2233 uint32_t end_ip = 0;
2234 dhcps_lease_t *poll = opt->val;
2235
2236 if (poll->enable) {
2237 memset(&info, 0x00, sizeof(esp_netif_ip_info_t));
2238 esp_netif_get_ip_info(esp_netif, &info);
2239
2240 softap_ip = htonl(info.ip.addr);
2241 start_ip = htonl(poll->start_ip.addr);
2242 end_ip = htonl(poll->end_ip.addr);
2243
2244 /*config ip information can't contain local ip*/
2245 if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
2246 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2247 }
2248
2249 /*config ip information must be in the same segment as the local ip*/
2250 softap_ip >>= 8;
2251 if ((start_ip >> 8 != softap_ip)
2252 || (end_ip >> 8 != softap_ip)) {
2253 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2254 }
2255
2256 if (end_ip - start_ip > DHCPS_MAX_LEASE) {
2257 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2258 }
2259 }
2260
2261 memcpy(opt_info, opt->val, opt->len);
2262 break;
2263 }
2264 case ROUTER_SOLICITATION_ADDRESS: {
2265 if (*(uint8_t *)opt->val) {
2266 *(uint8_t *)opt_info |= OFFER_ROUTER;
2267 } else {
2268 *(uint8_t *)opt_info &= ((~OFFER_ROUTER) & 0xFF);
2269 }
2270 break;
2271 }
2272 case DOMAIN_NAME_SERVER: {
2273 if (*(uint8_t *)opt->val) {
2274 *(uint8_t *)opt_info |= OFFER_DNS;
2275 } else {
2276 *(uint8_t *)opt_info &= ((~OFFER_DNS) & 0xFF);
2277 }
2278 break;
2279 }
2280
2281 default:
2282 break;
2283 }
2284 dhcps_set_option_info(esp_netif->dhcps, opt->id, opt_info, opt->len);
2285 } else {
2286 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2287 }
2288
2289 return ESP_OK;
2290 }
2291
esp_netif_dhcps_option(esp_netif_t * esp_netif,esp_netif_dhcp_option_mode_t opt_op,esp_netif_dhcp_option_id_t opt_id,void * opt_val,uint32_t opt_len)2292 esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
2293 uint32_t opt_len)
2294 {
2295 if (esp_netif == NULL || esp_netif->dhcps == NULL) {
2296 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
2297 }
2298 struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val };
2299 return esp_netif_lwip_ipc_call(esp_netif_dhcps_option_api, esp_netif, &opts);
2300 }
2301 #endif // ESP_DHCPS
2302
2303 #if CONFIG_LWIP_IPV4
2304
esp_netif_dhcpc_option_api(esp_netif_api_msg_t * msg)2305 esp_err_t esp_netif_dhcpc_option_api(esp_netif_api_msg_t *msg)
2306 {
2307 esp_netif_t *esp_netif = msg->esp_netif;
2308 struct dhcp_params *opt = msg->data;
2309
2310 struct dhcp *dhcp = netif_dhcp_data(esp_netif->lwip_netif);
2311 if (dhcp == NULL || opt->val == NULL) {
2312 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2313 }
2314 if (opt->op == ESP_NETIF_OP_GET) {
2315 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) {
2316 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
2317 }
2318 switch (opt->id) {
2319 case ESP_NETIF_IP_REQUEST_RETRY_TIME:
2320 if (opt->len == sizeof(dhcp->tries)) {
2321 *(uint8_t *)opt->val = dhcp->tries;
2322 }
2323 break;
2324 #if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
2325 case ESP_NETIF_VENDOR_SPECIFIC_INFO:
2326 return dhcp_get_vendor_specific_information(opt->len, opt->val);
2327 #endif
2328 default:
2329 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2330 }
2331 } else if (opt->op == ESP_NETIF_OP_SET) {
2332 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
2333 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
2334 }
2335 switch (opt->id) {
2336 case ESP_NETIF_IP_REQUEST_RETRY_TIME:
2337 if (opt->len == sizeof(dhcp->tries)) {
2338 dhcp->tries = *(uint8_t *)opt->val;
2339 }
2340 break;
2341 #if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
2342 case ESP_NETIF_VENDOR_CLASS_IDENTIFIER:
2343 return dhcp_set_vendor_class_identifier(opt->len, opt->val);
2344 #endif
2345 default:
2346 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2347 }
2348 } else {
2349 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2350 }
2351 return ESP_OK;
2352 }
2353
esp_netif_dhcpc_option(esp_netif_t * esp_netif,esp_netif_dhcp_option_mode_t opt_op,esp_netif_dhcp_option_id_t opt_id,void * opt_val,uint32_t opt_len)2354 esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
2355 uint32_t opt_len)
2356 {
2357 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
2358 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
2359 }
2360 struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val };
2361 return esp_netif_lwip_ipc_call(esp_netif_dhcpc_option_api, esp_netif, &opts);
2362 }
2363
2364 #endif /* CONFIG_LWIP_IPV4 */
2365
esp_netif_get_netif_impl_index(esp_netif_t * esp_netif)2366 int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
2367 {
2368 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
2369 return -1;
2370 }
2371 return netif_get_index(esp_netif->lwip_netif);
2372 }
2373
esp_netif_get_netif_impl_name_api(esp_netif_api_msg_t * msg)2374 esp_err_t esp_netif_get_netif_impl_name_api(esp_netif_api_msg_t *msg)
2375 {
2376 struct netif* netif = msg->esp_netif->lwip_netif;
2377 netif_index_to_name(netif_get_index(netif), msg->data);
2378 return ESP_OK;
2379 }
2380
esp_netif_get_netif_impl_name(esp_netif_t * esp_netif,char * name)2381 esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name)
2382 {
2383 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
2384
2385 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
2386 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
2387 }
2388 return esp_netif_lwip_ipc_call(esp_netif_get_netif_impl_name_api, esp_netif, name);
2389 }
2390
esp_netif_napt_enable(esp_netif_t * esp_netif)2391 esp_err_t esp_netif_napt_enable(esp_netif_t *esp_netif)
2392 {
2393 #if !IP_NAPT
2394 return ESP_ERR_NOT_SUPPORTED;
2395 #else
2396 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
2397
2398 /* Check if the interface is up */
2399 if (!netif_is_up(esp_netif->lwip_netif)) {
2400 return ESP_FAIL;
2401 }
2402
2403 esp_netif_list_lock();
2404 /* Disable napt on all other interface */
2405 esp_netif_t *netif = esp_netif_next_unsafe(NULL);
2406 while (netif) {
2407 if (netif != esp_netif) {
2408 ip_napt_enable_netif(netif->lwip_netif, 0); // Fails only if netif is down
2409 ESP_LOGW(TAG, "napt disabled on esp_netif:%p", esp_netif);
2410 }
2411 netif = esp_netif_next_unsafe(netif);
2412 }
2413
2414 int ret = ip_napt_enable_netif(esp_netif->lwip_netif, 1);
2415 esp_netif_list_unlock();
2416
2417 if (ret == 0) {
2418 return ESP_FAIL;
2419 }
2420
2421 return ESP_OK;
2422 #endif /* IP_NAPT */
2423 }
2424
esp_netif_napt_disable(esp_netif_t * esp_netif)2425 esp_err_t esp_netif_napt_disable(esp_netif_t *esp_netif)
2426 {
2427 #if !IP_NAPT
2428 return ESP_ERR_NOT_SUPPORTED;
2429 #else
2430 /* Check if the interface is up */
2431 if (!netif_is_up(esp_netif->lwip_netif)) {
2432 return ESP_FAIL;
2433 }
2434
2435 esp_netif_list_lock();
2436 ip_napt_enable_netif(esp_netif->lwip_netif, 0); // Fails only if netif is down
2437 ESP_LOGD(TAG, "napt disabled on esp_netif:%p", esp_netif);
2438 esp_netif_list_unlock();
2439
2440 return ESP_OK;
2441 #endif /* IP_NAPT */
2442 }
2443
2444 #if MIB2_STATS
esp_netif_set_link_speed_api(esp_netif_api_msg_t * msg)2445 static esp_err_t esp_netif_set_link_speed_api(esp_netif_api_msg_t *msg)
2446 {
2447 uint32_t speed = *((uint32_t*)msg->data);
2448 esp_err_t error = ESP_OK;
2449 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
2450 NETIF_INIT_SNMP(msg->esp_netif->lwip_netif, snmp_ifType_ethernet_csmacd, speed);
2451 LWIP_UNUSED_ARG(speed); // Maybe unused if SNMP disabled
2452 return error;
2453 }
2454
esp_netif_set_link_speed(esp_netif_t * esp_netif,uint32_t speed)2455 esp_err_t esp_netif_set_link_speed(esp_netif_t *esp_netif, uint32_t speed)
2456 _RUN_IN_LWIP_TASK(esp_netif_set_link_speed_api, esp_netif, &speed)
2457 #else
2458 esp_err_t esp_netif_set_link_speed(esp_netif_t *esp_netif, uint32_t speed)
2459 {
2460 // link speed is used only to collect interface related statistics (if MIB2_STATS enabled)
2461 return ESP_OK;
2462 }
2463 #endif /* MIB2_STATS */
2464
2465 #if CONFIG_LWIP_IPV6
2466
2467 static esp_err_t esp_netif_join_ip6_multicast_group_api(esp_netif_api_msg_t *msg)
2468 {
2469 esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
2470 esp_err_t error = ESP_OK;
2471 ip6_addr_t ip6addr;
2472
2473 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
2474 memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
2475 #if LWIP_IPV6_SCOPES
2476 ip6addr.zone = 0;
2477 #endif
2478 if (mld6_joingroup_netif(msg->esp_netif->lwip_netif, &ip6addr) != ERR_OK) {
2479 error = ESP_ERR_ESP_NETIF_MLD6_FAILED;
2480 ESP_LOGE(TAG, "failed to join ip6 multicast group");
2481 }
2482 return error;
2483 }
2484
esp_netif_join_ip6_multicast_group(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)2485 esp_err_t esp_netif_join_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
2486 _RUN_IN_LWIP_TASK(esp_netif_join_ip6_multicast_group_api, esp_netif, addr)
2487
2488 static esp_err_t esp_netif_leave_ip6_multicast_group_api(esp_netif_api_msg_t *msg)
2489 {
2490 esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
2491 ip6_addr_t ip6addr;
2492
2493 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
2494 memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
2495 #if LWIP_IPV6_SCOPES
2496 ip6addr.zone = 0;
2497 #endif
2498 ESP_RETURN_ON_FALSE(mld6_leavegroup_netif(msg->esp_netif->lwip_netif, &ip6addr) == ERR_OK,
2499 ESP_ERR_ESP_NETIF_MLD6_FAILED, TAG, "Failed to leave ip6 multicast group");
2500 return ESP_OK;
2501 }
2502
esp_netif_leave_ip6_multicast_group(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)2503 esp_err_t esp_netif_leave_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
2504 _RUN_IN_LWIP_TASK(esp_netif_leave_ip6_multicast_group_api, esp_netif, addr)
2505
2506 static esp_err_t esp_netif_add_ip6_address_api(esp_netif_api_msg_t *msg)
2507 {
2508 ip_event_add_ip6_t *addr = (ip_event_add_ip6_t *)msg->data;
2509 ip6_addr_t ip6addr;
2510 esp_err_t error = ESP_OK;
2511 int8_t index = -1;
2512
2513 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
2514 memcpy(ip6addr.addr, addr->addr.addr, sizeof(ip6addr.addr));
2515 #if LWIP_IPV6_SCOPES
2516 ip6addr.zone = 0;
2517 #endif
2518 err_t err = netif_add_ip6_address(msg->esp_netif->lwip_netif, &ip6addr, &index);
2519 ESP_RETURN_ON_FALSE(err == ERR_OK && index >= 0, ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED, TAG,
2520 "Failed to add ip6 address");
2521
2522 netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index,
2523 addr->preferred ? IP6_ADDR_PREFERRED : IP6_ADDR_DEPRECATED);
2524 ip_event_got_ip6_t evt = {.esp_netif = msg->esp_netif, .ip_index = index};
2525 evt.ip6_info.ip = addr->addr;
2526 ESP_RETURN_ON_ERROR(esp_event_post(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0), TAG,
2527 "Failed to post IP_EVENT_GOT_IP6");
2528 return error;
2529 }
2530
esp_netif_add_ip6_address(esp_netif_t * esp_netif,const ip_event_add_ip6_t * addr)2531 esp_err_t esp_netif_add_ip6_address(esp_netif_t *esp_netif, const ip_event_add_ip6_t *addr)
2532 _RUN_IN_LWIP_TASK(esp_netif_add_ip6_address_api, esp_netif, addr)
2533
2534 static esp_err_t esp_netif_remove_ip6_address_api(esp_netif_api_msg_t *msg)
2535 {
2536 esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
2537 ip6_addr_t ip6addr;
2538
2539 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
2540 memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
2541 #if LWIP_IPV6_SCOPES
2542 ip6addr.zone = 0;
2543 #endif
2544 int8_t index = netif_get_ip6_addr_match(msg->esp_netif->lwip_netif, &ip6addr);
2545 if (index != -1) {
2546 netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index, IP6_ADDR_INVALID);
2547 }
2548 return ESP_OK;
2549 }
2550
2551 esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
2552 _RUN_IN_LWIP_TASK(esp_netif_remove_ip6_address_api, esp_netif, addr)
2553
2554 #endif // CONFIG_LWIP_IPV6
2555