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