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