1 /* init.c */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_config, CONFIG_NET_CONFIG_LOG_LEVEL);
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/init.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <stdlib.h>
17 
18 #include <zephyr/logging/log_backend.h>
19 #include <zephyr/logging/log_backend_net.h>
20 #include <zephyr/net/ethernet.h>
21 #include <zephyr/net/net_core.h>
22 #include <zephyr/net/net_ip.h>
23 #include <zephyr/net/net_if.h>
24 #include <zephyr/net/dhcpv4.h>
25 #include <zephyr/net/dhcpv6.h>
26 #include <zephyr/net/net_mgmt.h>
27 #include <zephyr/net/dns_resolve.h>
28 
29 #include <zephyr/net/net_config.h>
30 
31 #include "ieee802154_settings.h"
32 
33 extern int net_init_clock_via_sntp(void);
34 
35 static K_SEM_DEFINE(waiter, 0, 1);
36 static K_SEM_DEFINE(counter, 0, UINT_MAX);
37 static atomic_t services_flags;
38 
39 #if defined(CONFIG_NET_NATIVE)
40 static struct net_mgmt_event_callback mgmt_iface_cb;
41 #endif
42 
services_notify_ready(int flags)43 static inline void services_notify_ready(int flags)
44 {
45 	atomic_or(&services_flags, flags);
46 	k_sem_give(&waiter);
47 }
48 
services_are_ready(int flags)49 static inline bool services_are_ready(int flags)
50 {
51 	return (atomic_get(&services_flags) & flags) == flags;
52 }
53 
54 #if defined(CONFIG_NET_NATIVE_IPV4)
55 
56 #if defined(CONFIG_NET_DHCPV4)
57 
setup_dhcpv4(struct net_if * iface)58 static void setup_dhcpv4(struct net_if *iface)
59 {
60 	NET_INFO("Running dhcpv4 client...");
61 
62 	net_dhcpv4_start(iface);
63 }
64 
print_dhcpv4_info(struct net_if * iface)65 static void print_dhcpv4_info(struct net_if *iface)
66 {
67 #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF
68 	char hr_addr[NET_IPV4_ADDR_LEN];
69 #endif
70 	ARRAY_FOR_EACH(iface->config.ip.ipv4->unicast, i) {
71 		struct net_if_addr *if_addr =
72 					&iface->config.ip.ipv4->unicast[i].ipv4;
73 
74 		if (if_addr->addr_type != NET_ADDR_DHCP ||
75 		    !if_addr->is_used) {
76 			continue;
77 		}
78 
79 #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF
80 		NET_INFO("IPv4 address: %s",
81 			 net_addr_ntop(AF_INET, &if_addr->address.in_addr,
82 				       hr_addr, sizeof(hr_addr)));
83 		NET_INFO("Lease time: %u seconds",
84 			 iface->config.dhcpv4.lease_time);
85 		NET_INFO("Subnet: %s",
86 			 net_addr_ntop(AF_INET,
87 				       &iface->config.ip.ipv4->unicast[i].netmask,
88 				       hr_addr, sizeof(hr_addr)));
89 		NET_INFO("Router: %s",
90 			 net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw,
91 				       hr_addr, sizeof(hr_addr)));
92 #endif
93 		break;
94 	}
95 }
96 
97 #else
98 #define setup_dhcpv4(...)
99 #define print_dhcpv4_info(...)
100 #endif /* CONFIG_NET_DHCPV4 */
101 
102 static struct net_mgmt_event_callback mgmt4_cb;
103 
ipv4_addr_add_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)104 static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb,
105 				  uint32_t mgmt_event,
106 				  struct net_if *iface)
107 {
108 	if (mgmt_event == NET_EVENT_IPV4_ADDR_ADD) {
109 		print_dhcpv4_info(iface);
110 
111 		if (!IS_ENABLED(CONFIG_NET_IPV4_ACD)) {
112 			services_notify_ready(NET_CONFIG_NEED_IPV4);
113 		}
114 	}
115 
116 	if (mgmt_event == NET_EVENT_IPV4_ACD_SUCCEED) {
117 		services_notify_ready(NET_CONFIG_NEED_IPV4);
118 	}
119 }
120 
121 #if defined(CONFIG_NET_VLAN) && (CONFIG_NET_CONFIG_MY_VLAN_ID > 0)
122 
setup_vlan(struct net_if * iface)123 static void setup_vlan(struct net_if *iface)
124 {
125 	int ret = net_eth_vlan_enable(iface, CONFIG_NET_CONFIG_MY_VLAN_ID);
126 
127 	if (ret < 0) {
128 		NET_ERR("Network interface %d (%p): cannot set VLAN tag (%d)",
129 			net_if_get_by_iface(iface), iface, ret);
130 	}
131 }
132 
133 #else
134 #define setup_vlan(...)
135 #endif /* CONFIG_NET_VLAN && (CONFIG_NET_CONFIG_MY_VLAN_ID > 0) */
136 
137 #if defined(CONFIG_NET_NATIVE_IPV4) && !defined(CONFIG_NET_DHCPV4) && \
138 	!defined(CONFIG_NET_CONFIG_MY_IPV4_ADDR)
139 #error "You need to define an IPv4 address or enable DHCPv4!"
140 #endif
141 
setup_ipv4(struct net_if * iface)142 static void setup_ipv4(struct net_if *iface)
143 {
144 #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF
145 	char hr_addr[NET_IPV4_ADDR_LEN];
146 #endif
147 	struct in_addr addr, netmask;
148 
149 	if (IS_ENABLED(CONFIG_NET_IPV4_ACD) || IS_ENABLED(CONFIG_NET_DHCPV4)) {
150 		net_mgmt_init_event_callback(&mgmt4_cb, ipv4_addr_add_handler,
151 					     NET_EVENT_IPV4_ADDR_ADD |
152 					     NET_EVENT_IPV4_ACD_SUCCEED);
153 		net_mgmt_add_event_callback(&mgmt4_cb);
154 	}
155 
156 	if (sizeof(CONFIG_NET_CONFIG_MY_IPV4_ADDR) == 1) {
157 		/* Empty address, skip setting ANY address in this case */
158 		return;
159 	}
160 
161 	if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &addr)) {
162 		NET_ERR("Invalid address: %s", CONFIG_NET_CONFIG_MY_IPV4_ADDR);
163 		return;
164 	}
165 
166 #if defined(CONFIG_NET_DHCPV4)
167 	/* In case DHCP is enabled, make the static address tentative,
168 	 * to allow DHCP address to override it. This covers a usecase
169 	 * of "there should be a static IP address for DHCP-less setups",
170 	 * but DHCP should override it (to use it, NET_IF_MAX_IPV4_ADDR
171 	 * should be set to 1). There is another usecase: "there should
172 	 * always be static IP address, and optionally, DHCP address".
173 	 * For that to work, NET_IF_MAX_IPV4_ADDR should be 2 (or more).
174 	 * (In this case, an app will need to bind to the needed addr
175 	 * explicitly.)
176 	 */
177 	net_if_ipv4_addr_add(iface, &addr, NET_ADDR_OVERRIDABLE, 0);
178 #else
179 	net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0);
180 #endif
181 
182 #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF
183 	NET_INFO("IPv4 address: %s",
184 		 net_addr_ntop(AF_INET, &addr, hr_addr, sizeof(hr_addr)));
185 #endif
186 
187 	if (sizeof(CONFIG_NET_CONFIG_MY_IPV4_NETMASK) > 1) {
188 		/* If not empty */
189 		if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_NETMASK,
190 				  &netmask)) {
191 			NET_ERR("Invalid netmask: %s",
192 				CONFIG_NET_CONFIG_MY_IPV4_NETMASK);
193 		} else {
194 			net_if_ipv4_set_netmask_by_addr(iface, &addr, &netmask);
195 		}
196 	}
197 
198 	if (sizeof(CONFIG_NET_CONFIG_MY_IPV4_GW) > 1) {
199 		/* If not empty */
200 		if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_GW,
201 				  &addr)) {
202 			NET_ERR("Invalid gateway: %s",
203 				CONFIG_NET_CONFIG_MY_IPV4_GW);
204 		} else {
205 			net_if_ipv4_set_gw(iface, &addr);
206 		}
207 	}
208 
209 	if (!IS_ENABLED(CONFIG_NET_IPV4_ACD)) {
210 		services_notify_ready(NET_CONFIG_NEED_IPV4);
211 	}
212 }
213 
214 #else
215 #define setup_ipv4(...)
216 #define setup_dhcpv4(...)
217 #define setup_vlan(...)
218 #endif /* CONFIG_NET_NATIVE_IPV4*/
219 
220 #if defined(CONFIG_NET_NATIVE_IPV6)
221 
222 #if defined(CONFIG_NET_DHCPV6)
setup_dhcpv6(struct net_if * iface)223 static void setup_dhcpv6(struct net_if *iface)
224 {
225 	struct net_dhcpv6_params params = {
226 		.request_addr = IS_ENABLED(CONFIG_NET_CONFIG_DHCPV6_REQUEST_ADDR),
227 		.request_prefix = IS_ENABLED(CONFIG_NET_CONFIG_DHCPV6_REQUEST_PREFIX),
228 	};
229 
230 	NET_INFO("Running dhcpv6 client...");
231 
232 	net_dhcpv6_start(iface, &params);
233 }
234 #else /* CONFIG_NET_DHCPV6 */
235 #define setup_dhcpv6(...)
236 #endif /* CONFIG_NET_DHCPV6 */
237 
238 #if !defined(CONFIG_NET_CONFIG_DHCPV6_REQUEST_ADDR) && \
239 	!defined(CONFIG_NET_CONFIG_MY_IPV6_ADDR)
240 #error "You need to define an IPv6 address or enable DHCPv6!"
241 #endif
242 
243 static struct net_mgmt_event_callback mgmt6_cb;
244 static struct in6_addr laddr;
245 
ipv6_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)246 static void ipv6_event_handler(struct net_mgmt_event_callback *cb,
247 			       uint32_t mgmt_event, struct net_if *iface)
248 {
249 	struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6;
250 	int i;
251 
252 	if (!ipv6) {
253 		return;
254 	}
255 
256 	if (mgmt_event == NET_EVENT_IPV6_ADDR_ADD) {
257 		/* save the last added IP address for this interface */
258 		for (i = NET_IF_MAX_IPV6_ADDR - 1; i >= 0; i--) {
259 			if (ipv6->unicast[i].is_used) {
260 				memcpy(&laddr,
261 				       &ipv6->unicast[i].address.in6_addr,
262 				       sizeof(laddr));
263 				break;
264 			}
265 		}
266 	}
267 
268 	if (mgmt_event == NET_EVENT_IPV6_DAD_SUCCEED) {
269 #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF
270 		char hr_addr[NET_IPV6_ADDR_LEN];
271 #endif
272 		struct net_if_addr *ifaddr;
273 
274 		ifaddr = net_if_ipv6_addr_lookup(&laddr, &iface);
275 		if (!ifaddr ||
276 		    !(net_ipv6_addr_cmp(&ifaddr->address.in6_addr, &laddr) &&
277 		      ifaddr->addr_state == NET_ADDR_PREFERRED)) {
278 			/* Address is not yet properly setup */
279 			return;
280 		}
281 
282 #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF
283 		NET_INFO("IPv6 address: %s",
284 			 net_addr_ntop(AF_INET6, &laddr, hr_addr, NET_IPV6_ADDR_LEN));
285 
286 		if (ifaddr->addr_type == NET_ADDR_DHCP) {
287 			char remaining_str[] = "infinite";
288 			uint32_t remaining;
289 
290 			remaining = net_timeout_remaining(&ifaddr->lifetime,
291 							  k_uptime_get_32());
292 
293 			if (!ifaddr->is_infinite) {
294 				snprintk(remaining_str, sizeof(remaining_str),
295 					 "%u", remaining);
296 			}
297 
298 			NET_INFO("Lifetime: %s seconds", remaining_str);
299 		}
300 #endif
301 
302 		services_notify_ready(NET_CONFIG_NEED_IPV6);
303 	}
304 
305 	if (mgmt_event == NET_EVENT_IPV6_ROUTER_ADD) {
306 		services_notify_ready(NET_CONFIG_NEED_ROUTER);
307 	}
308 }
309 
setup_ipv6(struct net_if * iface,uint32_t flags)310 static void setup_ipv6(struct net_if *iface, uint32_t flags)
311 {
312 	struct net_if_addr *ifaddr;
313 	uint32_t mask = NET_EVENT_IPV6_DAD_SUCCEED;
314 
315 	if (sizeof(CONFIG_NET_CONFIG_MY_IPV6_ADDR) == 1) {
316 		/* Empty address, skip setting ANY address in this case */
317 		goto exit;
318 	}
319 
320 	if (net_addr_pton(AF_INET6, CONFIG_NET_CONFIG_MY_IPV6_ADDR, &laddr)) {
321 		NET_ERR("Invalid address: %s", CONFIG_NET_CONFIG_MY_IPV6_ADDR);
322 		/* some interfaces may add IP address later */
323 		mask |= NET_EVENT_IPV6_ADDR_ADD;
324 	}
325 
326 	if (flags & NET_CONFIG_NEED_ROUTER) {
327 		mask |= NET_EVENT_IPV6_ROUTER_ADD;
328 	}
329 
330 	net_mgmt_init_event_callback(&mgmt6_cb, ipv6_event_handler, mask);
331 	net_mgmt_add_event_callback(&mgmt6_cb);
332 
333 	/*
334 	 * check for CMD_ADDR_ADD bit here, NET_EVENT_IPV6_ADDR_ADD is
335 	 * a combination of _NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_ADDR_ADD
336 	 * so it will always return != NET_EVENT_IPV6_CMD_ADDR_ADD if any other
337 	 * event is set (for instance NET_EVENT_IPV6_ROUTER_ADD)
338 	 */
339 	if ((mask & NET_EVENT_IPV6_CMD_ADDR_ADD) ==
340 	    NET_EVENT_IPV6_CMD_ADDR_ADD) {
341 		ifaddr = net_if_ipv6_addr_add(iface, &laddr,
342 					      NET_ADDR_MANUAL, 0);
343 		if (!ifaddr) {
344 			NET_ERR("Cannot add %s to interface",
345 				CONFIG_NET_CONFIG_MY_IPV6_ADDR);
346 		}
347 	}
348 
349 exit:
350 
351 	if (!IS_ENABLED(CONFIG_NET_IPV6_DAD) ||
352 	    net_if_flag_is_set(iface, NET_IF_IPV6_NO_ND)) {
353 		services_notify_ready(NET_CONFIG_NEED_IPV6);
354 	}
355 
356 	return;
357 }
358 
359 #else
360 #define setup_ipv6(...)
361 #define setup_dhcpv6(...)
362 #endif /* CONFIG_NET_IPV6 */
363 
364 #if defined(CONFIG_NET_NATIVE)
iface_up_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)365 static void iface_up_handler(struct net_mgmt_event_callback *cb,
366 			     uint32_t mgmt_event, struct net_if *iface)
367 {
368 	if (mgmt_event == NET_EVENT_IF_UP) {
369 		NET_INFO("Interface %d (%p) coming up",
370 			 net_if_get_by_iface(iface), iface);
371 
372 		k_sem_reset(&counter);
373 		k_sem_give(&waiter);
374 	}
375 }
376 
check_interface(struct net_if * iface)377 static bool check_interface(struct net_if *iface)
378 {
379 	if (net_if_is_up(iface)) {
380 		k_sem_reset(&counter);
381 		k_sem_give(&waiter);
382 		return true;
383 	}
384 
385 	NET_INFO("Waiting interface %d (%p) to be up...",
386 		 net_if_get_by_iface(iface), iface);
387 
388 	net_mgmt_init_event_callback(&mgmt_iface_cb, iface_up_handler,
389 				     NET_EVENT_IF_UP);
390 	net_mgmt_add_event_callback(&mgmt_iface_cb);
391 
392 	return false;
393 }
394 #else
check_interface(struct net_if * iface)395 static bool check_interface(struct net_if *iface)
396 {
397 	k_sem_reset(&counter);
398 	k_sem_give(&waiter);
399 
400 	return true;
401 }
402 #endif
403 
net_config_init_by_iface(struct net_if * iface,const char * app_info,uint32_t flags,int32_t timeout)404 int net_config_init_by_iface(struct net_if *iface, const char *app_info,
405 			     uint32_t flags, int32_t timeout)
406 {
407 #define LOOP_DIVIDER 10
408 	int loop = timeout / LOOP_DIVIDER;
409 	int count;
410 
411 	if (app_info) {
412 		NET_INFO("%s", app_info);
413 	}
414 
415 	if (!iface) {
416 		iface = net_if_get_default();
417 	}
418 
419 	if (!iface) {
420 		return -ENOENT;
421 	}
422 
423 	if (net_if_flag_is_set(iface, NET_IF_NO_AUTO_START)) {
424 		return -ENETDOWN;
425 	}
426 
427 	if (timeout < 0) {
428 		count = -1;
429 	} else if (timeout == 0) {
430 		count = 0;
431 	} else {
432 		count = LOOP_DIVIDER;
433 	}
434 
435 	/* First make sure that network interface is up */
436 	if (check_interface(iface) == false) {
437 		k_sem_init(&counter, 1, K_SEM_MAX_LIMIT);
438 
439 		while (count-- > 0) {
440 			if (!k_sem_count_get(&counter)) {
441 				break;
442 			}
443 
444 			if (k_sem_take(&waiter, K_MSEC(loop))) {
445 				if (!k_sem_count_get(&counter)) {
446 					break;
447 				}
448 			}
449 		}
450 
451 #if defined(CONFIG_NET_NATIVE)
452 		net_mgmt_del_event_callback(&mgmt_iface_cb);
453 #endif
454 	}
455 
456 	setup_vlan(iface);
457 	setup_ipv4(iface);
458 	setup_dhcpv4(iface);
459 	setup_ipv6(iface, flags);
460 	setup_dhcpv6(iface);
461 
462 	/* Network interface did not come up. */
463 	if (timeout > 0 && count < 0) {
464 		NET_ERR("Timeout while waiting network %s", "interface");
465 		return -ENETDOWN;
466 	}
467 
468 	/* Loop here until we are ready to continue. As we might need
469 	 * to wait multiple events, sleep smaller amounts of data.
470 	 */
471 	while (!services_are_ready(flags) && count-- > 0) {
472 		k_sem_take(&waiter, K_MSEC(loop));
473 	}
474 
475 	if (count == -1 && timeout > 0) {
476 		NET_ERR("Timeout while waiting network %s", "setup");
477 		return -ETIMEDOUT;
478 	}
479 
480 	return 0;
481 }
482 
net_config_init(const char * app_info,uint32_t flags,int32_t timeout)483 int net_config_init(const char *app_info, uint32_t flags,
484 		    int32_t timeout)
485 {
486 	return net_config_init_by_iface(NULL, app_info, flags, timeout);
487 }
488 
iface_find_cb(struct net_if * iface,void * user_data)489 static void iface_find_cb(struct net_if *iface, void *user_data)
490 {
491 	struct net_if **iface_to_use = user_data;
492 
493 	if (*iface_to_use == NULL &&
494 	    !net_if_flag_is_set(iface, NET_IF_NO_AUTO_START)) {
495 		*iface_to_use = iface;
496 		return;
497 	}
498 }
499 
net_config_init_app(const struct device * dev,const char * app_info)500 int net_config_init_app(const struct device *dev, const char *app_info)
501 {
502 	struct net_if *iface = NULL;
503 	uint32_t flags = 0U;
504 	int ret;
505 
506 	if (dev) {
507 		iface = net_if_lookup_by_dev(dev);
508 		if (iface == NULL) {
509 			NET_WARN("No interface for device %p, using default",
510 				 dev);
511 		}
512 	}
513 
514 	ret = z_net_config_ieee802154_setup(iface);
515 	if (ret < 0) {
516 		NET_ERR("Cannot setup IEEE 802.15.4 interface (%d)", ret);
517 	}
518 
519 	/* Only try to use a network interface that is auto started */
520 	if (iface == NULL) {
521 		net_if_foreach(iface_find_cb, &iface);
522 	}
523 
524 	if (!iface) {
525 		NET_WARN("No auto-started network interface - "
526 			 "network-bound app initialization skipped.");
527 		return 0;
528 	}
529 
530 	if (IS_ENABLED(CONFIG_NET_CONFIG_NEED_IPV6)) {
531 		flags |= NET_CONFIG_NEED_IPV6;
532 	}
533 
534 	if (IS_ENABLED(CONFIG_NET_CONFIG_NEED_IPV6_ROUTER)) {
535 		flags |= NET_CONFIG_NEED_ROUTER;
536 	}
537 
538 	if (IS_ENABLED(CONFIG_NET_CONFIG_NEED_IPV4)) {
539 		flags |= NET_CONFIG_NEED_IPV4;
540 	}
541 
542 	/* Initialize the application automatically if needed */
543 	ret = net_config_init_by_iface(iface, app_info, flags,
544 				CONFIG_NET_CONFIG_INIT_TIMEOUT * MSEC_PER_SEC);
545 	if (ret < 0) {
546 		NET_ERR("Network initialization failed (%d)", ret);
547 	}
548 
549 	if (IS_ENABLED(CONFIG_NET_CONFIG_CLOCK_SNTP_INIT)) {
550 		net_init_clock_via_sntp();
551 	}
552 
553 	/* This is activated late as it requires the network stack to be up
554 	 * and running before syslog messages can be sent to network.
555 	 */
556 	if (IS_ENABLED(CONFIG_LOG_BACKEND_NET) &&
557 	    IS_ENABLED(CONFIG_LOG_BACKEND_NET_AUTOSTART)) {
558 		const struct log_backend *backend = log_backend_net_get();
559 
560 		if (!log_backend_is_active(backend)) {
561 			if (backend->api->init != NULL) {
562 				backend->api->init(backend);
563 			}
564 
565 			log_backend_activate(backend, NULL);
566 		}
567 	}
568 
569 	return ret;
570 }
571 
572 #if defined(CONFIG_NET_CONFIG_AUTO_INIT)
init_app(void)573 static int init_app(void)
574 {
575 
576 	(void)net_config_init_app(NULL, "Initializing network");
577 
578 	return 0;
579 }
580 
581 SYS_INIT(init_app, APPLICATION, CONFIG_NET_CONFIG_INIT_PRIO);
582 #endif /* CONFIG_NET_CONFIG_AUTO_INIT */
583