1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Public API for network interface
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_NET_NET_IF_H_
13 #define ZEPHYR_INCLUDE_NET_NET_IF_H_
14 
15 /**
16  * @brief Network Interface abstraction layer
17  * @defgroup net_if Network Interface abstraction layer
18  * @since 1.5
19  * @version 1.0.0
20  * @ingroup networking
21  * @{
22  */
23 
24 #include <zephyr/device.h>
25 #include <zephyr/sys/slist.h>
26 #include <zephyr/sys/iterable_sections.h>
27 #include <zephyr/net/net_core.h>
28 #include <zephyr/net/hostname.h>
29 #include <zephyr/net/net_linkaddr.h>
30 #include <zephyr/net/net_ip.h>
31 #include <zephyr/net/net_l2.h>
32 #include <zephyr/net/net_stats.h>
33 #include <zephyr/net/net_timeout.h>
34 
35 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
36 #include <zephyr/net/dhcpv4.h>
37 #endif
38 #if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6)
39 #include <zephyr/net/dhcpv6.h>
40 #endif
41 #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
42 #include <zephyr/net/ipv4_autoconf.h>
43 #endif
44 
45 #include <zephyr/net/prometheus/collector.h>
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51 /**
52  * @brief Network Interface unicast IP addresses
53  *
54  * Stores the unicast IP addresses assigned to this network interface.
55  */
56 struct net_if_addr {
57 	/** IP address */
58 	struct net_addr address;
59 
60 	/** Reference counter. This is used to prevent address removal if there
61 	 * are sockets that have bound the local endpoint to this address.
62 	 */
63 	atomic_t atomic_ref;
64 
65 #if defined(CONFIG_NET_NATIVE_IPV6)
66 	struct net_timeout lifetime;
67 #endif
68 
69 	/** How the IP address was set */
70 	enum net_addr_type addr_type;
71 
72 	/** What is the current state of the address */
73 	enum net_addr_state addr_state;
74 
75 #if defined(CONFIG_NET_NATIVE_IPV6)
76 #if defined(CONFIG_NET_IPV6_PE)
77 	/** Address creation time. This is used to determine if the maximum
78 	 * lifetime for this address is reached or not. The value is in seconds.
79 	 */
80 	uint32_t addr_create_time;
81 
82 	/** Preferred lifetime for the address in seconds.
83 	 */
84 	uint32_t addr_preferred_lifetime;
85 
86 	/** Address timeout value. This is only used if DAD needs to be redone
87 	 * for this address because of earlier DAD failure. This value is in
88 	 * seconds.
89 	 */
90 	int32_t addr_timeout;
91 #endif
92 #endif /* CONFIG_NET_NATIVE_IPV6 */
93 
94 	union {
95 #if defined(CONFIG_NET_IPV6_DAD)
96 		struct {
97 			/** Duplicate address detection (DAD) timer */
98 			sys_snode_t dad_node;
99 
100 			/** DAD needed list node */
101 			sys_snode_t dad_need_node;
102 
103 			/** DAD start time */
104 			uint32_t dad_start;
105 
106 			/** How many times we have done DAD */
107 			uint8_t dad_count;
108 		};
109 #endif /* CONFIG_NET_IPV6_DAD */
110 #if defined(CONFIG_NET_IPV4_ACD)
111 		struct {
112 			/** Address conflict detection (ACD) timer. */
113 			sys_snode_t acd_node;
114 
115 			/** ACD needed list node */
116 			sys_snode_t acd_need_node;
117 
118 			/** ACD timeout value. */
119 			k_timepoint_t acd_timeout;
120 
121 			/** ACD probe/announcement counter. */
122 			uint8_t acd_count;
123 
124 			/** ACD status. */
125 			uint8_t acd_state;
126 		};
127 #endif /* CONFIG_NET_IPV4_ACD */
128 		uint8_t _dummy;
129 	};
130 
131 #if defined(CONFIG_NET_IPV6_DAD) || defined(CONFIG_NET_IPV4_ACD)
132 	/** What interface the conflict detection is running */
133 	uint8_t ifindex;
134 #endif
135 
136 	/** Is the IP address valid forever */
137 	uint8_t is_infinite : 1;
138 
139 	/** Is this IP address used or not */
140 	uint8_t is_used : 1;
141 
142 	/** Is this IP address usage limited to the subnet (mesh) or not */
143 	uint8_t is_mesh_local : 1;
144 
145 	/** Is this IP address temporary and generated for example by
146 	 * IPv6 privacy extension (RFC 8981)
147 	 */
148 	uint8_t is_temporary : 1;
149 
150 	/** Was this address added or not */
151 	uint8_t is_added : 1;
152 
153 	uint8_t _unused : 3;
154 };
155 
156 /**
157  * @brief Network Interface multicast IP addresses
158  *
159  * Stores the multicast IP addresses assigned to this network interface.
160  */
161 struct net_if_mcast_addr {
162 	/** IP address */
163 	struct net_addr address;
164 
165 	/** Rejoining multicast groups list node */
166 	sys_snode_t rejoin_node;
167 
168 #if defined(CONFIG_NET_IPV4_IGMPV3)
169 	/** Sources to filter on */
170 	struct net_addr sources[CONFIG_NET_IF_MCAST_IPV4_SOURCE_COUNT];
171 
172 	/** Number of sources to be used by the filter */
173 	uint16_t sources_len;
174 
175 	/** Filter mode (used in IGMPV3) */
176 	uint8_t record_type;
177 #endif
178 
179 	/** Is this multicast IP address used or not */
180 	uint8_t is_used : 1;
181 
182 	/** Did we join to this group */
183 	uint8_t is_joined : 1;
184 
185 	uint8_t _unused : 6;
186 };
187 
188 /**
189  * @brief Network Interface IPv6 prefixes
190  *
191  * Stores the IPV6 prefixes assigned to this network interface.
192  */
193 struct net_if_ipv6_prefix {
194 	/** Prefix lifetime */
195 	struct net_timeout lifetime;
196 
197 	/** IPv6 prefix */
198 	struct net_in6_addr prefix;
199 
200 	/** Backpointer to network interface where this prefix is used */
201 	struct net_if *iface;
202 
203 	/** Prefix length */
204 	uint8_t len;
205 
206 	/** Is the IP prefix valid forever */
207 	uint8_t is_infinite : 1;
208 
209 	/** Is this prefix used or not */
210 	uint8_t is_used : 1;
211 
212 	uint8_t _unused : 6;
213 };
214 
215 /**
216  * @brief Information about routers in the system.
217  *
218  * Stores the router information.
219  */
220 struct net_if_router {
221 	/** Slist lifetime timer node */
222 	sys_snode_t node;
223 
224 	/** IP address */
225 	struct net_addr address;
226 
227 	/** Network interface the router is connected to */
228 	struct net_if *iface;
229 
230 	/** Router life timer start */
231 	uint32_t life_start;
232 
233 	/** Router lifetime */
234 	uint16_t lifetime;
235 
236 	/** Is this router used or not */
237 	uint8_t is_used : 1;
238 
239 	/** Is default router */
240 	uint8_t is_default : 1;
241 
242 	/** Is the router valid forever */
243 	uint8_t is_infinite : 1;
244 
245 	uint8_t _unused : 5;
246 };
247 
248 /** Network interface flags. */
249 enum net_if_flag {
250 	/** Interface is admin up. */
251 	NET_IF_UP,
252 
253 	/** Interface is pointopoint */
254 	NET_IF_POINTOPOINT,
255 
256 	/** Interface is in promiscuous mode */
257 	NET_IF_PROMISC,
258 
259 	/** Do not start the interface immediately after initialization.
260 	 * This requires that either the device driver or some other entity
261 	 * will need to manually take the interface up when needed.
262 	 * For example for Ethernet this will happen when the driver calls
263 	 * the net_eth_carrier_on() function.
264 	 */
265 	NET_IF_NO_AUTO_START,
266 
267 	/** Power management specific: interface is being suspended */
268 	NET_IF_SUSPENDED,
269 
270 	/** Flag defines if received multicasts of other interface are
271 	 * forwarded on this interface. This activates multicast
272 	 * routing / forwarding for this interface.
273 	 */
274 	NET_IF_FORWARD_MULTICASTS,
275 
276 	/** Interface supports IPv4 */
277 	NET_IF_IPV4,
278 
279 	/** Interface supports IPv6 */
280 	NET_IF_IPV6,
281 
282 	/** Interface up and running (ready to receive and transmit). */
283 	NET_IF_RUNNING,
284 
285 	/** Driver signals L1 is up. */
286 	NET_IF_LOWER_UP,
287 
288 	/** Driver signals dormant. */
289 	NET_IF_DORMANT,
290 
291 	/** IPv6 Neighbor Discovery disabled. */
292 	NET_IF_IPV6_NO_ND,
293 
294 	/** IPv6 Multicast Listener Discovery disabled. */
295 	NET_IF_IPV6_NO_MLD,
296 
297 	/** Mutex locking on TX data path disabled on the interface. */
298 	NET_IF_NO_TX_LOCK,
299 
300 /** @cond INTERNAL_HIDDEN */
301 	/* Total number of flags - must be at the end of the enum */
302 	NET_IF_NUM_FLAGS
303 /** @endcond */
304 };
305 
306 /** @brief Network interface operational status (RFC 2863). */
307 enum net_if_oper_state {
308 	NET_IF_OPER_UNKNOWN,        /**< Initial (unknown) value */
309 	NET_IF_OPER_NOTPRESENT,     /**< Hardware missing */
310 	NET_IF_OPER_DOWN,           /**< Interface is down */
311 	NET_IF_OPER_LOWERLAYERDOWN, /**< Lower layer interface is down */
312 	NET_IF_OPER_TESTING,        /**< Training mode */
313 	NET_IF_OPER_DORMANT,        /**< Waiting external action */
314 	NET_IF_OPER_UP,             /**< Interface is up */
315 } __packed;
316 
317 #if defined(CONFIG_NET_OFFLOAD)
318 struct net_offload;
319 #endif /* CONFIG_NET_OFFLOAD */
320 
321 /** @cond INTERNAL_HIDDEN */
322 #if defined(CONFIG_NET_IPV6)
323 #define NET_IF_MAX_IPV6_ADDR CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT
324 #define NET_IF_MAX_IPV6_MADDR CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT
325 #define NET_IF_MAX_IPV6_PREFIX CONFIG_NET_IF_IPV6_PREFIX_COUNT
326 #else
327 #define NET_IF_MAX_IPV6_ADDR 0
328 #define NET_IF_MAX_IPV6_MADDR 0
329 #define NET_IF_MAX_IPV6_PREFIX 0
330 #endif
331 /* @endcond */
332 
333 /** IPv6 configuration */
334 struct net_if_ipv6 {
335 	/** Unicast IP addresses */
336 	struct net_if_addr unicast[NET_IF_MAX_IPV6_ADDR];
337 
338 	/** Multicast IP addresses */
339 	struct net_if_mcast_addr mcast[NET_IF_MAX_IPV6_MADDR];
340 
341 	/** Prefixes */
342 	struct net_if_ipv6_prefix prefix[NET_IF_MAX_IPV6_PREFIX];
343 
344 	/** Default reachable time (RFC 4861, page 52) */
345 	uint32_t base_reachable_time;
346 
347 	/** Reachable time (RFC 4861, page 20) */
348 	uint32_t reachable_time;
349 
350 	/** Retransmit timer (RFC 4861, page 52) */
351 	uint32_t retrans_timer;
352 
353 #if defined(CONFIG_NET_IPV6_IID_STABLE)
354 	/** IID (Interface Identifier) pointer used for link local address */
355 	struct net_if_addr *iid;
356 
357 	/** Incremented when network interface goes down so that we can
358 	 * generate new stable addresses when interface comes back up.
359 	 */
360 	uint32_t network_counter;
361 #endif /* CONFIG_NET_IPV6_IID_STABLE */
362 
363 #if defined(CONFIG_NET_IPV6_PE)
364 	/** Privacy extension DESYNC_FACTOR value from RFC 8981 ch 3.4.
365 	 * "DESYNC_FACTOR is a random value within the range 0 - MAX_DESYNC_FACTOR.
366 	 * It is computed every time a temporary address is created.
367 	 */
368 	uint32_t desync_factor;
369 #endif /* CONFIG_NET_IPV6_PE */
370 
371 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
372 	/** Router solicitation timer node */
373 	sys_snode_t rs_node;
374 
375 	/* RS start time */
376 	uint32_t rs_start;
377 
378 	/** RS count */
379 	uint8_t rs_count;
380 #endif
381 
382 	/** IPv6 hop limit */
383 	uint8_t hop_limit;
384 
385 	/** IPv6 multicast hop limit */
386 	uint8_t mcast_hop_limit;
387 };
388 
389 #if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6)
390 /** DHCPv6 configuration */
391 struct net_if_dhcpv6 {
392 	/** Used for timer list. */
393 	sys_snode_t node;
394 
395 	/** Generated Client ID. */
396 	struct net_dhcpv6_duid_storage clientid;
397 
398 	/** Server ID of the selected server. */
399 	struct net_dhcpv6_duid_storage serverid;
400 
401 	/** DHCPv6 client state. */
402 	enum net_dhcpv6_state state;
403 
404 	/** DHCPv6 client configuration parameters. */
405 	struct net_dhcpv6_params params;
406 
407 	/** Timeout for the next event, absolute time, milliseconds. */
408 	uint64_t timeout;
409 
410 	/** Time of the current exchange start, absolute time, milliseconds */
411 	uint64_t exchange_start;
412 
413 	/** Renewal time, absolute time, milliseconds. */
414 	uint64_t t1;
415 
416 	/** Rebinding time, absolute time, milliseconds. */
417 	uint64_t t2;
418 
419 	/** The time when the last lease expires (terminates rebinding,
420 	 *  DHCPv6 RFC8415, ch. 18.2.5). Absolute time, milliseconds.
421 	 */
422 	uint64_t expire;
423 
424 	/** Generated IAID for IA_NA. */
425 	uint32_t addr_iaid;
426 
427 	/** Generated IAID for IA_PD. */
428 	uint32_t prefix_iaid;
429 
430 	/** Retransmit timeout for the current message, milliseconds. */
431 	uint32_t retransmit_timeout;
432 
433 	/** Current best server preference received. */
434 	int16_t server_preference;
435 
436 	/** Retransmission counter. */
437 	uint8_t retransmissions;
438 
439 	/** Transaction ID for current exchange. */
440 	uint8_t tid[DHCPV6_TID_SIZE];
441 
442 	/** Prefix length. */
443 	uint8_t prefix_len;
444 
445 	/** Assigned IPv6 prefix. */
446 	struct net_in6_addr prefix;
447 
448 	/** Assigned IPv6 address. */
449 	struct net_in6_addr addr;
450 };
451 #endif /* defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6) */
452 
453 /** @cond INTERNAL_HIDDEN */
454 #if defined(CONFIG_NET_IPV4)
455 #define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT
456 #define NET_IF_MAX_IPV4_MADDR CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT
457 #else
458 #define NET_IF_MAX_IPV4_ADDR 0
459 #define NET_IF_MAX_IPV4_MADDR 0
460 #endif
461 /** @endcond */
462 
463 /**
464  * @brief Network Interface unicast IPv4 address and netmask
465  *
466  * Stores the unicast IPv4 address and related netmask.
467  */
468 struct net_if_addr_ipv4 {
469 	/** IPv4 address */
470 	struct net_if_addr ipv4;
471 	/** Netmask */
472 	struct net_in_addr netmask;
473 };
474 
475 /** IPv4 configuration */
476 struct net_if_ipv4 {
477 	/** Unicast IP addresses */
478 	struct net_if_addr_ipv4 unicast[NET_IF_MAX_IPV4_ADDR];
479 
480 	/** Multicast IP addresses */
481 	struct net_if_mcast_addr mcast[NET_IF_MAX_IPV4_MADDR];
482 
483 	/** Gateway */
484 	struct net_in_addr gw;
485 
486 	/** IPv4 time-to-live */
487 	uint8_t ttl;
488 
489 	/** IPv4 time-to-live for multicast packets */
490 	uint8_t mcast_ttl;
491 
492 #if defined(CONFIG_NET_IPV4_ACD)
493 	/** IPv4 conflict count.  */
494 	uint8_t conflict_cnt;
495 #endif
496 };
497 
498 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
499 struct net_if_dhcpv4 {
500 	/** Used for timer lists */
501 	sys_snode_t node;
502 
503 	/** Timer start */
504 	int64_t timer_start;
505 
506 	/** Time for INIT, INIT-REBOOT, DISCOVER, REQUESTING, RENEWAL */
507 	uint32_t request_time;
508 
509 	uint32_t xid;
510 
511 	/** IP address Lease time */
512 	uint32_t lease_time;
513 
514 	/** IP address Renewal time */
515 	uint32_t renewal_time;
516 
517 	/** IP address Rebinding time */
518 	uint32_t rebinding_time;
519 
520 	/** Server ID */
521 	struct net_in_addr server_id;
522 
523 	/** Requested IP addr */
524 	struct net_in_addr requested_ip;
525 
526 	/** Received netmask from the server */
527 	struct net_in_addr netmask;
528 
529 	/**
530 	 *  DHCPv4 client state in the process of network
531 	 *  address allocation.
532 	 */
533 	enum net_dhcpv4_state state;
534 
535 	/** Number of attempts made for REQUEST and RENEWAL messages */
536 	uint8_t attempts;
537 
538 	/** The address of the server the request is sent to */
539 	struct net_in_addr request_server_addr;
540 
541 	/** The source address of a received DHCP message */
542 	struct net_in_addr response_src_addr;
543 
544 #ifdef CONFIG_NET_DHCPV4_OPTION_NTP_SERVER
545 	/** NTP server address */
546 	struct net_in_addr ntp_addr;
547 #endif
548 };
549 #endif /* CONFIG_NET_DHCPV4 */
550 
551 #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
552 struct net_if_ipv4_autoconf {
553 	/** Backpointer to correct network interface */
554 	struct net_if *iface;
555 
556 	/** Requested IP addr */
557 	struct net_in_addr requested_ip;
558 
559 	/** IPV4 Autoconf state in the process of network address allocation.
560 	 */
561 	enum net_ipv4_autoconf_state state;
562 };
563 #endif /* CONFIG_NET_IPV4_AUTO */
564 
565 /** @cond INTERNAL_HIDDEN */
566 /* We always need to have at least one IP config */
567 #define NET_IF_MAX_CONFIGS 1
568 /** @endcond */
569 
570 /**
571  * @brief Network interface IP address configuration.
572  */
573 struct net_if_ip {
574 #if defined(CONFIG_NET_IPV6)
575 	struct net_if_ipv6 *ipv6;
576 #endif /* CONFIG_NET_IPV6 */
577 
578 #if defined(CONFIG_NET_IPV4)
579 	struct net_if_ipv4 *ipv4;
580 #endif /* CONFIG_NET_IPV4 */
581 };
582 
583 /**
584  * @brief IP and other configuration related data for network interface.
585  */
586 struct net_if_config {
587 #if defined(CONFIG_NET_IP)
588 	/** IP address configuration setting */
589 	struct net_if_ip ip;
590 #endif
591 
592 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
593 	struct net_if_dhcpv4 dhcpv4;
594 #endif /* CONFIG_NET_DHCPV4 */
595 
596 #if defined(CONFIG_NET_DHCPV6) && defined(CONFIG_NET_NATIVE_IPV6)
597 	struct net_if_dhcpv6 dhcpv6;
598 #endif /* CONFIG_NET_DHCPV6 */
599 
600 #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
601 	struct net_if_ipv4_autoconf ipv4auto;
602 #endif /* CONFIG_NET_IPV4_AUTO */
603 
604 #if defined(CONFIG_NET_L2_VIRTUAL)
605 	/**
606 	 * This list keeps track of the virtual network interfaces
607 	 * that are attached to this network interface.
608 	 */
609 	sys_slist_t virtual_interfaces;
610 #endif /* CONFIG_NET_L2_VIRTUAL */
611 
612 #if defined(CONFIG_NET_INTERFACE_NAME)
613 	/**
614 	 * Network interface can have a name and it is possible
615 	 * to search a network interface using this name.
616 	 */
617 	char name[CONFIG_NET_INTERFACE_NAME_LEN + 1];
618 #endif
619 };
620 
621 /**
622  * @brief Network traffic class.
623  *
624  * Traffic classes are used when sending or receiving data that is classified
625  * with different priorities. So some traffic can be marked as high priority
626  * and it will be sent or received first. Each network packet that is
627  * transmitted or received goes through a fifo to a thread that will transmit
628  * it.
629  */
630 struct net_traffic_class {
631 	/** Fifo for handling this Tx or Rx packet */
632 	struct k_fifo fifo;
633 
634 #if NET_TC_COUNT > 1 || defined(CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO) \
635 	|| defined(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO)
636 	/** Semaphore for tracking the available slots in the fifo */
637 	struct k_sem fifo_slot;
638 #endif
639 
640 	/** Traffic class handler thread */
641 	struct k_thread handler;
642 
643 	/** Stack for this handler */
644 	k_thread_stack_t *stack;
645 };
646 
647 /**
648  * @typedef net_socket_create_t
649 
650  * @brief A function prototype to create an offloaded socket. The prototype is
651  *        compatible with socket() function.
652  */
653 typedef int (*net_socket_create_t)(int, int, int);
654 
655 /**
656  * @brief Network Interface Device structure
657  *
658  * Used to handle a network interface on top of a device driver instance.
659  * There can be many net_if_dev instance against the same device.
660  *
661  * Such interface is mainly to be used by the link layer, but is also tight
662  * to a network context: it then makes the relation with a network context
663  * and the network device.
664  *
665  * Because of the strong relationship between a device driver and such
666  * network interface, each net_if_dev should be instantiated by one of the
667  * network device init macros found in net_if.h.
668  */
669 struct net_if_dev {
670 	/** The actually device driver instance the net_if is related to */
671 	const struct device *dev;
672 
673 	/** Interface's L2 layer */
674 	const struct net_l2 * const l2;
675 
676 	/** Interface's private L2 data pointer */
677 	void *l2_data;
678 
679 	/** For internal use */
680 	ATOMIC_DEFINE(flags, NET_IF_NUM_FLAGS);
681 
682 	/** The hardware link address */
683 	struct net_linkaddr link_addr;
684 
685 #if defined(CONFIG_NET_OFFLOAD)
686 	/** TCP/IP Offload functions.
687 	 * If non-NULL, then the TCP/IP stack is located
688 	 * in the communication chip that is accessed via this
689 	 * network interface.
690 	 */
691 	struct net_offload *offload;
692 #endif /* CONFIG_NET_OFFLOAD */
693 
694 	/** The hardware MTU */
695 	uint16_t mtu;
696 
697 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
698 	/** A function pointer to create an offloaded socket.
699 	 *  If non-NULL, the interface is considered offloaded at socket level.
700 	 */
701 	net_socket_create_t socket_offload;
702 #endif /* CONFIG_NET_SOCKETS_OFFLOAD */
703 
704 	/** RFC 2863 operational status */
705 	enum net_if_oper_state oper_state;
706 
707 	/** Last time the operational state was changed.
708 	 * This is used to determine how long the interface has been in the
709 	 * current operational state.
710 	 *
711 	 * This value is set to 0 when the interface is created, and then
712 	 * updated whenever the operational state changes.
713 	 *
714 	 * The value is in milliseconds since boot.
715 	 */
716 	int64_t oper_state_change_time;
717 };
718 
719 /**
720  * @brief Network Interface structure
721  *
722  * Used to handle a network interface on top of a net_if_dev instance.
723  * There can be many net_if instance against the same net_if_dev instance.
724  *
725  */
726 struct net_if {
727 	/** The net_if_dev instance the net_if is related to */
728 	struct net_if_dev *if_dev;
729 
730 #if defined(CONFIG_NET_STATISTICS_PER_INTERFACE)
731 	/** Network statistics related to this network interface */
732 	struct net_stats stats;
733 
734 	/** Promethus collector for this network interface */
735 	IF_ENABLED(CONFIG_NET_STATISTICS_VIA_PROMETHEUS,
736 		   (struct prometheus_collector *collector);)
737 #endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */
738 
739 	/** Network interface instance configuration */
740 	struct net_if_config config;
741 
742 #if defined(CONFIG_NET_POWER_MANAGEMENT)
743 	/** Keep track of packets pending in traffic queues. This is
744 	 * needed to avoid putting network device driver to sleep if
745 	 * there are packets waiting to be sent.
746 	 */
747 	int tx_pending;
748 #endif
749 
750 	/** Mutex protecting this network interface instance */
751 	struct k_mutex lock;
752 
753 	/** Mutex used when sending data */
754 	struct k_mutex tx_lock;
755 
756 	/** Network interface specific flags */
757 	/** Enable IPv6 privacy extension (RFC 8981), this is enabled
758 	 * by default if PE support is enabled in configuration.
759 	 */
760 	uint8_t pe_enabled : 1;
761 
762 	/** If PE is enabled, then this tells whether public addresses
763 	 * are preferred over temporary ones for this interface.
764 	 */
765 	uint8_t pe_prefer_public : 1;
766 
767 	/** Unused bit flags (ignore) */
768 	uint8_t _unused : 6;
769 };
770 
771 /** @cond INTERNAL_HIDDEN */
772 
net_if_lock(struct net_if * iface)773 static inline void net_if_lock(struct net_if *iface)
774 {
775 	NET_ASSERT(iface);
776 
777 	(void)k_mutex_lock(&iface->lock, K_FOREVER);
778 }
779 
net_if_unlock(struct net_if * iface)780 static inline void net_if_unlock(struct net_if *iface)
781 {
782 	NET_ASSERT(iface);
783 
784 	k_mutex_unlock(&iface->lock);
785 }
786 
787 static inline bool net_if_flag_is_set(struct net_if *iface,
788 				      enum net_if_flag value);
789 
net_if_tx_lock(struct net_if * iface)790 static inline void net_if_tx_lock(struct net_if *iface)
791 {
792 	NET_ASSERT(iface);
793 
794 	if (net_if_flag_is_set(iface, NET_IF_NO_TX_LOCK)) {
795 		return;
796 	}
797 
798 	(void)k_mutex_lock(&iface->tx_lock, K_FOREVER);
799 }
800 
net_if_tx_unlock(struct net_if * iface)801 static inline void net_if_tx_unlock(struct net_if *iface)
802 {
803 	NET_ASSERT(iface);
804 
805 	if (net_if_flag_is_set(iface, NET_IF_NO_TX_LOCK)) {
806 		return;
807 	}
808 
809 	k_mutex_unlock(&iface->tx_lock);
810 }
811 
812 /** @endcond */
813 
814 /**
815  * @brief Set a value in network interface flags
816  *
817  * @param iface Pointer to network interface
818  * @param value Flag value
819  */
net_if_flag_set(struct net_if * iface,enum net_if_flag value)820 static inline void net_if_flag_set(struct net_if *iface,
821 				   enum net_if_flag value)
822 {
823 	if (iface == NULL || iface->if_dev == NULL) {
824 		return;
825 	}
826 
827 	atomic_set_bit(iface->if_dev->flags, value);
828 }
829 
830 /**
831  * @brief Test and set a value in network interface flags
832  *
833  * @param iface Pointer to network interface
834  * @param value Flag value
835  *
836  * @return true if the bit was set, false if it wasn't.
837  */
net_if_flag_test_and_set(struct net_if * iface,enum net_if_flag value)838 static inline bool net_if_flag_test_and_set(struct net_if *iface,
839 					    enum net_if_flag value)
840 {
841 	if (iface == NULL || iface->if_dev == NULL) {
842 		return false;
843 	}
844 
845 	return atomic_test_and_set_bit(iface->if_dev->flags, value);
846 }
847 
848 /**
849  * @brief Clear a value in network interface flags
850  *
851  * @param iface Pointer to network interface
852  * @param value Flag value
853  */
net_if_flag_clear(struct net_if * iface,enum net_if_flag value)854 static inline void net_if_flag_clear(struct net_if *iface,
855 				     enum net_if_flag value)
856 {
857 	if (iface == NULL || iface->if_dev == NULL) {
858 		return;
859 	}
860 
861 	atomic_clear_bit(iface->if_dev->flags, value);
862 }
863 
864 /**
865  * @brief Test and clear a value in network interface flags
866  *
867  * @param iface Pointer to network interface
868  * @param value Flag value
869  *
870  * @return true if the bit was set, false if it wasn't.
871  */
net_if_flag_test_and_clear(struct net_if * iface,enum net_if_flag value)872 static inline bool net_if_flag_test_and_clear(struct net_if *iface,
873 					      enum net_if_flag value)
874 {
875 	if (iface == NULL || iface->if_dev == NULL) {
876 		return false;
877 	}
878 
879 	return atomic_test_and_clear_bit(iface->if_dev->flags, value);
880 }
881 
882 /**
883  * @brief Check if a value in network interface flags is set
884  *
885  * @param iface Pointer to network interface
886  * @param value Flag value
887  *
888  * @return True if the value is set, false otherwise
889  */
net_if_flag_is_set(struct net_if * iface,enum net_if_flag value)890 static inline bool net_if_flag_is_set(struct net_if *iface,
891 				      enum net_if_flag value)
892 {
893 	if (iface == NULL || iface->if_dev == NULL) {
894 		return false;
895 	}
896 
897 	return atomic_test_bit(iface->if_dev->flags, value);
898 }
899 
900 /**
901  * @brief Set an operational state on an interface
902  *
903  * @param iface Pointer to network interface
904  * @param oper_state Operational state to set
905  *
906  * @return The new operational state of an interface
907  */
net_if_oper_state_set(struct net_if * iface,enum net_if_oper_state oper_state)908 static inline enum net_if_oper_state net_if_oper_state_set(
909 	struct net_if *iface, enum net_if_oper_state oper_state)
910 {
911 	if (iface == NULL || iface->if_dev == NULL) {
912 		return NET_IF_OPER_UNKNOWN;
913 	}
914 
915 	if (oper_state <= NET_IF_OPER_UP) {
916 		iface->if_dev->oper_state = oper_state;
917 	}
918 
919 	net_if_lock(iface);
920 
921 	iface->if_dev->oper_state_change_time = k_uptime_get();
922 
923 	net_if_unlock(iface);
924 
925 	return iface->if_dev->oper_state;
926 }
927 
928 /**
929  * @brief Get an operational state of an interface
930  *
931  * @param iface Pointer to network interface
932  *
933  * @return Operational state of an interface
934  */
net_if_oper_state(struct net_if * iface)935 static inline enum net_if_oper_state net_if_oper_state(struct net_if *iface)
936 {
937 	if (iface == NULL || iface->if_dev == NULL) {
938 		return NET_IF_OPER_UNKNOWN;
939 	}
940 
941 	return iface->if_dev->oper_state;
942 }
943 
944 /**
945  * @brief Get an operational state change time of an interface
946  *
947  * @param iface Pointer to network interface
948  * @param change_time Pointer to store the change time. Time the operational
949  *        state of an interface was last changed, in milliseconds since boot.
950  *        If the interface operational state has not been changed yet,
951  *        then the value is 0.
952  *
953  * @return 0 if ok, -EINVAL if operational state change time could not be
954  *         retrieved (for example if iface or change_time is NULL).
955  */
net_if_oper_state_change_time(struct net_if * iface,int64_t * change_time)956 static inline int net_if_oper_state_change_time(struct net_if *iface,
957 						int64_t *change_time)
958 {
959 	if (iface == NULL || iface->if_dev == NULL || change_time == NULL) {
960 		return -EINVAL;
961 	}
962 
963 	net_if_lock(iface);
964 
965 	*change_time = iface->if_dev->oper_state_change_time;
966 
967 	net_if_unlock(iface);
968 
969 	return 0;
970 }
971 
972 /**
973  * @brief Try sending a packet through a net iface
974  *
975  * @param iface Pointer to a network interface structure
976  * @param pkt Pointer to a net packet to send
977  * @param timeout timeout for attempting to send
978  *
979  * @return verdict about the packet
980  */
981 enum net_verdict net_if_try_send_data(struct net_if *iface,
982 				      struct net_pkt *pkt, k_timeout_t timeout);
983 
984 /**
985  * @brief Send a packet through a net iface
986  *
987  * This is equivalent to net_if_try_queue_tx with an infinite timeout
988  * @param iface Pointer to a network interface structure
989  * @param pkt Pointer to a net packet to send
990  *
991  * @return verdict about the packet
992  */
net_if_send_data(struct net_if * iface,struct net_pkt * pkt)993 static inline enum net_verdict net_if_send_data(struct net_if *iface,
994 						struct net_pkt *pkt)
995 {
996 	k_timeout_t timeout = k_is_in_isr() ? K_NO_WAIT : K_FOREVER;
997 
998 	return net_if_try_send_data(iface, pkt, timeout);
999 }
1000 
1001 /**
1002  * @brief Get a pointer to the interface L2
1003  *
1004  * @param iface a valid pointer to a network interface structure
1005  *
1006  * @return a pointer to the iface L2
1007  */
net_if_l2(struct net_if * iface)1008 static inline const struct net_l2 *net_if_l2(struct net_if *iface)
1009 {
1010 	if (iface == NULL || iface->if_dev == NULL) {
1011 		return NULL;
1012 	}
1013 
1014 	return iface->if_dev->l2;
1015 }
1016 
1017 /**
1018  * @brief Input a packet through a net iface
1019  *
1020  * @param iface Pointer to a network interface structure
1021  * @param pkt Pointer to a net packet to input
1022  *
1023  * @return verdict about the packet
1024  */
1025 enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt);
1026 
1027 /**
1028  * @brief Get a pointer to the interface L2 private data
1029  *
1030  * @param iface a valid pointer to a network interface structure
1031  *
1032  * @return a pointer to the iface L2 data
1033  */
net_if_l2_data(struct net_if * iface)1034 static inline void *net_if_l2_data(struct net_if *iface)
1035 {
1036 	if (iface == NULL || iface->if_dev == NULL) {
1037 		return NULL;
1038 	}
1039 
1040 	return iface->if_dev->l2_data;
1041 }
1042 
1043 /**
1044  * @brief Get an network interface's device
1045  *
1046  * @param iface Pointer to a network interface structure
1047  *
1048  * @return a pointer to the device driver instance
1049  */
net_if_get_device(struct net_if * iface)1050 static inline const struct device *net_if_get_device(struct net_if *iface)
1051 {
1052 	if (iface == NULL || iface->if_dev == NULL) {
1053 		return NULL;
1054 	}
1055 
1056 	return iface->if_dev->dev;
1057 }
1058 
1059 /**
1060  * @brief Try enqueuing a packet to the net interface TX queue
1061  *
1062  * @param iface Pointer to a network interface structure
1063  * @param pkt Pointer to a net packet to queue
1064  * @param timeout Timeout for the enqueuing attempt
1065  */
1066 void net_if_try_queue_tx(struct net_if *iface, struct net_pkt *pkt, k_timeout_t timeout);
1067 
1068 /**
1069  * @brief Queue a packet to the net interface TX queue
1070  *
1071  * This is equivalent to net_if_try_queue_tx with an infinite timeout
1072  * @param iface Pointer to a network interface structure
1073  * @param pkt Pointer to a net packet to queue
1074  */
net_if_queue_tx(struct net_if * iface,struct net_pkt * pkt)1075 static inline void net_if_queue_tx(struct net_if *iface, struct net_pkt *pkt)
1076 {
1077 	k_timeout_t timeout = k_is_in_isr() ? K_NO_WAIT : K_FOREVER;
1078 
1079 	net_if_try_queue_tx(iface, pkt, timeout);
1080 }
1081 
1082 /**
1083  * @brief Return the IP offload status
1084  *
1085  * @param iface Network interface
1086  *
1087  * @return True if IP offloading is active, false otherwise.
1088  */
net_if_is_ip_offloaded(struct net_if * iface)1089 static inline bool net_if_is_ip_offloaded(struct net_if *iface)
1090 {
1091 #if defined(CONFIG_NET_OFFLOAD)
1092 	return (iface != NULL && iface->if_dev != NULL &&
1093 		iface->if_dev->offload != NULL);
1094 #else
1095 	ARG_UNUSED(iface);
1096 
1097 	return false;
1098 #endif
1099 }
1100 
1101 /**
1102  * @brief Return offload status of a given network interface.
1103  *
1104  * @param iface Network interface
1105  *
1106  * @return True if IP or socket offloading is active, false otherwise.
1107  */
1108 bool net_if_is_offloaded(struct net_if *iface);
1109 
1110 /**
1111  * @brief Return the IP offload plugin
1112  *
1113  * @param iface Network interface
1114  *
1115  * @return NULL if there is no offload plugin defined, valid pointer otherwise
1116  */
net_if_offload(struct net_if * iface)1117 static inline struct net_offload *net_if_offload(struct net_if *iface)
1118 {
1119 #if defined(CONFIG_NET_OFFLOAD)
1120 	if (iface == NULL || iface->if_dev == NULL) {
1121 		return NULL;
1122 	}
1123 
1124 	return iface->if_dev->offload;
1125 #else
1126 	ARG_UNUSED(iface);
1127 
1128 	return NULL;
1129 #endif
1130 }
1131 
1132 /**
1133  * @brief Return the socket offload status
1134  *
1135  * @param iface Network interface
1136  *
1137  * @return True if socket offloading is active, false otherwise.
1138  */
net_if_is_socket_offloaded(struct net_if * iface)1139 static inline bool net_if_is_socket_offloaded(struct net_if *iface)
1140 {
1141 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
1142 	if (iface == NULL || iface->if_dev == NULL) {
1143 		return false;
1144 	}
1145 
1146 	return (iface->if_dev->socket_offload != NULL);
1147 #else
1148 	ARG_UNUSED(iface);
1149 
1150 	return false;
1151 #endif
1152 }
1153 
1154 /**
1155  * @brief Set the function to create an offloaded socket
1156  *
1157  * @param iface Network interface
1158  * @param socket_offload A function to create an offloaded socket
1159  */
net_if_socket_offload_set(struct net_if * iface,net_socket_create_t socket_offload)1160 static inline void net_if_socket_offload_set(
1161 		struct net_if *iface, net_socket_create_t socket_offload)
1162 {
1163 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
1164 	if (iface == NULL || iface->if_dev == NULL) {
1165 		return;
1166 	}
1167 
1168 	iface->if_dev->socket_offload = socket_offload;
1169 #else
1170 	ARG_UNUSED(iface);
1171 	ARG_UNUSED(socket_offload);
1172 #endif
1173 }
1174 
1175 /**
1176  * @brief Return the function to create an offloaded socket
1177  *
1178  * @param iface Network interface
1179  *
1180  * @return NULL if the interface is not socket offloaded, valid pointer otherwise
1181  */
net_if_socket_offload(struct net_if * iface)1182 static inline net_socket_create_t net_if_socket_offload(struct net_if *iface)
1183 {
1184 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
1185 	if (iface == NULL || iface->if_dev == NULL) {
1186 		return NULL;
1187 	}
1188 
1189 	return iface->if_dev->socket_offload;
1190 #else
1191 	ARG_UNUSED(iface);
1192 
1193 	return NULL;
1194 #endif
1195 }
1196 
1197 /**
1198  * @brief Get an network interface's link address
1199  *
1200  * @param iface Pointer to a network interface structure
1201  *
1202  * @return a pointer to the network link address
1203  */
net_if_get_link_addr(struct net_if * iface)1204 static inline struct net_linkaddr *net_if_get_link_addr(struct net_if *iface)
1205 {
1206 	if (iface == NULL || iface->if_dev == NULL) {
1207 		return NULL;
1208 	}
1209 
1210 	return &iface->if_dev->link_addr;
1211 }
1212 
1213 /**
1214  * @brief Return network configuration for this network interface
1215  *
1216  * @param iface Pointer to a network interface structure
1217  *
1218  * @return Pointer to configuration
1219  */
net_if_get_config(struct net_if * iface)1220 static inline struct net_if_config *net_if_get_config(struct net_if *iface)
1221 {
1222 	if (iface == NULL) {
1223 		return NULL;
1224 	}
1225 
1226 	return &iface->config;
1227 }
1228 
1229 /**
1230  * @brief Start duplicate address detection procedure.
1231  *
1232  * @param iface Pointer to a network interface structure
1233  */
1234 #if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
1235 void net_if_start_dad(struct net_if *iface);
1236 #else
net_if_start_dad(struct net_if * iface)1237 static inline void net_if_start_dad(struct net_if *iface)
1238 {
1239 	ARG_UNUSED(iface);
1240 }
1241 #endif
1242 
1243 /**
1244  * @brief Start neighbor discovery and send router solicitation message.
1245  *
1246  * @param iface Pointer to a network interface structure
1247  */
1248 void net_if_start_rs(struct net_if *iface);
1249 
1250 
1251 /**
1252  * @brief Stop neighbor discovery.
1253  *
1254  * @param iface Pointer to a network interface structure
1255  */
1256 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
1257 void net_if_stop_rs(struct net_if *iface);
1258 #else
net_if_stop_rs(struct net_if * iface)1259 static inline void net_if_stop_rs(struct net_if *iface)
1260 {
1261 	ARG_UNUSED(iface);
1262 }
1263 #endif /* CONFIG_NET_IPV6_ND */
1264 
1265 /**
1266  * @brief Provide a reachability hint for IPv6 Neighbor Discovery.
1267  *
1268  * This function is intended for upper-layer protocols to inform the IPv6
1269  * Neighbor Discovery process about an active link to a specific neighbor.
1270  * By signaling a recent "forward progress" event, such as the reception of
1271  * an ACK, this function can help reduce unnecessary ND traffic as per the
1272  * guidelines in RFC 4861 (section 7.3).
1273  *
1274  * @param iface A pointer to the network interface.
1275  * @param ipv6_addr Pointer to the IPv6 address of the neighbor node.
1276  */
1277 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
1278 void net_if_nbr_reachability_hint(struct net_if *iface, const struct net_in6_addr *ipv6_addr);
1279 #else
net_if_nbr_reachability_hint(struct net_if * iface,const struct net_in6_addr * ipv6_addr)1280 static inline void net_if_nbr_reachability_hint(struct net_if *iface,
1281 						const struct net_in6_addr *ipv6_addr)
1282 {
1283 	ARG_UNUSED(iface);
1284 	ARG_UNUSED(ipv6_addr);
1285 }
1286 #endif
1287 
1288 /** @cond INTERNAL_HIDDEN */
1289 
net_if_set_link_addr_unlocked(struct net_if * iface,uint8_t * addr,uint8_t len,enum net_link_type type)1290 static inline int net_if_set_link_addr_unlocked(struct net_if *iface,
1291 						uint8_t *addr, uint8_t len,
1292 						enum net_link_type type)
1293 {
1294 	int ret;
1295 
1296 	if (net_if_flag_is_set(iface, NET_IF_RUNNING)) {
1297 		return -EPERM;
1298 	}
1299 
1300 	if (len > sizeof(net_if_get_link_addr(iface)->addr)) {
1301 		return -EINVAL;
1302 	}
1303 
1304 	ret = net_linkaddr_create(net_if_get_link_addr(iface), addr, len, type);
1305 	if (ret < 0) {
1306 		return ret;
1307 	}
1308 
1309 	net_hostname_set_postfix(addr, len);
1310 
1311 	return 0;
1312 }
1313 
1314 int net_if_set_link_addr_locked(struct net_if *iface,
1315 				uint8_t *addr, uint8_t len,
1316 				enum net_link_type type);
1317 
1318 #if CONFIG_NET_IF_LOG_LEVEL >= LOG_LEVEL_DBG
1319 extern int net_if_addr_unref_debug(struct net_if *iface,
1320 				   net_sa_family_t family,
1321 				   const void *addr,
1322 				   struct net_if_addr **ifaddr,
1323 				   const char *caller, int line);
1324 #define net_if_addr_unref(iface, family, addr, ifaddr)			\
1325 	net_if_addr_unref_debug(iface, family, addr, ifaddr, __func__, __LINE__)
1326 
1327 extern struct net_if_addr *net_if_addr_ref_debug(struct net_if *iface,
1328 						 net_sa_family_t family,
1329 						 const void *addr,
1330 						 const char *caller,
1331 						 int line);
1332 #define net_if_addr_ref(iface, family, addr) \
1333 	net_if_addr_ref_debug(iface, family, addr, __func__, __LINE__)
1334 #else
1335 extern int net_if_addr_unref(struct net_if *iface,
1336 			     net_sa_family_t family,
1337 			     const void *addr,
1338 			     struct net_if_addr **ifaddr);
1339 extern struct net_if_addr *net_if_addr_ref(struct net_if *iface,
1340 					   net_sa_family_t family,
1341 					   const void *addr);
1342 #endif /* CONFIG_NET_IF_LOG_LEVEL */
1343 
1344 /** @endcond */
1345 
1346 /**
1347  * @brief Set a network interface's link address
1348  *
1349  * @param iface Pointer to a network interface structure
1350  * @param addr A pointer to a uint8_t buffer representing the address.
1351  *             The buffer must remain valid throughout interface lifetime.
1352  * @param len length of the address buffer
1353  * @param type network bearer type of this link address
1354  *
1355  * @return 0 on success
1356  */
net_if_set_link_addr(struct net_if * iface,uint8_t * addr,uint8_t len,enum net_link_type type)1357 static inline int net_if_set_link_addr(struct net_if *iface,
1358 				       uint8_t *addr, uint8_t len,
1359 				       enum net_link_type type)
1360 {
1361 #if defined(CONFIG_NET_RAW_MODE)
1362 	return net_if_set_link_addr_unlocked(iface, addr, len, type);
1363 #else
1364 	return net_if_set_link_addr_locked(iface, addr, len, type);
1365 #endif
1366 }
1367 
1368 /**
1369  * @brief Get an network interface's MTU
1370  *
1371  * @param iface Pointer to a network interface structure
1372  *
1373  * @return the MTU
1374  */
net_if_get_mtu(struct net_if * iface)1375 static inline uint16_t net_if_get_mtu(struct net_if *iface)
1376 {
1377 	if (iface == NULL || iface->if_dev == NULL) {
1378 		return 0U;
1379 	}
1380 
1381 	return iface->if_dev->mtu;
1382 }
1383 
1384 /**
1385  * @brief Set an network interface's MTU
1386  *
1387  * @param iface Pointer to a network interface structure
1388  * @param mtu New MTU, note that we store only 16 bit mtu value.
1389  */
net_if_set_mtu(struct net_if * iface,uint16_t mtu)1390 static inline void net_if_set_mtu(struct net_if *iface,
1391 				  uint16_t mtu)
1392 {
1393 	if (iface == NULL || iface->if_dev == NULL) {
1394 		return;
1395 	}
1396 
1397 	iface->if_dev->mtu = mtu;
1398 }
1399 
1400 /**
1401  * @brief Set the infinite status of the network interface address
1402  *
1403  * @param ifaddr IP address for network interface
1404  * @param is_infinite Infinite status
1405  */
net_if_addr_set_lf(struct net_if_addr * ifaddr,bool is_infinite)1406 static inline void net_if_addr_set_lf(struct net_if_addr *ifaddr,
1407 				      bool is_infinite)
1408 {
1409 	if (ifaddr == NULL) {
1410 		return;
1411 	}
1412 
1413 	ifaddr->is_infinite = is_infinite;
1414 }
1415 
1416 /**
1417  * @brief Get an interface according to link layer address.
1418  *
1419  * @param ll_addr Link layer address.
1420  *
1421  * @return Network interface or NULL if not found.
1422  */
1423 struct net_if *net_if_get_by_link_addr(struct net_linkaddr *ll_addr);
1424 
1425 /**
1426  * @brief Find an interface from it's related device
1427  *
1428  * @param dev A valid struct device pointer to relate with an interface
1429  *
1430  * @return a valid struct net_if pointer on success, NULL otherwise
1431  */
1432 struct net_if *net_if_lookup_by_dev(const struct device *dev);
1433 
1434 /**
1435  * @brief Get network interface IP config
1436  *
1437  * @param iface Interface to use.
1438  *
1439  * @return NULL if not found or pointer to correct config settings.
1440  */
net_if_config_get(struct net_if * iface)1441 static inline struct net_if_config *net_if_config_get(struct net_if *iface)
1442 {
1443 	if (iface == NULL) {
1444 		return NULL;
1445 	}
1446 
1447 	return &iface->config;
1448 }
1449 
1450 /**
1451  * @brief Remove a router from the system
1452  *
1453  * @param router Pointer to existing router
1454  */
1455 void net_if_router_rm(struct net_if_router *router);
1456 
1457 /**
1458  * @brief Set the default network interface.
1459  *
1460  * @param iface New default interface, or NULL to revert to the one set by Kconfig.
1461  */
1462 void net_if_set_default(struct net_if *iface);
1463 
1464 /**
1465  * @brief Get the default network interface.
1466  *
1467  * @return Default interface or NULL if no interfaces are configured.
1468  */
1469 struct net_if *net_if_get_default(void);
1470 
1471 /**
1472  * @brief Get the first network interface according to its type.
1473  *
1474  * @param l2 Layer 2 type of the network interface.
1475  *
1476  * @return First network interface of a given type or NULL if no such
1477  * interfaces was found.
1478  */
1479 struct net_if *net_if_get_first_by_type(const struct net_l2 *l2);
1480 
1481 /**
1482  * @brief Get the first network interface which is up.
1483  *
1484  * @return First network interface which is up or NULL if all
1485  * interfaces are down.
1486  */
1487 struct net_if *net_if_get_first_up(void);
1488 
1489 #if defined(CONFIG_NET_L2_IEEE802154)
1490 /**
1491  * @brief Get the first IEEE 802.15.4 network interface.
1492  *
1493  * @return First IEEE 802.15.4 network interface or NULL if no such
1494  * interfaces was found.
1495  */
net_if_get_ieee802154(void)1496 static inline struct net_if *net_if_get_ieee802154(void)
1497 {
1498 	return net_if_get_first_by_type(&NET_L2_GET_NAME(IEEE802154));
1499 }
1500 #endif /* CONFIG_NET_L2_IEEE802154 */
1501 
1502 /**
1503  * @brief Allocate network interface IPv6 config.
1504  *
1505  * @details This function will allocate new IPv6 config.
1506  *
1507  * @param iface Interface to use.
1508  * @param ipv6 Pointer to allocated IPv6 struct is returned to caller.
1509  *
1510  * @return 0 if ok, <0 if error
1511  */
1512 int net_if_config_ipv6_get(struct net_if *iface,
1513 			   struct net_if_ipv6 **ipv6);
1514 
1515 /**
1516  * @brief Release network interface IPv6 config.
1517  *
1518  * @param iface Interface to use.
1519  *
1520  * @return 0 if ok, <0 if error
1521  */
1522 int net_if_config_ipv6_put(struct net_if *iface);
1523 
1524 
1525 /** @cond INTERNAL_HIDDEN */
1526 struct net_if_addr *net_if_ipv6_addr_lookup_raw(const uint8_t *addr,
1527 						struct net_if **ret);
1528 /** @endcond */
1529 
1530 /**
1531  * @brief Check if this IPv6 address belongs to one of the interfaces.
1532  *
1533  * @param addr IPv6 address
1534  * @param iface Pointer to interface is returned
1535  *
1536  * @return Pointer to interface address, NULL if not found.
1537  */
1538 struct net_if_addr *net_if_ipv6_addr_lookup(const struct net_in6_addr *addr,
1539 					    struct net_if **iface);
1540 
1541 /** @cond INTERNAL_HIDDEN */
1542 struct net_if_addr *net_if_ipv6_addr_lookup_by_iface_raw(struct net_if *iface,
1543 							 const uint8_t *addr);
1544 /** @endcond */
1545 
1546 /**
1547  * @brief Check if this IPv6 address belongs to this specific interfaces.
1548  *
1549  * @param iface Network interface
1550  * @param addr IPv6 address
1551  *
1552  * @return Pointer to interface address, NULL if not found.
1553  */
1554 struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
1555 						     const struct net_in6_addr *addr);
1556 
1557 /**
1558  * @brief Check if this IPv6 address belongs to one of the interface indices.
1559  *
1560  * @param addr IPv6 address
1561  *
1562  * @return >0 if address was found in given network interface index,
1563  * all other values mean address was not found
1564  */
1565 __syscall int net_if_ipv6_addr_lookup_by_index(const struct net_in6_addr *addr);
1566 
1567 /**
1568  * @brief Add a IPv6 address to an interface
1569  *
1570  * @param iface Network interface
1571  * @param addr IPv6 address
1572  * @param addr_type IPv6 address type
1573  * @param vlifetime Validity time for this address
1574  *
1575  * @return Pointer to interface address, NULL if cannot be added
1576  */
1577 struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
1578 					 const struct net_in6_addr *addr,
1579 					 enum net_addr_type addr_type,
1580 					 uint32_t vlifetime);
1581 
1582 /**
1583  * @brief Add a IPv6 address to an interface by index
1584  *
1585  * @param index Network interface index
1586  * @param addr IPv6 address
1587  * @param addr_type IPv6 address type
1588  * @param vlifetime Validity time for this address
1589  *
1590  * @return True if ok, false if address could not be added
1591  */
1592 __syscall bool net_if_ipv6_addr_add_by_index(int index,
1593 					     const struct net_in6_addr *addr,
1594 					     enum net_addr_type addr_type,
1595 					     uint32_t vlifetime);
1596 
1597 /**
1598  * @brief Update validity lifetime time of an IPv6 address.
1599  *
1600  * @param ifaddr Network IPv6 address
1601  * @param vlifetime Validity time for this address
1602  */
1603 void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr,
1604 				      uint32_t vlifetime);
1605 
1606 /**
1607  * @brief Remove an IPv6 address from an interface
1608  *
1609  * @param iface Network interface
1610  * @param addr IPv6 address
1611  *
1612  * @return True if successfully removed, false otherwise
1613  */
1614 bool net_if_ipv6_addr_rm(struct net_if *iface, const struct net_in6_addr *addr);
1615 
1616 /**
1617  * @brief Remove an IPv6 address from an interface by index
1618  *
1619  * @param index Network interface index
1620  * @param addr IPv6 address
1621  *
1622  * @return True if successfully removed, false otherwise
1623  */
1624 __syscall bool net_if_ipv6_addr_rm_by_index(int index,
1625 					    const struct net_in6_addr *addr);
1626 
1627 /**
1628  * @typedef net_if_ip_addr_cb_t
1629  * @brief Callback used while iterating over network interface IP addresses
1630  *
1631  * @param iface Pointer to the network interface the address belongs to
1632  * @param addr Pointer to current IP address
1633  * @param user_data A valid pointer to user data or NULL
1634  */
1635 typedef void (*net_if_ip_addr_cb_t)(struct net_if *iface,
1636 				    struct net_if_addr *addr,
1637 				    void *user_data);
1638 
1639 /**
1640  * @brief Go through all IPv6 addresses on a network interface and call callback
1641  * for each used address.
1642  *
1643  * @param iface Pointer to the network interface
1644  * @param cb User-supplied callback function to call
1645  * @param user_data User specified data
1646  */
1647 void net_if_ipv6_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb,
1648 			      void *user_data);
1649 
1650 /**
1651  * @brief Add a IPv6 multicast address to an interface
1652  *
1653  * @param iface Network interface
1654  * @param addr IPv6 multicast address
1655  *
1656  * @return Pointer to interface multicast address, NULL if cannot be added
1657  */
1658 struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
1659 						const struct net_in6_addr *addr);
1660 
1661 /**
1662  * @brief Remove an IPv6 multicast address from an interface
1663  *
1664  * @param iface Network interface
1665  * @param addr IPv6 multicast address
1666  *
1667  * @return True if successfully removed, false otherwise
1668  */
1669 bool net_if_ipv6_maddr_rm(struct net_if *iface, const struct net_in6_addr *addr);
1670 
1671 /**
1672  * @typedef net_if_ip_maddr_cb_t
1673  * @brief Callback used while iterating over network interface multicast IP addresses
1674  *
1675  * @param iface Pointer to the network interface the address belongs to
1676  * @param maddr Pointer to current multicast IP address
1677  * @param user_data A valid pointer to user data or NULL
1678  */
1679 typedef void (*net_if_ip_maddr_cb_t)(struct net_if *iface,
1680 				     struct net_if_mcast_addr *maddr,
1681 				     void *user_data);
1682 
1683 /**
1684  * @brief Go through all IPv6 multicast addresses on a network interface and call
1685  * callback for each used address.
1686  *
1687  * @param iface Pointer to the network interface
1688  * @param cb User-supplied callback function to call
1689  * @param user_data User specified data
1690  */
1691 void net_if_ipv6_maddr_foreach(struct net_if *iface, net_if_ip_maddr_cb_t cb,
1692 			       void *user_data);
1693 
1694 
1695 /** @cond INTERNAL_HIDDEN */
1696 struct net_if_mcast_addr *net_if_ipv6_maddr_lookup_raw(const uint8_t *maddr,
1697 						       struct net_if **ret);
1698 /** @endcond */
1699 
1700 /**
1701  * @brief Check if this IPv6 multicast address belongs to a specific interface
1702  * or one of the interfaces.
1703  *
1704  * @param addr IPv6 address
1705  * @param iface If *iface is null, then pointer to interface is returned,
1706  * otherwise the *iface value needs to be matched.
1707  *
1708  * @return Pointer to interface multicast address, NULL if not found.
1709  */
1710 struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct net_in6_addr *addr,
1711 						   struct net_if **iface);
1712 
1713 /**
1714  * @typedef net_if_mcast_callback_t
1715 
1716  * @brief Define a callback that is called whenever a IPv6 or IPv4 multicast
1717  *        address group is joined or left.
1718  * @param iface A pointer to a struct net_if to which the multicast address is
1719  *        attached.
1720  * @param addr IP multicast address.
1721  * @param is_joined True if the multicast group is joined, false if group is left.
1722  */
1723 typedef void (*net_if_mcast_callback_t)(struct net_if *iface,
1724 					const struct net_addr *addr,
1725 					bool is_joined);
1726 
1727 /**
1728  * @brief Multicast monitor handler struct.
1729  *
1730  * Stores the multicast callback information. Caller must make sure that
1731  * the variable pointed by this is valid during the lifetime of
1732  * registration. Typically this means that the variable cannot be
1733  * allocated from stack.
1734  */
1735 struct net_if_mcast_monitor {
1736 	/** Node information for the slist. */
1737 	sys_snode_t node;
1738 
1739 	/** Network interface */
1740 	struct net_if *iface;
1741 
1742 	/** Multicast callback */
1743 	net_if_mcast_callback_t cb;
1744 };
1745 
1746 /**
1747  * @brief Register a multicast monitor
1748  *
1749  * @param mon Monitor handle. This is a pointer to a monitor storage structure
1750  * which should be allocated by caller, but does not need to be initialized.
1751  * @param iface Network interface or NULL for all interfaces
1752  * @param cb Monitor callback
1753  */
1754 void net_if_mcast_mon_register(struct net_if_mcast_monitor *mon,
1755 			       struct net_if *iface,
1756 			       net_if_mcast_callback_t cb);
1757 
1758 /**
1759  * @brief Unregister a multicast monitor
1760  *
1761  * @param mon Monitor handle
1762  */
1763 void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon);
1764 
1765 /**
1766  * @brief Call registered multicast monitors
1767  *
1768  * @param iface Network interface
1769  * @param addr Multicast address
1770  * @param is_joined Is this multicast address group joined (true) or not (false)
1771  */
1772 void net_if_mcast_monitor(struct net_if *iface, const struct net_addr *addr,
1773 			  bool is_joined);
1774 
1775 /**
1776  * @brief Mark a given multicast address to be joined.
1777  *
1778  * @param iface Network interface the address belongs to
1779  * @param addr IPv6 multicast address
1780  */
1781 void net_if_ipv6_maddr_join(struct net_if *iface,
1782 			    struct net_if_mcast_addr *addr);
1783 
1784 /**
1785  * @brief Check if given multicast address is joined or not.
1786  *
1787  * @param addr IPv6 multicast address
1788  *
1789  * @return True if address is joined, False otherwise.
1790  */
net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr * addr)1791 static inline bool net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr *addr)
1792 {
1793 	if (addr == NULL) {
1794 		return false;
1795 	}
1796 
1797 	return addr->is_joined;
1798 }
1799 
1800 /**
1801  * @brief Mark a given multicast address to be left.
1802  *
1803  * @param iface Network interface the address belongs to
1804  * @param addr IPv6 multicast address
1805  */
1806 void net_if_ipv6_maddr_leave(struct net_if *iface,
1807 			     struct net_if_mcast_addr *addr);
1808 
1809 /**
1810  * @brief Return prefix that corresponds to this IPv6 address.
1811  *
1812  * @param iface Network interface
1813  * @param addr IPv6 address
1814  *
1815  * @return Pointer to prefix, NULL if not found.
1816  */
1817 struct net_if_ipv6_prefix *net_if_ipv6_prefix_get(struct net_if *iface,
1818 						  const struct net_in6_addr *addr);
1819 
1820 /**
1821  * @brief Check if this IPv6 prefix belongs to this interface
1822  *
1823  * @param iface Network interface
1824  * @param addr IPv6 address
1825  * @param len Prefix length
1826  *
1827  * @return Pointer to prefix, NULL if not found.
1828  */
1829 struct net_if_ipv6_prefix *net_if_ipv6_prefix_lookup(struct net_if *iface,
1830 						     const struct net_in6_addr *addr,
1831 						     uint8_t len);
1832 
1833 /**
1834  * @brief Add a IPv6 prefix to an network interface.
1835  *
1836  * @param iface Network interface
1837  * @param prefix IPv6 address
1838  * @param len Prefix length
1839  * @param lifetime Prefix lifetime in seconds
1840  *
1841  * @return Pointer to prefix, NULL if the prefix was not added.
1842  */
1843 struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface,
1844 						  const struct net_in6_addr *prefix,
1845 						  uint8_t len,
1846 						  uint32_t lifetime);
1847 
1848 /**
1849  * @brief Remove an IPv6 prefix from an interface
1850  *
1851  * @param iface Network interface
1852  * @param addr IPv6 prefix address
1853  * @param len Prefix length
1854  *
1855  * @return True if successfully removed, false otherwise
1856  */
1857 bool net_if_ipv6_prefix_rm(struct net_if *iface, const struct net_in6_addr *addr,
1858 			   uint8_t len);
1859 
1860 /**
1861  * @brief Set the infinite status of the prefix
1862  *
1863  * @param prefix IPv6 address
1864  * @param is_infinite Infinite status
1865  */
net_if_ipv6_prefix_set_lf(struct net_if_ipv6_prefix * prefix,bool is_infinite)1866 static inline void net_if_ipv6_prefix_set_lf(struct net_if_ipv6_prefix *prefix,
1867 					     bool is_infinite)
1868 {
1869 	prefix->is_infinite = is_infinite;
1870 }
1871 
1872 /**
1873  * @brief Set the prefix lifetime timer.
1874  *
1875  * @param prefix IPv6 address
1876  * @param lifetime Prefix lifetime in seconds
1877  */
1878 void net_if_ipv6_prefix_set_timer(struct net_if_ipv6_prefix *prefix,
1879 				  uint32_t lifetime);
1880 
1881 /**
1882  * @brief Unset the prefix lifetime timer.
1883  *
1884  * @param prefix IPv6 address
1885  */
1886 void net_if_ipv6_prefix_unset_timer(struct net_if_ipv6_prefix *prefix);
1887 
1888 /**
1889  * @brief Check if this IPv6 address is part of the subnet of our
1890  * network interface.
1891  *
1892  * @param iface Network interface. This is returned to the caller.
1893  * The iface can be NULL in which case we check all the interfaces.
1894  * @param addr IPv6 address
1895  *
1896  * @return True if address is part of our subnet, false otherwise
1897  */
1898 bool net_if_ipv6_addr_onlink(struct net_if **iface, const struct net_in6_addr *addr);
1899 
1900 /**
1901  * @brief Get the IPv6 address of the given router
1902  * @param router a network router
1903  *
1904  * @return pointer to the IPv6 address, or NULL if none
1905  */
1906 #if defined(CONFIG_NET_NATIVE_IPV6)
net_if_router_ipv6(struct net_if_router * router)1907 static inline struct net_in6_addr *net_if_router_ipv6(struct net_if_router *router)
1908 {
1909 	if (router == NULL) {
1910 		return NULL;
1911 	}
1912 
1913 	return &router->address.in6_addr;
1914 }
1915 #else
net_if_router_ipv6(struct net_if_router * router)1916 static inline struct net_in6_addr *net_if_router_ipv6(struct net_if_router *router)
1917 {
1918 	static struct net_in6_addr addr;
1919 
1920 	ARG_UNUSED(router);
1921 
1922 	return &addr;
1923 }
1924 #endif
1925 
1926 /**
1927  * @brief Check if IPv6 address is one of the routers configured
1928  * in the system.
1929  *
1930  * @param iface Network interface
1931  * @param addr IPv6 address
1932  *
1933  * @return Pointer to router information, NULL if cannot be found
1934  */
1935 struct net_if_router *net_if_ipv6_router_lookup(struct net_if *iface,
1936 						const struct net_in6_addr *addr);
1937 
1938 /**
1939  * @brief Find default router for this IPv6 address.
1940  *
1941  * @param iface Network interface. This can be NULL in which case we
1942  * go through all the network interfaces to find a suitable router.
1943  * @param addr IPv6 address
1944  *
1945  * @return Pointer to router information, NULL if cannot be found
1946  */
1947 struct net_if_router *net_if_ipv6_router_find_default(struct net_if *iface,
1948 						      const struct net_in6_addr *addr);
1949 
1950 /**
1951  * @brief Update validity lifetime time of a router.
1952  *
1953  * @param router Network IPv6 address
1954  * @param lifetime Lifetime of this router.
1955  */
1956 void net_if_ipv6_router_update_lifetime(struct net_if_router *router,
1957 					uint16_t lifetime);
1958 
1959 /**
1960  * @brief Add IPv6 router to the system.
1961  *
1962  * @param iface Network interface
1963  * @param addr IPv6 address
1964  * @param router_lifetime Lifetime of the router
1965  *
1966  * @return Pointer to router information, NULL if could not be added
1967  */
1968 struct net_if_router *net_if_ipv6_router_add(struct net_if *iface,
1969 					     const struct net_in6_addr *addr,
1970 					     uint16_t router_lifetime);
1971 
1972 /**
1973  * @brief Remove IPv6 router from the system.
1974  *
1975  * @param router Router information.
1976  *
1977  * @return True if successfully removed, false otherwise
1978  */
1979 bool net_if_ipv6_router_rm(struct net_if_router *router);
1980 
1981 /**
1982  * @brief Get IPv6 hop limit specified for a given interface. This is the
1983  * default value but can be overridden by the user.
1984  *
1985  * @param iface Network interface
1986  *
1987  * @return Hop limit
1988  */
1989 #if defined(CONFIG_NET_NATIVE_IPV6)
1990 uint8_t net_if_ipv6_get_hop_limit(struct net_if *iface);
1991 #else
net_if_ipv6_get_hop_limit(struct net_if * iface)1992 static inline uint8_t net_if_ipv6_get_hop_limit(struct net_if *iface)
1993 {
1994 	ARG_UNUSED(iface);
1995 
1996 	return 0;
1997 }
1998 #endif /* CONFIG_NET_NATIVE_IPV6 */
1999 
2000 /**
2001  * @brief Set the default IPv6 hop limit of a given interface.
2002  *
2003  * @param iface Network interface
2004  * @param hop_limit New hop limit
2005  */
2006 #if defined(CONFIG_NET_NATIVE_IPV6)
2007 void net_if_ipv6_set_hop_limit(struct net_if *iface, uint8_t hop_limit);
2008 #else
net_if_ipv6_set_hop_limit(struct net_if * iface,uint8_t hop_limit)2009 static inline void net_if_ipv6_set_hop_limit(struct net_if *iface,
2010 					     uint8_t hop_limit)
2011 {
2012 	ARG_UNUSED(iface);
2013 	ARG_UNUSED(hop_limit);
2014 }
2015 #endif /* CONFIG_NET_NATIVE_IPV6 */
2016 
2017 /** @cond INTERNAL_HIDDEN */
2018 
2019 /* The old hop limit setter function is deprecated because the naming
2020  * of it was incorrect. The API name was missing "_if_" so this function
2021  * should not be used.
2022  */
2023 __deprecated
net_ipv6_set_hop_limit(struct net_if * iface,uint8_t hop_limit)2024 static inline void net_ipv6_set_hop_limit(struct net_if *iface,
2025 					  uint8_t hop_limit)
2026 {
2027 	net_if_ipv6_set_hop_limit(iface, hop_limit);
2028 }
2029 
2030 /** @endcond */
2031 
2032 /**
2033  * @brief Get IPv6 multicast hop limit specified for a given interface. This is the
2034  * default value but can be overridden by the user.
2035  *
2036  * @param iface Network interface
2037  *
2038  * @return Hop limit
2039  */
2040 #if defined(CONFIG_NET_NATIVE_IPV6)
2041 uint8_t net_if_ipv6_get_mcast_hop_limit(struct net_if *iface);
2042 #else
net_if_ipv6_get_mcast_hop_limit(struct net_if * iface)2043 static inline uint8_t net_if_ipv6_get_mcast_hop_limit(struct net_if *iface)
2044 {
2045 	ARG_UNUSED(iface);
2046 
2047 	return 0;
2048 }
2049 #endif /* CONFIG_NET_NATIVE_IPV6 */
2050 
2051 /**
2052  * @brief Set the default IPv6 multicast hop limit of a given interface.
2053  *
2054  * @param iface Network interface
2055  * @param hop_limit New hop limit
2056  */
2057 #if defined(CONFIG_NET_NATIVE_IPV6)
2058 void net_if_ipv6_set_mcast_hop_limit(struct net_if *iface, uint8_t hop_limit);
2059 #else
net_if_ipv6_set_mcast_hop_limit(struct net_if * iface,uint8_t hop_limit)2060 static inline void net_if_ipv6_set_mcast_hop_limit(struct net_if *iface,
2061 						   uint8_t hop_limit)
2062 {
2063 	ARG_UNUSED(iface);
2064 	ARG_UNUSED(hop_limit);
2065 }
2066 #endif /* CONFIG_NET_NATIVE_IPV6 */
2067 
2068 /**
2069  * @brief Set IPv6 reachable time for a given interface
2070  *
2071  * @param iface Network interface
2072  * @param reachable_time New reachable time
2073  */
net_if_ipv6_set_base_reachable_time(struct net_if * iface,uint32_t reachable_time)2074 static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface,
2075 						       uint32_t reachable_time)
2076 {
2077 #if defined(CONFIG_NET_NATIVE_IPV6)
2078 	if (iface == NULL) {
2079 		return;
2080 	}
2081 
2082 	if (!iface->config.ip.ipv6) {
2083 		return;
2084 	}
2085 
2086 	iface->config.ip.ipv6->base_reachable_time = reachable_time;
2087 #else
2088 	ARG_UNUSED(iface);
2089 	ARG_UNUSED(reachable_time);
2090 
2091 #endif
2092 }
2093 
2094 /**
2095  * @brief Get IPv6 reachable timeout specified for a given interface
2096  *
2097  * @param iface Network interface
2098  *
2099  * @return Reachable timeout
2100  */
net_if_ipv6_get_reachable_time(struct net_if * iface)2101 static inline uint32_t net_if_ipv6_get_reachable_time(struct net_if *iface)
2102 {
2103 #if defined(CONFIG_NET_NATIVE_IPV6)
2104 	if (iface == NULL) {
2105 		return 0;
2106 	}
2107 
2108 	if (!iface->config.ip.ipv6) {
2109 		return 0;
2110 	}
2111 
2112 	return iface->config.ip.ipv6->reachable_time;
2113 #else
2114 	ARG_UNUSED(iface);
2115 	return 0;
2116 #endif
2117 }
2118 
2119 /**
2120  * @brief Calculate next reachable time value for IPv6 reachable time
2121  *
2122  * @param ipv6 IPv6 address configuration
2123  *
2124  * @return Reachable time
2125  */
2126 uint32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6);
2127 
2128 /**
2129  * @brief Set IPv6 reachable time for a given interface. This requires
2130  * that base reachable time is set for the interface.
2131  *
2132  * @param ipv6 IPv6 address configuration
2133  */
net_if_ipv6_set_reachable_time(struct net_if_ipv6 * ipv6)2134 static inline void net_if_ipv6_set_reachable_time(struct net_if_ipv6 *ipv6)
2135 {
2136 #if defined(CONFIG_NET_NATIVE_IPV6)
2137 	if (ipv6 == NULL) {
2138 		return;
2139 	}
2140 
2141 	ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6);
2142 #else
2143 	ARG_UNUSED(ipv6);
2144 #endif
2145 }
2146 
2147 /**
2148  * @brief Set IPv6 retransmit timer for a given interface
2149  *
2150  * @param iface Network interface
2151  * @param retrans_timer New retransmit timer
2152  */
net_if_ipv6_set_retrans_timer(struct net_if * iface,uint32_t retrans_timer)2153 static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface,
2154 						 uint32_t retrans_timer)
2155 {
2156 #if defined(CONFIG_NET_NATIVE_IPV6)
2157 	if (iface == NULL) {
2158 		return;
2159 	}
2160 
2161 	if (!iface->config.ip.ipv6) {
2162 		return;
2163 	}
2164 
2165 	iface->config.ip.ipv6->retrans_timer = retrans_timer;
2166 #else
2167 	ARG_UNUSED(iface);
2168 	ARG_UNUSED(retrans_timer);
2169 #endif
2170 }
2171 
2172 /**
2173  * @brief Get IPv6 retransmit timer specified for a given interface
2174  *
2175  * @param iface Network interface
2176  *
2177  * @return Retransmit timer
2178  */
net_if_ipv6_get_retrans_timer(struct net_if * iface)2179 static inline uint32_t net_if_ipv6_get_retrans_timer(struct net_if *iface)
2180 {
2181 #if defined(CONFIG_NET_NATIVE_IPV6)
2182 	if (iface == NULL) {
2183 		return 0;
2184 	}
2185 
2186 	if (!iface->config.ip.ipv6) {
2187 		return 0;
2188 	}
2189 
2190 	return iface->config.ip.ipv6->retrans_timer;
2191 #else
2192 	ARG_UNUSED(iface);
2193 	return 0;
2194 #endif
2195 }
2196 
2197 /**
2198  * @brief Get a IPv6 source address that should be used when sending
2199  * network data to destination.
2200  *
2201  * @param iface Interface that was used when packet was received.
2202  * If the interface is not known, then NULL can be given.
2203  * @param dst IPv6 destination address
2204  *
2205  * @return Pointer to IPv6 address to use, NULL if no IPv6 address
2206  * could be found.
2207  */
2208 #if defined(CONFIG_NET_IPV6)
2209 const struct net_in6_addr *net_if_ipv6_select_src_addr(struct net_if *iface,
2210 						   const struct net_in6_addr *dst);
2211 #else
net_if_ipv6_select_src_addr(struct net_if * iface,const struct net_in6_addr * dst)2212 static inline const struct net_in6_addr *net_if_ipv6_select_src_addr(
2213 	struct net_if *iface, const struct net_in6_addr *dst)
2214 {
2215 	ARG_UNUSED(iface);
2216 	ARG_UNUSED(dst);
2217 
2218 	return NULL;
2219 }
2220 #endif
2221 
2222 /**
2223  * @brief Get a IPv6 source address that should be used when sending
2224  * network data to destination. Use a hint set to the socket to select
2225  * the proper address.
2226  *
2227  * @param iface Interface that was used when packet was received.
2228  * If the interface is not known, then NULL can be given.
2229  * @param dst IPv6 destination address
2230  * @param flags Hint from the related socket. See RFC 5014 for value details.
2231  *
2232  * @return Pointer to IPv6 address to use, NULL if no IPv6 address
2233  * could be found.
2234  */
2235 #if defined(CONFIG_NET_IPV6)
2236 const struct net_in6_addr *net_if_ipv6_select_src_addr_hint(struct net_if *iface,
2237 							const struct net_in6_addr *dst,
2238 							int flags);
2239 #else
net_if_ipv6_select_src_addr_hint(struct net_if * iface,const struct net_in6_addr * dst,int flags)2240 static inline const struct net_in6_addr *net_if_ipv6_select_src_addr_hint(
2241 	struct net_if *iface, const struct net_in6_addr *dst, int flags)
2242 {
2243 	ARG_UNUSED(iface);
2244 	ARG_UNUSED(dst);
2245 	ARG_UNUSED(flags);
2246 
2247 	return NULL;
2248 }
2249 #endif
2250 
2251 /**
2252  * @brief Get a network interface that should be used when sending
2253  * IPv6 network data to destination.
2254  *
2255  * @param dst IPv6 destination address
2256  *
2257  * @return Pointer to network interface to use, NULL if no suitable interface
2258  * could be found.
2259  */
2260 #if defined(CONFIG_NET_IPV6)
2261 struct net_if *net_if_ipv6_select_src_iface(const struct net_in6_addr *dst);
2262 #else
net_if_ipv6_select_src_iface(const struct net_in6_addr * dst)2263 static inline struct net_if *net_if_ipv6_select_src_iface(
2264 	const struct net_in6_addr *dst)
2265 {
2266 	ARG_UNUSED(dst);
2267 
2268 	return NULL;
2269 }
2270 #endif
2271 
2272 /**
2273  * @brief Get a network interface that should be used when sending
2274  * IPv6 network data to destination. Also return the source IPv6 address from
2275  * that network interface.
2276  *
2277  * @param dst IPv6 destination address
2278  * @param src_addr IPv6 source address. This can be set to NULL if the source
2279  *                 address is not needed.
2280  *
2281  * @return Pointer to network interface to use, NULL if no suitable interface
2282  * could be found.
2283  */
2284 #if defined(CONFIG_NET_IPV6)
2285 struct net_if *net_if_ipv6_select_src_iface_addr(const struct net_in6_addr *dst,
2286 						 const struct net_in6_addr **src_addr);
2287 #else
net_if_ipv6_select_src_iface_addr(const struct net_in6_addr * dst,const struct net_in6_addr ** src_addr)2288 static inline struct net_if *net_if_ipv6_select_src_iface_addr(
2289 	const struct net_in6_addr *dst, const struct net_in6_addr **src_addr)
2290 {
2291 	ARG_UNUSED(dst);
2292 	ARG_UNUSED(src_addr);
2293 
2294 	return NULL;
2295 }
2296 #endif /* CONFIG_NET_IPV6 */
2297 
2298 /**
2299  * @brief Get a IPv6 link local address in a given state.
2300  *
2301  * @param iface Interface to use. Must be a valid pointer to an interface.
2302  * @param addr_state IPv6 address state (preferred, tentative, deprecated)
2303  *
2304  * @return Pointer to link local IPv6 address, NULL if no proper IPv6 address
2305  * could be found.
2306  */
2307 struct net_in6_addr *net_if_ipv6_get_ll(struct net_if *iface,
2308 				    enum net_addr_state addr_state);
2309 
2310 /**
2311  * @brief Return link local IPv6 address from the first interface that has
2312  * a link local address matching give state.
2313  *
2314  * @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
2315  * @param iface Pointer to interface is returned
2316  *
2317  * @return Pointer to IPv6 address, NULL if not found.
2318  */
2319 struct net_in6_addr *net_if_ipv6_get_ll_addr(enum net_addr_state state,
2320 					 struct net_if **iface);
2321 
2322 /**
2323  * @brief Stop IPv6 Duplicate Address Detection (DAD) procedure if
2324  * we find out that our IPv6 address is already in use.
2325  *
2326  * @param iface Interface where the DAD was running.
2327  * @param addr IPv6 address that failed DAD
2328  */
2329 void net_if_ipv6_dad_failed(struct net_if *iface, const struct net_in6_addr *addr);
2330 
2331 /**
2332  * @brief Return global IPv6 address from the first interface that has
2333  * a global IPv6 address matching the given state.
2334  *
2335  * @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
2336  * @param iface Caller can give an interface to check. If iface is set to NULL,
2337  * then all the interfaces are checked. Pointer to interface where the IPv6
2338  * address is defined is returned to the caller.
2339  *
2340  * @return Pointer to IPv6 address, NULL if not found.
2341  */
2342 struct net_in6_addr *net_if_ipv6_get_global_addr(enum net_addr_state state,
2343 					     struct net_if **iface);
2344 
2345 /**
2346  * @brief Allocate network interface IPv4 config.
2347  *
2348  * @details This function will allocate new IPv4 config.
2349  *
2350  * @param iface Interface to use.
2351  * @param ipv4 Pointer to allocated IPv4 struct is returned to caller.
2352  *
2353  * @return 0 if ok, <0 if error
2354  */
2355 int net_if_config_ipv4_get(struct net_if *iface,
2356 			   struct net_if_ipv4 **ipv4);
2357 
2358 /**
2359  * @brief Release network interface IPv4 config.
2360  *
2361  * @param iface Interface to use.
2362  *
2363  * @return 0 if ok, <0 if error
2364  */
2365 int net_if_config_ipv4_put(struct net_if *iface);
2366 
2367 /**
2368  * @brief Get IPv4 time-to-live value specified for a given interface
2369  *
2370  * @param iface Network interface
2371  *
2372  * @return Time-to-live
2373  */
2374 uint8_t net_if_ipv4_get_ttl(struct net_if *iface);
2375 
2376 /**
2377  * @brief Set IPv4 time-to-live value specified to a given interface
2378  *
2379  * @param iface Network interface
2380  * @param ttl Time-to-live value
2381  */
2382 void net_if_ipv4_set_ttl(struct net_if *iface, uint8_t ttl);
2383 
2384 /**
2385  * @brief Get IPv4 multicast time-to-live value specified for a given interface
2386  *
2387  * @param iface Network interface
2388  *
2389  * @return Time-to-live
2390  */
2391 uint8_t net_if_ipv4_get_mcast_ttl(struct net_if *iface);
2392 
2393 /**
2394  * @brief Set IPv4 multicast time-to-live value specified to a given interface
2395  *
2396  * @param iface Network interface
2397  * @param ttl Time-to-live value
2398  */
2399 void net_if_ipv4_set_mcast_ttl(struct net_if *iface, uint8_t ttl);
2400 
2401 /**
2402  * @brief Check if this IPv4 address belongs to one of the interfaces.
2403  *
2404  * @param addr IPv4 address
2405  * @param iface Interface is returned
2406  *
2407  * @return Pointer to interface address, NULL if not found.
2408  */
2409 struct net_if_addr *net_if_ipv4_addr_lookup(const struct net_in_addr *addr,
2410 					    struct net_if **iface);
2411 
2412 /**
2413  * @brief Add a IPv4 address to an interface
2414  *
2415  * @param iface Network interface
2416  * @param addr IPv4 address
2417  * @param addr_type IPv4 address type
2418  * @param vlifetime Validity time for this address
2419  *
2420  * @return Pointer to interface address, NULL if cannot be added
2421  */
2422 struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface,
2423 					 const struct net_in_addr *addr,
2424 					 enum net_addr_type addr_type,
2425 					 uint32_t vlifetime);
2426 
2427 /**
2428  * @brief Remove a IPv4 address from an interface
2429  *
2430  * @param iface Network interface
2431  * @param addr IPv4 address
2432  *
2433  * @return True if successfully removed, false otherwise
2434  */
2435 bool net_if_ipv4_addr_rm(struct net_if *iface, const struct net_in_addr *addr);
2436 
2437 /**
2438  * @brief Check if this IPv4 address belongs to one of the interface indices.
2439  *
2440  * @param addr IPv4 address
2441  *
2442  * @return >0 if address was found in given network interface index,
2443  * all other values mean address was not found
2444  */
2445 __syscall int net_if_ipv4_addr_lookup_by_index(const struct net_in_addr *addr);
2446 
2447 /**
2448  * @brief Add a IPv4 address to an interface by network interface index
2449  *
2450  * @param index Network interface index
2451  * @param addr IPv4 address
2452  * @param addr_type IPv4 address type
2453  * @param vlifetime Validity time for this address
2454  *
2455  * @return True if ok, false if the address could not be added
2456  */
2457 __syscall bool net_if_ipv4_addr_add_by_index(int index,
2458 					     const struct net_in_addr *addr,
2459 					     enum net_addr_type addr_type,
2460 					     uint32_t vlifetime);
2461 
2462 /**
2463  * @brief Remove a IPv4 address from an interface by interface index
2464  *
2465  * @param index Network interface index
2466  * @param addr IPv4 address
2467  *
2468  * @return True if successfully removed, false otherwise
2469  */
2470 __syscall bool net_if_ipv4_addr_rm_by_index(int index,
2471 					    const struct net_in_addr *addr);
2472 
2473 /**
2474  * @brief Go through all IPv4 addresses on a network interface and call callback
2475  * for each used address.
2476  *
2477  * @param iface Pointer to the network interface
2478  * @param cb User-supplied callback function to call
2479  * @param user_data User specified data
2480  */
2481 void net_if_ipv4_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb,
2482 			      void *user_data);
2483 
2484 /**
2485  * @brief Add a IPv4 multicast address to an interface
2486  *
2487  * @param iface Network interface
2488  * @param addr IPv4 multicast address
2489  *
2490  * @return Pointer to interface multicast address, NULL if cannot be added
2491  */
2492 struct net_if_mcast_addr *net_if_ipv4_maddr_add(struct net_if *iface,
2493 						const struct net_in_addr *addr);
2494 
2495 /**
2496  * @brief Remove an IPv4 multicast address from an interface
2497  *
2498  * @param iface Network interface
2499  * @param addr IPv4 multicast address
2500  *
2501  * @return True if successfully removed, false otherwise
2502  */
2503 bool net_if_ipv4_maddr_rm(struct net_if *iface, const struct net_in_addr *addr);
2504 
2505 /**
2506  * @brief Go through all IPv4 multicast addresses on a network interface and call
2507  * callback for each used address.
2508  *
2509  * @param iface Pointer to the network interface
2510  * @param cb User-supplied callback function to call
2511  * @param user_data User specified data
2512  */
2513 void net_if_ipv4_maddr_foreach(struct net_if *iface, net_if_ip_maddr_cb_t cb,
2514 			       void *user_data);
2515 
2516 /**
2517  * @brief Check if this IPv4 multicast address belongs to a specific interface
2518  * or one of the interfaces.
2519  *
2520  * @param addr IPv4 address
2521  * @param iface If *iface is null, then pointer to interface is returned,
2522  * otherwise the *iface value needs to be matched.
2523  *
2524  * @return Pointer to interface multicast address, NULL if not found.
2525  */
2526 struct net_if_mcast_addr *net_if_ipv4_maddr_lookup(const struct net_in_addr *addr,
2527 						   struct net_if **iface);
2528 
2529 /**
2530  * @brief Mark a given multicast address to be joined.
2531  *
2532  * @param iface Network interface the address belongs to
2533  * @param addr IPv4 multicast address
2534  */
2535 void net_if_ipv4_maddr_join(struct net_if *iface,
2536 			    struct net_if_mcast_addr *addr);
2537 
2538 /**
2539  * @brief Check if given multicast address is joined or not.
2540  *
2541  * @param addr IPv4 multicast address
2542  *
2543  * @return True if address is joined, False otherwise.
2544  */
net_if_ipv4_maddr_is_joined(struct net_if_mcast_addr * addr)2545 static inline bool net_if_ipv4_maddr_is_joined(struct net_if_mcast_addr *addr)
2546 {
2547 	if (addr == NULL) {
2548 		return false;
2549 	}
2550 
2551 	return addr->is_joined;
2552 }
2553 
2554 /**
2555  * @brief Mark a given multicast address to be left.
2556  *
2557  * @param iface Network interface the address belongs to
2558  * @param addr IPv4 multicast address
2559  */
2560 void net_if_ipv4_maddr_leave(struct net_if *iface,
2561 			     struct net_if_mcast_addr *addr);
2562 
2563 /**
2564  * @brief Get the IPv4 address of the given router
2565  * @param router a network router
2566  *
2567  * @return pointer to the IPv4 address, or NULL if none
2568  */
2569 #if defined(CONFIG_NET_NATIVE_IPV4)
net_if_router_ipv4(struct net_if_router * router)2570 static inline struct net_in_addr *net_if_router_ipv4(struct net_if_router *router)
2571 {
2572 	if (router == NULL) {
2573 		return NULL;
2574 	}
2575 
2576 	return &router->address.in_addr;
2577 }
2578 #else
net_if_router_ipv4(struct net_if_router * router)2579 static inline struct net_in_addr *net_if_router_ipv4(struct net_if_router *router)
2580 {
2581 	static struct net_in_addr addr;
2582 
2583 	ARG_UNUSED(router);
2584 
2585 	return &addr;
2586 }
2587 #endif
2588 
2589 /**
2590  * @brief Check if IPv4 address is one of the routers configured
2591  * in the system.
2592  *
2593  * @param iface Network interface
2594  * @param addr IPv4 address
2595  *
2596  * @return Pointer to router information, NULL if cannot be found
2597  */
2598 struct net_if_router *net_if_ipv4_router_lookup(struct net_if *iface,
2599 						const struct net_in_addr *addr);
2600 
2601 /**
2602  * @brief Find default router for this IPv4 address.
2603  *
2604  * @param iface Network interface. This can be NULL in which case we
2605  * go through all the network interfaces to find a suitable router.
2606  * @param addr IPv4 address
2607  *
2608  * @return Pointer to router information, NULL if cannot be found
2609  */
2610 struct net_if_router *net_if_ipv4_router_find_default(struct net_if *iface,
2611 						      const struct net_in_addr *addr);
2612 /**
2613  * @brief Add IPv4 router to the system.
2614  *
2615  * @param iface Network interface
2616  * @param addr IPv4 address
2617  * @param is_default Is this router the default one
2618  * @param router_lifetime Lifetime of the router
2619  *
2620  * @return Pointer to router information, NULL if could not be added
2621  */
2622 struct net_if_router *net_if_ipv4_router_add(struct net_if *iface,
2623 					     const struct net_in_addr *addr,
2624 					     bool is_default,
2625 					     uint16_t router_lifetime);
2626 
2627 /**
2628  * @brief Remove IPv4 router from the system.
2629  *
2630  * @param router Router information.
2631  *
2632  * @return True if successfully removed, false otherwise
2633  */
2634 bool net_if_ipv4_router_rm(struct net_if_router *router);
2635 
2636 /**
2637  * @brief Check if the given IPv4 address belongs to local subnet.
2638  *
2639  * @param iface Interface to use. Must be a valid pointer to an interface.
2640  * @param addr IPv4 address
2641  *
2642  * @return True if address is part of local subnet, false otherwise.
2643  */
2644 bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
2645 			       const struct net_in_addr *addr);
2646 
2647 /**
2648  * @brief Check if the given IPv4 address is a broadcast address.
2649  *
2650  * @param iface Interface to use. Must be a valid pointer to an interface.
2651  * @param addr IPv4 address, this should be in network byte order
2652  *
2653  * @return True if address is a broadcast address, false otherwise.
2654  */
2655 bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
2656 			       const struct net_in_addr *addr);
2657 
2658 /**
2659  * @brief Get a network interface that should be used when sending
2660  * IPv4 network data to destination.
2661  *
2662  * @param dst IPv4 destination address
2663  *
2664  * @return Pointer to network interface to use, NULL if no suitable interface
2665  * could be found.
2666  */
2667 #if defined(CONFIG_NET_IPV4)
2668 struct net_if *net_if_ipv4_select_src_iface(const struct net_in_addr *dst);
2669 #else
net_if_ipv4_select_src_iface(const struct net_in_addr * dst)2670 static inline struct net_if *net_if_ipv4_select_src_iface(
2671 	const struct net_in_addr *dst)
2672 {
2673 	ARG_UNUSED(dst);
2674 
2675 	return NULL;
2676 }
2677 #endif
2678 
2679 /**
2680  * @brief Get a network interface that should be used when sending
2681  * IPv4 network data to destination. Also return the source IPv4 address from
2682  * that network interface.
2683  *
2684  * @param dst IPv4 destination address
2685  * @param src_addr IPv4 source address. This can be set to NULL if the source
2686  *                 address is not needed.
2687  *
2688  * @return Pointer to network interface to use, NULL if no suitable interface
2689  * could be found.
2690  */
2691 #if defined(CONFIG_NET_IPV4)
2692 struct net_if *net_if_ipv4_select_src_iface_addr(const struct net_in_addr *dst,
2693 						 const struct net_in_addr **src_addr);
2694 #else
net_if_ipv4_select_src_iface_addr(const struct net_in_addr * dst,const struct net_in_addr ** src_addr)2695 static inline struct net_if *net_if_ipv4_select_src_iface_addr(
2696 	const struct net_in_addr *dst, const struct net_in_addr **src_addr)
2697 {
2698 	ARG_UNUSED(dst);
2699 	ARG_UNUSED(src_addr);
2700 
2701 	return NULL;
2702 }
2703 #endif /* CONFIG_NET_IPV4 */
2704 
2705 /**
2706  * @brief Get a IPv4 source address that should be used when sending
2707  * network data to destination.
2708  *
2709  * @param iface Interface to use when sending the packet.
2710  * If the interface is not known, then NULL can be given.
2711  * @param dst IPv4 destination address
2712  *
2713  * @return Pointer to IPv4 address to use, NULL if no IPv4 address
2714  * could be found.
2715  */
2716 #if defined(CONFIG_NET_IPV4)
2717 const struct net_in_addr *net_if_ipv4_select_src_addr(struct net_if *iface,
2718 						  const struct net_in_addr *dst);
2719 #else
net_if_ipv4_select_src_addr(struct net_if * iface,const struct net_in_addr * dst)2720 static inline const struct net_in_addr *net_if_ipv4_select_src_addr(
2721 	struct net_if *iface, const struct net_in_addr *dst)
2722 {
2723 	ARG_UNUSED(iface);
2724 	ARG_UNUSED(dst);
2725 
2726 	return NULL;
2727 }
2728 #endif
2729 
2730 /**
2731  * @brief Get a IPv4 link local address in a given state.
2732  *
2733  * @param iface Interface to use. Must be a valid pointer to an interface.
2734  * @param addr_state IPv4 address state (preferred, tentative, deprecated)
2735  *
2736  * @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
2737  * could be found.
2738  */
2739 struct net_in_addr *net_if_ipv4_get_ll(struct net_if *iface,
2740 				   enum net_addr_state addr_state);
2741 
2742 /**
2743  * @brief Get a IPv4 global address in a given state.
2744  *
2745  * @param iface Interface to use. Must be a valid pointer to an interface.
2746  * @param addr_state IPv4 address state (preferred, tentative, deprecated)
2747  *
2748  * @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
2749  * could be found.
2750  */
2751 struct net_in_addr *net_if_ipv4_get_global_addr(struct net_if *iface,
2752 					    enum net_addr_state addr_state);
2753 
2754 /**
2755  * @brief Get IPv4 netmask related to an address of an interface.
2756  *
2757  * @param iface Interface to use.
2758  * @param addr IPv4 address to check.
2759  *
2760  * @return The netmask set on the interface related to the give address,
2761  *         unspecified address if not found.
2762  */
2763 struct net_in_addr net_if_ipv4_get_netmask_by_addr(struct net_if *iface,
2764 					       const struct net_in_addr *addr);
2765 
2766 /**
2767  * @brief Get IPv4 netmask of an interface.
2768  *
2769  * @deprecated Use net_if_ipv4_get_netmask_by_addr() instead.
2770  *
2771  * @param iface Interface to use.
2772  *
2773  * @return The netmask set on the interface, unspecified address if not found.
2774  */
2775 __deprecated struct net_in_addr net_if_ipv4_get_netmask(struct net_if *iface);
2776 
2777 /**
2778  * @brief Set IPv4 netmask for an interface.
2779  *
2780  * @deprecated Use net_if_ipv4_set_netmask_by_addr() instead.
2781  *
2782  * @param iface Interface to use.
2783  * @param netmask IPv4 netmask
2784  */
2785 __deprecated void net_if_ipv4_set_netmask(struct net_if *iface,
2786 					  const struct net_in_addr *netmask);
2787 
2788 /**
2789  * @brief Set IPv4 netmask for an interface index.
2790  *
2791  * @deprecated Use net_if_ipv4_set_netmask_by_addr() instead.
2792  *
2793  * @param index Network interface index
2794  * @param netmask IPv4 netmask
2795  *
2796  * @return True if netmask was added, false otherwise.
2797  */
2798 __deprecated __syscall bool net_if_ipv4_set_netmask_by_index(int index,
2799 							     const struct net_in_addr *netmask);
2800 
2801 /**
2802  * @brief Set IPv4 netmask for an interface index for a given address.
2803  *
2804  * @param index Network interface index
2805  * @param addr IPv4 address related to this netmask
2806  * @param netmask IPv4 netmask
2807  *
2808  * @return True if netmask was added, false otherwise.
2809  */
2810 __syscall bool net_if_ipv4_set_netmask_by_addr_by_index(int index,
2811 							const struct net_in_addr *addr,
2812 							const struct net_in_addr *netmask);
2813 
2814 /**
2815  * @brief Set IPv4 netmask for an interface index for a given address.
2816  *
2817  * @param iface Network interface
2818  * @param addr IPv4 address related to this netmask
2819  * @param netmask IPv4 netmask
2820  *
2821  * @return True if netmask was added, false otherwise.
2822  */
2823 bool net_if_ipv4_set_netmask_by_addr(struct net_if *iface,
2824 				     const struct net_in_addr *addr,
2825 				     const struct net_in_addr *netmask);
2826 
2827 /**
2828  * @brief Get IPv4 gateway of an interface.
2829  *
2830  * @param iface Interface to use.
2831  *
2832  * @return The gateway set on the interface, unspecified address if not found.
2833  */
2834 struct net_in_addr net_if_ipv4_get_gw(struct net_if *iface);
2835 
2836 /**
2837  * @brief Set IPv4 gateway for an interface.
2838  *
2839  * @param iface Interface to use.
2840  * @param gw IPv4 address of an gateway
2841  */
2842 void net_if_ipv4_set_gw(struct net_if *iface, const struct net_in_addr *gw);
2843 
2844 /**
2845  * @brief Set IPv4 gateway for an interface index.
2846  *
2847  * @param index Network interface index
2848  * @param gw IPv4 address of an gateway
2849  *
2850  * @return True if gateway was added, false otherwise.
2851  */
2852 __syscall bool net_if_ipv4_set_gw_by_index(int index, const struct net_in_addr *gw);
2853 
2854 /**
2855  * @brief Get a network interface that should be used when sending
2856  * IPv6 or IPv4 network data to destination.
2857  *
2858  * @param dst IPv6 or IPv4 destination address
2859  *
2860  * @return Pointer to network interface to use. Note that the function
2861  * will return the default network interface if the best network interface
2862  * is not found.
2863  */
2864 struct net_if *net_if_select_src_iface(const struct net_sockaddr *dst);
2865 
2866 /**
2867  * @typedef net_if_link_callback_t
2868  * @brief Define callback that is called after a network packet
2869  *        has been sent.
2870  * @param iface A pointer to a struct net_if to which the net_pkt was sent to.
2871  * @param dst Link layer address of the destination where the network packet was sent.
2872  * @param status Send status, 0 is ok, < 0 error.
2873  */
2874 typedef void (*net_if_link_callback_t)(struct net_if *iface,
2875 				       struct net_linkaddr *dst,
2876 				       int status);
2877 
2878 /**
2879  * @brief Link callback handler struct.
2880  *
2881  * Stores the link callback information. Caller must make sure that
2882  * the variable pointed by this is valid during the lifetime of
2883  * registration. Typically this means that the variable cannot be
2884  * allocated from stack.
2885  */
2886 struct net_if_link_cb {
2887 	/** Node information for the slist. */
2888 	sys_snode_t node;
2889 
2890 	/** Link callback */
2891 	net_if_link_callback_t cb;
2892 };
2893 
2894 /**
2895  * @brief Register a link callback.
2896  *
2897  * @param link Caller specified handler for the callback.
2898  * @param cb Callback to register.
2899  */
2900 void net_if_register_link_cb(struct net_if_link_cb *link,
2901 			     net_if_link_callback_t cb);
2902 
2903 /**
2904  * @brief Unregister a link callback.
2905  *
2906  * @param link Caller specified handler for the callback.
2907  */
2908 void net_if_unregister_link_cb(struct net_if_link_cb *link);
2909 
2910 /**
2911  * @brief Call a link callback function.
2912  *
2913  * @param iface Network interface.
2914  * @param lladdr Destination link layer address
2915  * @param status 0 is ok, < 0 error
2916  */
2917 void net_if_call_link_cb(struct net_if *iface, struct net_linkaddr *lladdr,
2918 			 int status);
2919 
2920 /** @cond INTERNAL_HIDDEN */
2921 
2922 /* used to ensure encoding of checksum support in net_if.h and
2923  * ethernet.h is the same
2924  */
2925 #define NET_IF_CHECKSUM_NONE_BIT			0
2926 #define NET_IF_CHECKSUM_IPV4_HEADER_BIT			BIT(0)
2927 #define NET_IF_CHECKSUM_IPV4_ICMP_BIT			BIT(1)
2928 /* Space for future protocols and restrictions for IPV4 */
2929 #define NET_IF_CHECKSUM_IPV6_HEADER_BIT			BIT(10)
2930 #define NET_IF_CHECKSUM_IPV6_ICMP_BIT			BIT(11)
2931 /* Space for future protocols and restrictions for IPV6 */
2932 #define NET_IF_CHECKSUM_TCP_BIT				BIT(21)
2933 #define NET_IF_CHECKSUM_UDP_BIT				BIT(22)
2934 
2935 /** @endcond */
2936 
2937 /**
2938  * @brief Type of checksum for which support in the interface will be queried.
2939  */
2940 enum net_if_checksum_type {
2941 	/** Interface supports IP version 4 header checksum calculation */
2942 	NET_IF_CHECKSUM_IPV4_HEADER = NET_IF_CHECKSUM_IPV4_HEADER_BIT,
2943 	/** Interface supports checksum calculation for TCP payload in IPv4 */
2944 	NET_IF_CHECKSUM_IPV4_TCP    = NET_IF_CHECKSUM_IPV4_HEADER_BIT |
2945 				      NET_IF_CHECKSUM_TCP_BIT,
2946 	/** Interface supports checksum calculation for UDP payload in IPv4 */
2947 	NET_IF_CHECKSUM_IPV4_UDP    = NET_IF_CHECKSUM_IPV4_HEADER_BIT |
2948 				      NET_IF_CHECKSUM_UDP_BIT,
2949 	/** Interface supports checksum calculation for ICMP4 payload in IPv4 */
2950 	NET_IF_CHECKSUM_IPV4_ICMP   = NET_IF_CHECKSUM_IPV4_ICMP_BIT,
2951 	/** Interface supports IP version 6 header checksum calculation */
2952 	NET_IF_CHECKSUM_IPV6_HEADER = NET_IF_CHECKSUM_IPV6_HEADER_BIT,
2953 	/** Interface supports checksum calculation for TCP payload in IPv6 */
2954 	NET_IF_CHECKSUM_IPV6_TCP    = NET_IF_CHECKSUM_IPV6_HEADER_BIT |
2955 				      NET_IF_CHECKSUM_TCP_BIT,
2956 	/** Interface supports checksum calculation for UDP payload in IPv6 */
2957 	NET_IF_CHECKSUM_IPV6_UDP    = NET_IF_CHECKSUM_IPV6_HEADER_BIT |
2958 				      NET_IF_CHECKSUM_UDP_BIT,
2959 	/** Interface supports checksum calculation for ICMP6 payload in IPv6 */
2960 	NET_IF_CHECKSUM_IPV6_ICMP   = NET_IF_CHECKSUM_IPV6_ICMP_BIT
2961 };
2962 
2963 /**
2964  * @brief Check if received network packet checksum calculation can be avoided
2965  * or not. For example many ethernet devices support network packet offloading
2966  * in which case the IP stack does not need to calculate the checksum.
2967  *
2968  * @param iface Network interface
2969  * @param chksum_type L3 and/or L4 protocol for which to compute checksum
2970  *
2971  * @return True if checksum needs to be calculated, false otherwise.
2972  */
2973 bool net_if_need_calc_rx_checksum(struct net_if *iface,
2974 				  enum net_if_checksum_type chksum_type);
2975 
2976 /**
2977  * @brief Check if network packet checksum calculation can be avoided or not
2978  * when sending the packet. For example many ethernet devices support network
2979  * packet offloading in which case the IP stack does not need to calculate the
2980  * checksum.
2981  *
2982  * @param iface Network interface
2983  * @param chksum_type L3 and/or L4 protocol for which to compute checksum
2984  *
2985  * @return True if checksum needs to be calculated, false otherwise.
2986  */
2987 bool net_if_need_calc_tx_checksum(struct net_if *iface,
2988 				  enum net_if_checksum_type chksum_type);
2989 
2990 /**
2991  * @brief Get interface according to index
2992  *
2993  * @details This is a syscall only to provide access to the object for purposes
2994  *          of assigning permissions.
2995  *
2996  * @param index Interface index
2997  *
2998  * @return Pointer to interface or NULL if not found.
2999  */
3000 __syscall struct net_if *net_if_get_by_index(int index);
3001 
3002 /**
3003  * @brief Get interface index according to pointer
3004  *
3005  * @param iface Pointer to network interface
3006  *
3007  * @return Interface index
3008  */
3009 int net_if_get_by_iface(struct net_if *iface);
3010 
3011 /**
3012  * @typedef net_if_cb_t
3013  * @brief Callback used while iterating over network interfaces
3014  *
3015  * @param iface Pointer to current network interface
3016  * @param user_data A valid pointer to user data or NULL
3017  */
3018 typedef void (*net_if_cb_t)(struct net_if *iface, void *user_data);
3019 
3020 /**
3021  * @brief Go through all the network interfaces and call callback
3022  * for each interface.
3023  *
3024  * @param cb User-supplied callback function to call
3025  * @param user_data User specified data
3026  */
3027 void net_if_foreach(net_if_cb_t cb, void *user_data);
3028 
3029 /**
3030  * @brief Bring interface up
3031  *
3032  * @param iface Pointer to network interface
3033  *
3034  * @return 0 on success
3035  */
3036 int net_if_up(struct net_if *iface);
3037 
3038 /**
3039  * @brief Check if interface is up and running.
3040  *
3041  * @param iface Pointer to network interface
3042  *
3043  * @return True if interface is up, False if it is down.
3044  */
net_if_is_up(struct net_if * iface)3045 static inline bool net_if_is_up(struct net_if *iface)
3046 {
3047 	if (iface == NULL) {
3048 		return false;
3049 	}
3050 
3051 	return net_if_flag_is_set(iface, NET_IF_UP) &&
3052 	       net_if_flag_is_set(iface, NET_IF_RUNNING);
3053 }
3054 
3055 /**
3056  * @brief Bring interface down
3057  *
3058  * @param iface Pointer to network interface
3059  *
3060  * @return 0 on success
3061  */
3062 int net_if_down(struct net_if *iface);
3063 
3064 /**
3065  * @brief Check if interface was brought up by the administrator.
3066  *
3067  * @param iface Pointer to network interface
3068  *
3069  * @return True if interface is admin up, false otherwise.
3070  */
net_if_is_admin_up(struct net_if * iface)3071 static inline bool net_if_is_admin_up(struct net_if *iface)
3072 {
3073 	if (iface == NULL) {
3074 		return false;
3075 	}
3076 
3077 	return net_if_flag_is_set(iface, NET_IF_UP);
3078 }
3079 
3080 /**
3081  * @brief Underlying network device has detected the carrier (cable connected).
3082  *
3083  * @details The function should be used by the respective network device driver
3084  *          or L2 implementation to update its state on a network interface.
3085  *
3086  * @param iface Pointer to network interface
3087  */
3088 void net_if_carrier_on(struct net_if *iface);
3089 
3090 /**
3091  * @brief Underlying network device has lost the carrier (cable disconnected).
3092  *
3093  * @details The function should be used by the respective network device driver
3094  *          or L2 implementation to update its state on a network interface.
3095  *
3096  * @param iface Pointer to network interface
3097  */
3098 void net_if_carrier_off(struct net_if *iface);
3099 
3100 /**
3101  * @brief Check if carrier is present on network device.
3102  *
3103  * @param iface Pointer to network interface
3104  *
3105  * @return True if carrier is present, false otherwise.
3106  */
net_if_is_carrier_ok(struct net_if * iface)3107 static inline bool net_if_is_carrier_ok(struct net_if *iface)
3108 {
3109 	if (iface == NULL) {
3110 		return false;
3111 	}
3112 
3113 	return net_if_flag_is_set(iface, NET_IF_LOWER_UP);
3114 }
3115 
3116 /**
3117  * @brief Mark interface as dormant. Dormant state indicates that the interface
3118  *        is not ready to pass packets yet, but is waiting for some event
3119  *        (for example Wi-Fi network association).
3120  *
3121  * @details The function should be used by the respective network device driver
3122  *          or L2 implementation to update its state on a network interface.
3123  *
3124  * @param iface Pointer to network interface
3125  */
3126 void net_if_dormant_on(struct net_if *iface);
3127 
3128 /**
3129  * @brief Mark interface as not dormant.
3130  *
3131  * @details The function should be used by the respective network device driver
3132  *          or L2 implementation to update its state on a network interface.
3133  *
3134  * @param iface Pointer to network interface
3135  */
3136 void net_if_dormant_off(struct net_if *iface);
3137 
3138 /**
3139  * @brief Check if the interface is dormant.
3140  *
3141  * @param iface Pointer to network interface
3142  *
3143  * @return True if interface is dormant, false otherwise.
3144  */
net_if_is_dormant(struct net_if * iface)3145 static inline bool net_if_is_dormant(struct net_if *iface)
3146 {
3147 	if (iface == NULL) {
3148 		return false;
3149 	}
3150 
3151 	return net_if_flag_is_set(iface, NET_IF_DORMANT);
3152 }
3153 
3154 #if defined(CONFIG_NET_PKT_TIMESTAMP_THREAD) || defined(__DOXYGEN__)
3155 /**
3156  * @typedef net_if_timestamp_callback_t
3157  * @brief Define callback that is called after a network packet
3158  *        has been timestamped.
3159  * @param pkt A pointer on a struct net_pkt which has
3160  *        been timestamped after being sent.
3161  */
3162 typedef void (*net_if_timestamp_callback_t)(struct net_pkt *pkt);
3163 
3164 /**
3165  * @brief Timestamp callback handler struct.
3166  *
3167  * Stores the timestamp callback information. Caller must make sure that
3168  * the variable pointed by this is valid during the lifetime of
3169  * registration. Typically this means that the variable cannot be
3170  * allocated from stack.
3171  */
3172 struct net_if_timestamp_cb {
3173 	/** Node information for the slist. */
3174 	sys_snode_t node;
3175 
3176 	/** Packet for which the callback is needed.
3177 	 *  A NULL value means all packets.
3178 	 */
3179 	struct net_pkt *pkt;
3180 
3181 	/** Net interface for which the callback is needed.
3182 	 *  A NULL value means all interfaces.
3183 	 */
3184 	struct net_if *iface;
3185 
3186 	/** Timestamp callback */
3187 	net_if_timestamp_callback_t cb;
3188 };
3189 
3190 /**
3191  * @brief Register a timestamp callback.
3192  *
3193  * @param handle Caller specified handler for the callback.
3194  * @param pkt Net packet for which the callback is registered. NULL for all
3195  * 	      packets.
3196  * @param iface Net interface for which the callback is. NULL for all
3197  *		interfaces.
3198  * @param cb Callback to register.
3199  */
3200 void net_if_register_timestamp_cb(struct net_if_timestamp_cb *handle,
3201 				  struct net_pkt *pkt,
3202 				  struct net_if *iface,
3203 				  net_if_timestamp_callback_t cb);
3204 
3205 /**
3206  * @brief Unregister a timestamp callback.
3207  *
3208  * @param handle Caller specified handler for the callback.
3209  */
3210 void net_if_unregister_timestamp_cb(struct net_if_timestamp_cb *handle);
3211 
3212 /**
3213  * @brief Call a timestamp callback function.
3214  *
3215  * @param pkt Network buffer.
3216  */
3217 void net_if_call_timestamp_cb(struct net_pkt *pkt);
3218 
3219 /*
3220  * @brief Add timestamped TX buffer to be handled
3221  *
3222  * @param pkt Timestamped buffer
3223  */
3224 void net_if_add_tx_timestamp(struct net_pkt *pkt);
3225 #endif /* CONFIG_NET_PKT_TIMESTAMP_THREAD */
3226 
3227 /**
3228  * @brief Set network interface into promiscuous mode
3229  *
3230  * @details Note that not all network technologies will support this.
3231  *
3232  * @param iface Pointer to network interface
3233  *
3234  * @return 0 on success, <0 if error
3235  */
3236 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
3237 int net_if_set_promisc(struct net_if *iface);
3238 #else
net_if_set_promisc(struct net_if * iface)3239 static inline int net_if_set_promisc(struct net_if *iface)
3240 {
3241 	ARG_UNUSED(iface);
3242 
3243 	return -ENOTSUP;
3244 }
3245 #endif
3246 
3247 /**
3248  * @brief Set network interface into normal mode
3249  *
3250  * @param iface Pointer to network interface
3251  */
3252 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
3253 void net_if_unset_promisc(struct net_if *iface);
3254 #else
net_if_unset_promisc(struct net_if * iface)3255 static inline void net_if_unset_promisc(struct net_if *iface)
3256 {
3257 	ARG_UNUSED(iface);
3258 }
3259 #endif
3260 
3261 /**
3262  * @brief Check if promiscuous mode is set or not.
3263  *
3264  * @param iface Pointer to network interface
3265  *
3266  * @return True if interface is in promisc mode,
3267  *         False if interface is not in promiscuous mode.
3268  */
3269 #if defined(CONFIG_NET_PROMISCUOUS_MODE)
3270 bool net_if_is_promisc(struct net_if *iface);
3271 #else
net_if_is_promisc(struct net_if * iface)3272 static inline bool net_if_is_promisc(struct net_if *iface)
3273 {
3274 	ARG_UNUSED(iface);
3275 
3276 	return false;
3277 }
3278 #endif
3279 
3280 /**
3281  * @brief Check if there are any pending TX network data for a given network
3282  *        interface.
3283  *
3284  * @param iface Pointer to network interface
3285  *
3286  * @return True if there are pending TX network packets for this network
3287  *         interface, False otherwise.
3288  */
net_if_are_pending_tx_packets(struct net_if * iface)3289 static inline bool net_if_are_pending_tx_packets(struct net_if *iface)
3290 {
3291 #if defined(CONFIG_NET_POWER_MANAGEMENT)
3292 	return !!iface->tx_pending;
3293 #else
3294 	ARG_UNUSED(iface);
3295 
3296 	return false;
3297 #endif
3298 }
3299 
3300 #ifdef CONFIG_NET_POWER_MANAGEMENT
3301 /**
3302  * @brief Suspend a network interface from a power management perspective
3303  *
3304  * @param iface Pointer to network interface
3305  *
3306  * @return 0 on success, or -EALREADY/-EBUSY as possible errors.
3307  */
3308 int net_if_suspend(struct net_if *iface);
3309 
3310 /**
3311  * @brief Resume a network interface from a power management perspective
3312  *
3313  * @param iface Pointer to network interface
3314  *
3315  * @return 0 on success, or -EALREADY as a possible error.
3316  */
3317 int net_if_resume(struct net_if *iface);
3318 
3319 /**
3320  * @brief Check if the network interface is suspended or not.
3321  *
3322  * @param iface Pointer to network interface
3323  *
3324  * @return True if interface is suspended, False otherwise.
3325  */
3326 bool net_if_is_suspended(struct net_if *iface);
3327 #endif /* CONFIG_NET_POWER_MANAGEMENT */
3328 
3329 /**
3330  * @brief Check if the network interface supports Wi-Fi.
3331  *
3332  * @param iface Pointer to network interface
3333  *
3334  * @return True if interface supports Wi-Fi, False otherwise.
3335  */
3336 bool net_if_is_wifi(struct net_if *iface);
3337 
3338 /**
3339  * @brief Get first Wi-Fi network interface.
3340  *
3341  * @return Pointer to network interface, NULL if not found.
3342  */
3343 struct net_if *net_if_get_first_wifi(void);
3344 
3345 /**
3346  * @brief Get Wi-Fi network station interface.
3347  *
3348  * @return Pointer to network interface, NULL if not found.
3349  */
3350 struct net_if *net_if_get_wifi_sta(void);
3351 
3352 /**
3353  * @brief Get first Wi-Fi network Soft-AP interface.
3354  *
3355  * @return Pointer to network interface, NULL if not found.
3356  */
3357 struct net_if *net_if_get_wifi_sap(void);
3358 
3359 /**
3360  * @brief Get network interface name.
3361  *
3362  * @details If interface name support is not enabled, empty string is returned.
3363  *
3364  * @param iface Pointer to network interface
3365  * @param buf User supplied buffer
3366  * @param len Length of the user supplied buffer
3367  *
3368  * @return Length of the interface name copied to buf,
3369  *         -EINVAL if invalid parameters,
3370  *         -ERANGE if name cannot be copied to the user supplied buffer,
3371  *         -ENOTSUP if interface name support is disabled,
3372  */
3373 int net_if_get_name(struct net_if *iface, char *buf, int len);
3374 
3375 /**
3376  * @brief Set network interface name.
3377  *
3378  * @details Normally this function is not needed to call as the system
3379  *          will automatically assign a name to the network interface.
3380  *
3381  * @param iface Pointer to network interface
3382  * @param buf User supplied name
3383  *
3384  * @return 0 name is set correctly
3385  *         -ENOTSUP interface name support is disabled
3386  *         -EINVAL if invalid parameters are given,
3387  *         -ENAMETOOLONG if name is too long
3388  */
3389 int net_if_set_name(struct net_if *iface, const char *buf);
3390 
3391 /**
3392  * @brief Get interface index according to its name
3393  *
3394  * @param name Name of the network interface
3395  *
3396  * @return Interface index
3397  */
3398 int net_if_get_by_name(const char *name);
3399 
3400 /** @cond INTERNAL_HIDDEN */
3401 struct net_if_api {
3402 	void (*init)(struct net_if *iface);
3403 };
3404 
3405 #define NET_IF_DHCPV4_INIT						\
3406 	IF_ENABLED(UTIL_AND(IS_ENABLED(CONFIG_NET_DHCPV4),		\
3407 			    IS_ENABLED(CONFIG_NET_NATIVE_IPV4)),	\
3408 		   (.dhcpv4.state = NET_DHCPV4_DISABLED,))
3409 
3410 #define NET_IF_DHCPV6_INIT						\
3411 	IF_ENABLED(UTIL_AND(IS_ENABLED(CONFIG_NET_DHCPV6),		\
3412 			    IS_ENABLED(CONFIG_NET_NATIVE_IPV6)),	\
3413 		   (.dhcpv6.state = NET_DHCPV6_DISABLED,))
3414 
3415 #define NET_IF_CONFIG_INIT				\
3416 	.config = {					\
3417 		IF_ENABLED(CONFIG_NET_IP, (.ip = {},))  \
3418 		NET_IF_DHCPV4_INIT			\
3419 		NET_IF_DHCPV6_INIT			\
3420 	}
3421 
3422 #define NET_PROMETHEUS_GET_COLLECTOR_NAME(dev_id, sfx)			\
3423 	net_stats_##dev_id##_##sfx##_collector
3424 #define NET_PROMETHEUS_INIT(dev_id, sfx)				\
3425 	IF_ENABLED(CONFIG_NET_STATISTICS_VIA_PROMETHEUS,		\
3426 		   (.collector = &NET_PROMETHEUS_GET_COLLECTOR_NAME(dev_id, sfx),))
3427 
3428 #define NET_IF_GET_NAME(dev_id, sfx) __net_if_##dev_id##_##sfx
3429 #define NET_IF_DEV_GET_NAME(dev_id, sfx) __net_if_dev_##dev_id##_##sfx
3430 
3431 #define NET_IF_GET(dev_id, sfx)						\
3432 	((struct net_if *)&NET_IF_GET_NAME(dev_id, sfx))
3433 
3434 #if defined(CONFIG_NET_STATISTICS_VIA_PROMETHEUS)
3435 extern int net_stats_prometheus_scrape(struct prometheus_collector *collector,
3436 				       struct prometheus_metric *metric,
3437 				       void *user_data);
3438 #endif /* CONFIG_NET_STATISTICS_VIA_PROMETHEUS */
3439 
3440 #define NET_IF_INIT(dev_id, sfx, _l2, _mtu, _num_configs)		\
3441 	static STRUCT_SECTION_ITERABLE(net_if_dev,			\
3442 				NET_IF_DEV_GET_NAME(dev_id, sfx)) = {	\
3443 		.dev = &(DEVICE_NAME_GET(dev_id)),			\
3444 		.l2 = &(NET_L2_GET_NAME(_l2)),				\
3445 		.l2_data = &(NET_L2_GET_DATA(dev_id, sfx)),		\
3446 		.mtu = _mtu,						\
3447 		.flags = {BIT(NET_IF_LOWER_UP)},			\
3448 	};								\
3449 	static Z_DECL_ALIGN(struct net_if)				\
3450 		       NET_IF_GET_NAME(dev_id, sfx)[_num_configs]	\
3451 		       __used __noasan __in_section(_net_if, static,	\
3452 					   dev_id) = {			\
3453 		[0 ... (_num_configs - 1)] = {				\
3454 			.if_dev = &(NET_IF_DEV_GET_NAME(dev_id, sfx)),	\
3455 			NET_IF_CONFIG_INIT				\
3456 		}							\
3457 	};								\
3458 	IF_ENABLED(CONFIG_NET_STATISTICS_VIA_PROMETHEUS,		\
3459 		   (static PROMETHEUS_COLLECTOR_DEFINE(			\
3460 			   NET_PROMETHEUS_GET_COLLECTOR_NAME(dev_id,	\
3461 							     sfx),	\
3462 			   net_stats_prometheus_scrape,			\
3463 			   NET_IF_GET(dev_id, sfx));			\
3464 		    NET_STATS_PROMETHEUS(NET_IF_GET(dev_id, sfx),	\
3465 					 dev_id, sfx);))
3466 
3467 #define NET_IF_OFFLOAD_INIT(dev_id, sfx, _mtu)				\
3468 	static STRUCT_SECTION_ITERABLE(net_if_dev,			\
3469 				NET_IF_DEV_GET_NAME(dev_id, sfx)) = {	\
3470 		.dev = &(DEVICE_NAME_GET(dev_id)),			\
3471 		.mtu = _mtu,						\
3472 		.l2 = &(NET_L2_GET_NAME(OFFLOADED_NETDEV)),		\
3473 		.flags = {BIT(NET_IF_LOWER_UP)},			\
3474 	};								\
3475 	static Z_DECL_ALIGN(struct net_if)				\
3476 		NET_IF_GET_NAME(dev_id, sfx)[NET_IF_MAX_CONFIGS]	\
3477 		       __used __noasan __in_section(_net_if, static,	\
3478 					   dev_id) = {			\
3479 		[0 ... (NET_IF_MAX_CONFIGS - 1)] = {			\
3480 			.if_dev = &(NET_IF_DEV_GET_NAME(dev_id, sfx)),	\
3481 			NET_IF_CONFIG_INIT				\
3482 		}							\
3483 	};								\
3484 	IF_ENABLED(CONFIG_NET_STATISTICS_VIA_PROMETHEUS,		\
3485 		   (static PROMETHEUS_COLLECTOR_DEFINE(			\
3486 			   NET_PROMETHEUS_GET_COLLECTOR_NAME(dev_id,	\
3487 							     sfx),	\
3488 			   net_stats_prometheus_scrape,			\
3489 			   NET_IF_GET(dev_id, sfx));			\
3490 		    NET_STATS_PROMETHEUS(NET_IF_GET(dev_id, sfx),	\
3491 					 dev_id, sfx);))
3492 
3493 
3494 /** @endcond */
3495 
3496 /* Network device initialization macros */
3497 
3498 /**
3499  * @brief Forward declaration of a network interface
3500  *
3501  * Enables to use of `NET_IF_GET` above the instantiation macro.
3502  *
3503  * @param dev_id Device ID provided to `NET_IF_INIT` or `NET_IF_OFFLOAD_INIT`
3504  */
3505 #define NET_IF_DECLARE(dev_id, inst) \
3506 	static struct net_if NET_IF_GET_NAME(dev_id, inst)[NET_IF_MAX_CONFIGS]
3507 
3508 #define Z_NET_DEVICE_INIT_INSTANCE(node_id, dev_id, name, instance,	\
3509 				   init_fn, pm, data, config, prio,	\
3510 				   api, l2, l2_ctx_type, mtu)		\
3511 	Z_DEVICE_STATE_DEFINE(dev_id);					\
3512 	Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, NULL,		\
3513 			Z_DEVICE_DT_FLAGS(node_id), pm, data,		\
3514 			config, POST_KERNEL, prio, api,			\
3515 			&Z_DEVICE_STATE_NAME(dev_id));			\
3516 	NET_L2_DATA_INIT(dev_id, instance, l2_ctx_type);		\
3517 	NET_IF_INIT(dev_id, instance, l2, mtu, NET_IF_MAX_CONFIGS)
3518 
3519 #define Z_NET_DEVICE_INIT(node_id, dev_id, name, init_fn, pm, data,	\
3520 			  config, prio, api, l2, l2_ctx_type, mtu)	\
3521 	Z_NET_DEVICE_INIT_INSTANCE(node_id, dev_id, name, 0, init_fn,	\
3522 				   pm, data, config, prio, api, l2,	\
3523 				   l2_ctx_type, mtu)
3524 
3525 /**
3526  * @brief Create a network interface and bind it to network device.
3527  *
3528  * @param dev_id Network device id.
3529  * @param name The name this instance of the driver exposes to
3530  * the system.
3531  * @param init_fn Address to the init function of the driver.
3532  * @param pm Reference to struct pm_device associated with the device.
3533  * (optional).
3534  * @param data Pointer to the device's private data.
3535  * @param config The address to the structure containing the
3536  * configuration information for this instance of the driver.
3537  * @param prio The initialization level at which configuration occurs.
3538  * @param api Provides an initial pointer to the API function struct
3539  * used by the driver. Can be NULL.
3540  * @param l2 Network L2 layer for this network interface.
3541  * @param l2_ctx_type Type of L2 context data.
3542  * @param mtu Maximum transfer unit in bytes for this network interface.
3543  */
3544 #define NET_DEVICE_INIT(dev_id, name, init_fn, pm, data, config, prio,	\
3545 			api, l2, l2_ctx_type, mtu)			\
3546 	Z_NET_DEVICE_INIT(DT_INVALID_NODE, dev_id, name, init_fn, pm,	\
3547 			  data, config, prio, api, l2, l2_ctx_type, mtu)
3548 
3549 /**
3550  * @brief Like NET_DEVICE_INIT but taking metadata from a devicetree node.
3551  * Create a network interface and bind it to network device.
3552  *
3553  * @param node_id The devicetree node identifier.
3554  * @param init_fn Address to the init function of the driver.
3555  * @param pm Reference to struct pm_device associated with the device.
3556  * (optional).
3557  * @param data Pointer to the device's private data.
3558  * @param config The address to the structure containing the
3559  * configuration information for this instance of the driver.
3560  * @param prio The initialization level at which configuration occurs.
3561  * @param api Provides an initial pointer to the API function struct
3562  * used by the driver. Can be NULL.
3563  * @param l2 Network L2 layer for this network interface.
3564  * @param l2_ctx_type Type of L2 context data.
3565  * @param mtu Maximum transfer unit in bytes for this network interface.
3566  */
3567 #define NET_DEVICE_DT_DEFINE(node_id, init_fn, pm, data,		\
3568 			     config, prio, api, l2, l2_ctx_type, mtu)	\
3569 	Z_NET_DEVICE_INIT(node_id, Z_DEVICE_DT_DEV_ID(node_id),	\
3570 			  DEVICE_DT_NAME(node_id), init_fn, pm, data,	\
3571 			  config, prio, api, l2, l2_ctx_type, mtu)
3572 
3573 /**
3574  * @brief Like NET_DEVICE_DT_DEFINE for an instance of a DT_DRV_COMPAT compatible
3575  *
3576  * @param inst instance number.  This is replaced by
3577  * <tt>DT_DRV_COMPAT(inst)</tt> in the call to NET_DEVICE_DT_DEFINE.
3578  *
3579  * @param ... other parameters as expected by NET_DEVICE_DT_DEFINE.
3580  */
3581 #define NET_DEVICE_DT_INST_DEFINE(inst, ...) \
3582 	NET_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
3583 
3584 /**
3585  * @brief Create multiple network interfaces and bind them to network device.
3586  * If your network device needs more than one instance of a network interface,
3587  * use this macro below and provide a different instance suffix each time
3588  * (0, 1, 2, ... or a, b, c ... whatever works for you)
3589  *
3590  * @param dev_id Network device id.
3591  * @param name The name this instance of the driver exposes to
3592  * the system.
3593  * @param instance Instance identifier.
3594  * @param init_fn Address to the init function of the driver.
3595  * @param pm Reference to struct pm_device associated with the device.
3596  * (optional).
3597  * @param data Pointer to the device's private data.
3598  * @param config The address to the structure containing the
3599  * configuration information for this instance of the driver.
3600  * @param prio The initialization level at which configuration occurs.
3601  * @param api Provides an initial pointer to the API function struct
3602  * used by the driver. Can be NULL.
3603  * @param l2 Network L2 layer for this network interface.
3604  * @param l2_ctx_type Type of L2 context data.
3605  * @param mtu Maximum transfer unit in bytes for this network interface.
3606  */
3607 #define NET_DEVICE_INIT_INSTANCE(dev_id, name, instance, init_fn, pm,	\
3608 				 data, config, prio, api, l2,		\
3609 				 l2_ctx_type, mtu)			\
3610 	Z_NET_DEVICE_INIT_INSTANCE(DT_INVALID_NODE, dev_id, name,	\
3611 				   instance, init_fn, pm, data, config,	\
3612 				   prio, api, l2, l2_ctx_type, mtu)
3613 
3614 /**
3615  * @brief Like NET_DEVICE_OFFLOAD_INIT but taking metadata from a devicetree.
3616  * Create multiple network interfaces and bind them to network device.
3617  * If your network device needs more than one instance of a network interface,
3618  * use this macro below and provide a different instance suffix each time
3619  * (0, 1, 2, ... or a, b, c ... whatever works for you)
3620  *
3621  * @param node_id The devicetree node identifier.
3622  * @param instance Instance identifier.
3623  * @param init_fn Address to the init function of the driver.
3624  * @param pm Reference to struct pm_device associated with the device.
3625  * (optional).
3626  * @param data Pointer to the device's private data.
3627  * @param config The address to the structure containing the
3628  * configuration information for this instance of the driver.
3629  * @param prio The initialization level at which configuration occurs.
3630  * @param api Provides an initial pointer to the API function struct
3631  * used by the driver. Can be NULL.
3632  * @param l2 Network L2 layer for this network interface.
3633  * @param l2_ctx_type Type of L2 context data.
3634  * @param mtu Maximum transfer unit in bytes for this network interface.
3635  */
3636 #define NET_DEVICE_DT_DEFINE_INSTANCE(node_id, instance, init_fn, pm,	\
3637 				      data, config, prio, api, l2,	\
3638 				      l2_ctx_type, mtu)			\
3639 	Z_NET_DEVICE_INIT_INSTANCE(node_id,				\
3640 				   Z_DEVICE_DT_DEV_ID(node_id),		\
3641 				   DEVICE_DT_NAME(node_id), instance,	\
3642 				   init_fn, pm, data, config, prio,	\
3643 				   api,	l2, l2_ctx_type, mtu)
3644 
3645 /**
3646  * @brief Like NET_DEVICE_DT_DEFINE_INSTANCE for an instance of a DT_DRV_COMPAT
3647  * compatible
3648  *
3649  * @param inst instance number.  This is replaced by
3650  * <tt>DT_DRV_COMPAT(inst)</tt> in the call to NET_DEVICE_DT_DEFINE_INSTANCE.
3651  *
3652  * @param ... other parameters as expected by NET_DEVICE_DT_DEFINE_INSTANCE.
3653  */
3654 #define NET_DEVICE_DT_INST_DEFINE_INSTANCE(inst, ...) \
3655 	NET_DEVICE_DT_DEFINE_INSTANCE(DT_DRV_INST(inst), __VA_ARGS__)
3656 
3657 #define Z_NET_DEVICE_OFFLOAD_INIT(node_id, dev_id, name, init_fn, pm,	\
3658 				  data, config, prio, api, mtu)		\
3659 	Z_DEVICE_STATE_DEFINE(dev_id);					\
3660 	Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn,	NULL,		\
3661 			Z_DEVICE_DT_FLAGS(node_id), pm, data,		\
3662 			config, POST_KERNEL, prio, api,			\
3663 			&Z_DEVICE_STATE_NAME(dev_id));			\
3664 	NET_IF_OFFLOAD_INIT(dev_id, 0, mtu)
3665 
3666 /**
3667  * @brief Create a offloaded network interface and bind it to network device.
3668  * The offloaded network interface is implemented by a device vendor HAL or
3669  * similar.
3670  *
3671  * @param dev_id Network device id.
3672  * @param name The name this instance of the driver exposes to
3673  * the system.
3674  * @param init_fn Address to the init function of the driver.
3675  * @param pm Reference to struct pm_device associated with the device.
3676  * (optional).
3677  * @param data Pointer to the device's private data.
3678  * @param config The address to the structure containing the
3679  * configuration information for this instance of the driver.
3680  * @param prio The initialization level at which configuration occurs.
3681  * @param api Provides an initial pointer to the API function struct
3682  * used by the driver. Can be NULL.
3683  * @param mtu Maximum transfer unit in bytes for this network interface.
3684  */
3685 #define NET_DEVICE_OFFLOAD_INIT(dev_id, name, init_fn, pm, data,	\
3686 				config,	prio, api, mtu)			\
3687 	Z_NET_DEVICE_OFFLOAD_INIT(DT_INVALID_NODE, dev_id, name,	\
3688 				  init_fn, pm, data, config, prio, api,	\
3689 				  mtu)
3690 
3691 /**
3692  * @brief Like NET_DEVICE_OFFLOAD_INIT but taking metadata from a devicetree
3693  * node. Create a offloaded network interface and bind it to network device.
3694  * The offloaded network interface is implemented by a device vendor HAL or
3695  * similar.
3696  *
3697  * @param node_id The devicetree node identifier.
3698  * @param init_fn Address to the init function of the driver.
3699  * @param pm Reference to struct pm_device associated with the device.
3700  * (optional).
3701  * @param data Pointer to the device's private data.
3702  * @param config The address to the structure containing the
3703  * configuration information for this instance of the driver.
3704  * @param prio The initialization level at which configuration occurs.
3705  * @param api Provides an initial pointer to the API function struct
3706  * used by the driver. Can be NULL.
3707  * @param mtu Maximum transfer unit in bytes for this network interface.
3708  */
3709 #define NET_DEVICE_DT_OFFLOAD_DEFINE(node_id, init_fn, pm, data,	\
3710 				     config, prio, api, mtu)		\
3711 	Z_NET_DEVICE_OFFLOAD_INIT(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
3712 				  DEVICE_DT_NAME(node_id), init_fn, pm, \
3713 				  data, config,	prio, api, mtu)
3714 
3715 /**
3716  * @brief Like NET_DEVICE_DT_OFFLOAD_DEFINE for an instance of a DT_DRV_COMPAT
3717  * compatible
3718  *
3719  * @param inst instance number.  This is replaced by
3720  * <tt>DT_DRV_COMPAT(inst)</tt> in the call to NET_DEVICE_DT_OFFLOAD_DEFINE.
3721  *
3722  * @param ... other parameters as expected by NET_DEVICE_DT_OFFLOAD_DEFINE.
3723  */
3724 #define NET_DEVICE_DT_INST_OFFLOAD_DEFINE(inst, ...) \
3725 	NET_DEVICE_DT_OFFLOAD_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
3726 
3727 /**
3728  * @brief Count the number of network interfaces.
3729  *
3730  * @param[out] _dst Pointer to location where result is written.
3731  */
3732 #define NET_IFACE_COUNT(_dst) \
3733 		do {							\
3734 			extern struct net_if _net_if_list_start[];	\
3735 			extern struct net_if _net_if_list_end[];	\
3736 			*(_dst) = ((uintptr_t)_net_if_list_end -	\
3737 				   (uintptr_t)_net_if_list_start) /	\
3738 				sizeof(struct net_if);			\
3739 		} while (0)
3740 
3741 #ifdef __cplusplus
3742 }
3743 #endif
3744 
3745 #include <zephyr/syscalls/net_if.h>
3746 
3747 /**
3748  * @}
3749  */
3750 
3751 #endif /* ZEPHYR_INCLUDE_NET_NET_IF_H_ */
3752