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