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