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