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 * @ingroup networking
19 * @{
20 */
21
22 #include <device.h>
23 #include <sys/slist.h>
24
25 #include <net/net_core.h>
26 #include <net/hostname.h>
27 #include <net/net_linkaddr.h>
28 #include <net/net_ip.h>
29 #include <net/net_l2.h>
30 #include <net/net_stats.h>
31 #include <net/net_timeout.h>
32
33 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
34 #include <net/dhcpv4.h>
35 #endif
36 #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
37 #include <net/ipv4_autoconf.h>
38 #endif
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 /**
45 * @brief Network Interface unicast IP addresses
46 *
47 * Stores the unicast IP addresses assigned to this network interface.
48 */
49 struct net_if_addr {
50 /** IP address */
51 struct net_addr address;
52
53 #if defined(CONFIG_NET_NATIVE_IPV6)
54 struct net_timeout lifetime;
55 #endif
56
57 #if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
58 /** Duplicate address detection (DAD) timer */
59 sys_snode_t dad_node;
60 uint32_t dad_start;
61 #endif
62 /** How the IP address was set */
63 enum net_addr_type addr_type;
64
65 /** What is the current state of the address */
66 enum net_addr_state addr_state;
67
68 #if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
69 /** How many times we have done DAD */
70 uint8_t dad_count;
71 #endif
72
73 /** Is the IP address valid forever */
74 uint8_t is_infinite : 1;
75
76 /** Is this IP address used or not */
77 uint8_t is_used : 1;
78
79 /** Is this IP address usage limited to the subnet (mesh) or not */
80 uint8_t is_mesh_local : 1;
81
82 uint8_t _unused : 5;
83 };
84
85 /**
86 * @brief Network Interface multicast IP addresses
87 *
88 * Stores the multicast IP addresses assigned to this network interface.
89 */
90 struct net_if_mcast_addr {
91 /** IP address */
92 struct net_addr address;
93
94 /** Is this multicast IP address used or not */
95 uint8_t is_used : 1;
96
97 /** Did we join to this group */
98 uint8_t is_joined : 1;
99
100 uint8_t _unused : 6;
101 };
102
103 /**
104 * @brief Network Interface IPv6 prefixes
105 *
106 * Stores the multicast IP addresses assigned to this network interface.
107 */
108 struct net_if_ipv6_prefix {
109 /** Prefix lifetime */
110 struct net_timeout lifetime;
111
112 /** IPv6 prefix */
113 struct in6_addr prefix;
114
115 /** Backpointer to network interface where this prefix is used */
116 struct net_if *iface;
117
118 /** Prefix length */
119 uint8_t len;
120
121 /** Is the IP prefix valid forever */
122 uint8_t is_infinite : 1;
123
124 /** Is this prefix used or not */
125 uint8_t is_used : 1;
126
127 uint8_t _unused : 6;
128 };
129
130 /**
131 * @brief Information about routers in the system.
132 *
133 * Stores the router information.
134 */
135 struct net_if_router {
136 /** Slist lifetime timer node */
137 sys_snode_t node;
138
139 /** IP address */
140 struct net_addr address;
141
142 /** Network interface the router is connected to */
143 struct net_if *iface;
144
145 /** Router life timer start */
146 uint32_t life_start;
147
148 /** Router lifetime */
149 uint16_t lifetime;
150
151 /** Is this router used or not */
152 uint8_t is_used : 1;
153
154 /** Is default router */
155 uint8_t is_default : 1;
156
157 /** Is the router valid forever */
158 uint8_t is_infinite : 1;
159
160 uint8_t _unused : 5;
161 };
162
163 enum net_if_flag {
164 /** Interface is up/ready to receive and transmit */
165 NET_IF_UP,
166
167 /** Interface is pointopoint */
168 NET_IF_POINTOPOINT,
169
170 /** Interface is in promiscuous mode */
171 NET_IF_PROMISC,
172
173 /** Do not start the interface immediately after initialization.
174 * This requires that either the device driver or some other entity
175 * will need to manually take the interface up when needed.
176 * For example for Ethernet this will happen when the driver calls
177 * the net_eth_carrier_on() function.
178 */
179 NET_IF_NO_AUTO_START,
180
181 /** Power management specific: interface is being suspended */
182 NET_IF_SUSPENDED,
183
184 /** Flag defines if received multicasts of other interface are
185 * forwarded on this interface. This activates multicast
186 * routing / forwarding for this interface.
187 */
188 NET_IF_FORWARD_MULTICASTS,
189
190 /** Interface supports IPv4 */
191 NET_IF_IPV4,
192
193 /** Interface supports IPv6 */
194 NET_IF_IPV6,
195
196 /** @cond INTERNAL_HIDDEN */
197 /* Total number of flags - must be at the end of the enum */
198 NET_IF_NUM_FLAGS
199 /** @endcond */
200 };
201
202 #if defined(CONFIG_NET_OFFLOAD)
203 struct net_offload;
204 #endif /* CONFIG_NET_OFFLOAD */
205
206 /** @cond INTERNAL_HIDDEN */
207 #if defined(CONFIG_NET_NATIVE_IPV6)
208 #define NET_IF_MAX_IPV6_ADDR CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT
209 #define NET_IF_MAX_IPV6_MADDR CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT
210 #define NET_IF_MAX_IPV6_PREFIX CONFIG_NET_IF_IPV6_PREFIX_COUNT
211 #else
212 #define NET_IF_MAX_IPV6_ADDR 0
213 #define NET_IF_MAX_IPV6_MADDR 0
214 #define NET_IF_MAX_IPV6_PREFIX 0
215 #endif
216 /* @endcond */
217
218 struct net_if_ipv6 {
219 /** Unicast IP addresses */
220 struct net_if_addr unicast[NET_IF_MAX_IPV6_ADDR];
221
222 /** Multicast IP addresses */
223 struct net_if_mcast_addr mcast[NET_IF_MAX_IPV6_MADDR];
224
225 /** Prefixes */
226 struct net_if_ipv6_prefix prefix[NET_IF_MAX_IPV6_PREFIX];
227
228 /** Default reachable time (RFC 4861, page 52) */
229 uint32_t base_reachable_time;
230
231 /** Reachable time (RFC 4861, page 20) */
232 uint32_t reachable_time;
233
234 /** Retransmit timer (RFC 4861, page 52) */
235 uint32_t retrans_timer;
236 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
237 /** Router solicitation timer node */
238 sys_snode_t rs_node;
239
240 /* RS start time */
241 uint32_t rs_start;
242
243 /** RS count */
244 uint8_t rs_count;
245 #endif
246
247 /** IPv6 hop limit */
248 uint8_t hop_limit;
249 };
250
251 /** @cond INTERNAL_HIDDEN */
252 #if defined(CONFIG_NET_NATIVE_IPV4)
253 #define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT
254 #define NET_IF_MAX_IPV4_MADDR CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT
255 #else
256 #define NET_IF_MAX_IPV4_ADDR 0
257 #define NET_IF_MAX_IPV4_MADDR 0
258 #endif
259 /** @endcond */
260
261 struct net_if_ipv4 {
262 /** Unicast IP addresses */
263 struct net_if_addr unicast[NET_IF_MAX_IPV4_ADDR];
264
265 /** Multicast IP addresses */
266 struct net_if_mcast_addr mcast[NET_IF_MAX_IPV4_MADDR];
267
268 /** Gateway */
269 struct in_addr gw;
270
271 /** Netmask */
272 struct in_addr netmask;
273
274 /** IPv4 time-to-live */
275 uint8_t ttl;
276 };
277
278 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
279 struct net_if_dhcpv4 {
280 /** Used for timer lists */
281 sys_snode_t node;
282
283 /** Timer start */
284 int64_t timer_start;
285
286 /** Time for INIT, DISCOVER, REQUESTING, RENEWAL */
287 uint32_t request_time;
288
289 uint32_t xid;
290
291 /** IP address Lease time */
292 uint32_t lease_time;
293
294 /** IP address Renewal time */
295 uint32_t renewal_time;
296
297 /** IP address Rebinding time */
298 uint32_t rebinding_time;
299
300 /** Server ID */
301 struct in_addr server_id;
302
303 /** Requested IP addr */
304 struct in_addr requested_ip;
305
306 /**
307 * DHCPv4 client state in the process of network
308 * address allocation.
309 */
310 enum net_dhcpv4_state state;
311
312 /** Number of attempts made for REQUEST and RENEWAL messages */
313 uint8_t attempts;
314 };
315 #endif /* CONFIG_NET_DHCPV4 */
316
317 #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
318 struct net_if_ipv4_autoconf {
319 /** Used for timer lists */
320 sys_snode_t node;
321
322 /** Backpointer to correct network interface */
323 struct net_if *iface;
324
325 /** Timer start */
326 int64_t timer_start;
327
328 /** Time for INIT, DISCOVER, REQUESTING, RENEWAL */
329 uint32_t timer_timeout;
330
331 /** Current IP addr */
332 struct in_addr current_ip;
333
334 /** Requested IP addr */
335 struct in_addr requested_ip;
336
337 /** IPV4 Autoconf state in the process of network address allocation.
338 */
339 enum net_ipv4_autoconf_state state;
340
341 /** Number of sent probe requests */
342 uint8_t probe_cnt;
343
344 /** Number of sent announcements */
345 uint8_t announce_cnt;
346
347 /** Incoming conflict count */
348 uint8_t conflict_cnt;
349 };
350 #endif /* CONFIG_NET_IPV4_AUTO */
351
352 /** @cond INTERNAL_HIDDEN */
353 /* We always need to have at least one IP config */
354 #define NET_IF_MAX_CONFIGS 1
355 /** @endcond */
356
357 /**
358 * @brief Network interface IP address configuration.
359 */
360 struct net_if_ip {
361 #if defined(CONFIG_NET_NATIVE_IPV6)
362 struct net_if_ipv6 *ipv6;
363 #endif /* CONFIG_NET_IPV6 */
364
365 #if defined(CONFIG_NET_NATIVE_IPV4)
366 struct net_if_ipv4 *ipv4;
367 #endif /* CONFIG_NET_IPV4 */
368 };
369
370 /**
371 * @brief IP and other configuration related data for network interface.
372 */
373 struct net_if_config {
374 /** IP address configuration setting */
375 struct net_if_ip ip;
376
377 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
378 struct net_if_dhcpv4 dhcpv4;
379 #endif /* CONFIG_NET_DHCPV4 */
380
381 #if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
382 struct net_if_ipv4_autoconf ipv4auto;
383 #endif /* CONFIG_NET_IPV4_AUTO */
384
385 #if defined(CONFIG_NET_L2_VIRTUAL)
386 /**
387 * This list keeps track of the virtual network interfaces
388 * that are attached to this network interface.
389 */
390 sys_slist_t virtual_interfaces;
391 #endif /* CONFIG_NET_L2_VIRTUAL */
392 };
393
394 /**
395 * @brief Network traffic class.
396 *
397 * Traffic classes are used when sending or receiving data that is classified
398 * with different priorities. So some traffic can be marked as high priority
399 * and it will be sent or received first. Each network packet that is
400 * transmitted or received goes through a fifo to a thread that will transmit
401 * it.
402 */
403 struct net_traffic_class {
404 /** Fifo for handling this Tx or Rx packet */
405 struct k_fifo fifo;
406
407 /** Traffic class handler thread */
408 struct k_thread handler;
409
410 /** Stack for this handler */
411 k_thread_stack_t *stack;
412 };
413
414 /**
415 * @brief Network Interface Device structure
416 *
417 * Used to handle a network interface on top of a device driver instance.
418 * There can be many net_if_dev instance against the same device.
419 *
420 * Such interface is mainly to be used by the link layer, but is also tight
421 * to a network context: it then makes the relation with a network context
422 * and the network device.
423 *
424 * Because of the strong relationship between a device driver and such
425 * network interface, each net_if_dev should be instantiated by
426 */
427 struct net_if_dev {
428 /** The actually device driver instance the net_if is related to */
429 const struct device *dev;
430
431 /** Interface's L2 layer */
432 const struct net_l2 * const l2;
433
434 /** Interface's private L2 data pointer */
435 void *l2_data;
436
437 /* For internal use */
438 ATOMIC_DEFINE(flags, NET_IF_NUM_FLAGS);
439
440 /** The hardware link address */
441 struct net_linkaddr link_addr;
442
443 #if defined(CONFIG_NET_OFFLOAD)
444 /** TCP/IP Offload functions.
445 * If non-NULL, then the TCP/IP stack is located
446 * in the communication chip that is accessed via this
447 * network interface.
448 */
449 struct net_offload *offload;
450 #endif /* CONFIG_NET_OFFLOAD */
451
452 /** The hardware MTU */
453 uint16_t mtu;
454
455 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
456 /** Indicate whether interface is offloaded at socket level. */
457 bool offloaded;
458 #endif /* CONFIG_NET_SOCKETS_OFFLOAD */
459 };
460
461 /**
462 * @brief Network Interface structure
463 *
464 * Used to handle a network interface on top of a net_if_dev instance.
465 * There can be many net_if instance against the same net_if_dev instance.
466 *
467 */
468 struct net_if {
469 /** The net_if_dev instance the net_if is related to */
470 struct net_if_dev *if_dev;
471
472 #if defined(CONFIG_NET_STATISTICS_PER_INTERFACE)
473 /** Network statistics related to this network interface */
474 struct net_stats stats;
475 #endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */
476
477 /** Network interface instance configuration */
478 struct net_if_config config;
479
480 #if defined(CONFIG_NET_POWER_MANAGEMENT)
481 /** Keep track of packets pending in traffic queues. This is
482 * needed to avoid putting network device driver to sleep if
483 * there are packets waiting to be sent.
484 */
485 int tx_pending;
486 #endif
487 };
488
489 /**
490 * @brief Set a value in network interface flags
491 *
492 * @param iface Pointer to network interface
493 * @param value Flag value
494 */
net_if_flag_set(struct net_if * iface,enum net_if_flag value)495 static inline void net_if_flag_set(struct net_if *iface,
496 enum net_if_flag value)
497 {
498 NET_ASSERT(iface);
499
500 atomic_set_bit(iface->if_dev->flags, value);
501 }
502
503 /**
504 * @brief Test and set a value in network interface flags
505 *
506 * @param iface Pointer to network interface
507 * @param value Flag value
508 *
509 * @return true if the bit was set, false if it wasn't.
510 */
net_if_flag_test_and_set(struct net_if * iface,enum net_if_flag value)511 static inline bool net_if_flag_test_and_set(struct net_if *iface,
512 enum net_if_flag value)
513 {
514 NET_ASSERT(iface);
515
516 return atomic_test_and_set_bit(iface->if_dev->flags, value);
517 }
518
519 /**
520 * @brief Clear a value in network interface flags
521 *
522 * @param iface Pointer to network interface
523 * @param value Flag value
524 */
net_if_flag_clear(struct net_if * iface,enum net_if_flag value)525 static inline void net_if_flag_clear(struct net_if *iface,
526 enum net_if_flag value)
527 {
528 NET_ASSERT(iface);
529
530 atomic_clear_bit(iface->if_dev->flags, value);
531 }
532
533 /**
534 * @brief Check if a value in network interface flags is set
535 *
536 * @param iface Pointer to network interface
537 * @param value Flag value
538 *
539 * @return True if the value is set, false otherwise
540 */
net_if_flag_is_set(struct net_if * iface,enum net_if_flag value)541 static inline bool net_if_flag_is_set(struct net_if *iface,
542 enum net_if_flag value)
543 {
544 if (iface == NULL) {
545 return false;
546 }
547
548 return atomic_test_bit(iface->if_dev->flags, value);
549 }
550
551 /**
552 * @brief Send a packet through a net iface
553 *
554 * @param iface Pointer to a network interface structure
555 * @param pkt Pointer to a net packet to send
556 *
557 * return verdict about the packet
558 */
559 enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt);
560
561 /**
562 * @brief Get a pointer to the interface L2
563 *
564 * @param iface a valid pointer to a network interface structure
565 *
566 * @return a pointer to the iface L2
567 */
net_if_l2(struct net_if * iface)568 static inline const struct net_l2 * const net_if_l2(struct net_if *iface)
569 {
570 if (!iface || !iface->if_dev) {
571 return NULL;
572 }
573
574 return iface->if_dev->l2;
575 }
576
577 /**
578 * @brief Input a packet through a net iface
579 *
580 * @param iface Pointer to a network interface structure
581 * @param pkt Pointer to a net packet to input
582 *
583 * @return verdict about the packet
584 */
585 enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt);
586
587 /**
588 * @brief Get a pointer to the interface L2 private data
589 *
590 * @param iface a valid pointer to a network interface structure
591 *
592 * @return a pointer to the iface L2 data
593 */
net_if_l2_data(struct net_if * iface)594 static inline void *net_if_l2_data(struct net_if *iface)
595 {
596 return iface->if_dev->l2_data;
597 }
598
599 /**
600 * @brief Get an network interface's device
601 *
602 * @param iface Pointer to a network interface structure
603 *
604 * @return a pointer to the device driver instance
605 */
net_if_get_device(struct net_if * iface)606 static inline const struct device *net_if_get_device(struct net_if *iface)
607 {
608 return iface->if_dev->dev;
609 }
610
611 /**
612 * @brief Queue a packet to the net interface TX queue
613 *
614 * @param iface Pointer to a network interface structure
615 * @param pkt Pointer to a net packet to queue
616 */
617 void net_if_queue_tx(struct net_if *iface, struct net_pkt *pkt);
618
619 /**
620 * @brief Return the IP offload status
621 *
622 * @param iface Network interface
623 *
624 * @return True if IP offlining is active, false otherwise.
625 */
net_if_is_ip_offloaded(struct net_if * iface)626 static inline bool net_if_is_ip_offloaded(struct net_if *iface)
627 {
628 #if defined(CONFIG_NET_OFFLOAD)
629 return (iface->if_dev->offload != NULL);
630 #else
631 ARG_UNUSED(iface);
632
633 return false;
634 #endif
635 }
636
637 /**
638 * @brief Return the IP offload plugin
639 *
640 * @param iface Network interface
641 *
642 * @return NULL if there is no offload plugin defined, valid pointer otherwise
643 */
net_if_offload(struct net_if * iface)644 static inline struct net_offload *net_if_offload(struct net_if *iface)
645 {
646 #if defined(CONFIG_NET_OFFLOAD)
647 return iface->if_dev->offload;
648 #else
649 ARG_UNUSED(iface);
650
651 return NULL;
652 #endif
653 }
654
655 /**
656 * @brief Return the socket offload status
657 *
658 * @param iface Network interface
659 *
660 * @return True if socket offloading is active, false otherwise.
661 */
net_if_is_socket_offloaded(struct net_if * iface)662 static inline bool net_if_is_socket_offloaded(struct net_if *iface)
663 {
664 #if defined(CONFIG_NET_SOCKETS_OFFLOAD)
665 return iface->if_dev->offloaded;
666 #else
667 ARG_UNUSED(iface);
668
669 return false;
670 #endif
671 }
672
673 /**
674 * @brief Get an network interface's link address
675 *
676 * @param iface Pointer to a network interface structure
677 *
678 * @return a pointer to the network link address
679 */
net_if_get_link_addr(struct net_if * iface)680 static inline struct net_linkaddr *net_if_get_link_addr(struct net_if *iface)
681 {
682 return &iface->if_dev->link_addr;
683 }
684
685 /**
686 * @brief Return network configuration for this network interface
687 *
688 * @param iface Pointer to a network interface structure
689 *
690 * @return Pointer to configuration
691 */
net_if_get_config(struct net_if * iface)692 static inline struct net_if_config *net_if_get_config(struct net_if *iface)
693 {
694 return &iface->config;
695 }
696
697 /**
698 * @brief Start duplicate address detection procedure.
699 *
700 * @param iface Pointer to a network interface structure
701 */
702 #if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
703 void net_if_start_dad(struct net_if *iface);
704 #else
net_if_start_dad(struct net_if * iface)705 static inline void net_if_start_dad(struct net_if *iface)
706 {
707 ARG_UNUSED(iface);
708 }
709 #endif
710
711 /**
712 * @brief Start neighbor discovery and send router solicitation message.
713 *
714 * @param iface Pointer to a network interface structure
715 */
716 void net_if_start_rs(struct net_if *iface);
717
718
719 /**
720 * @brief Stop neighbor discovery.
721 *
722 * @param iface Pointer to a network interface structure
723 */
724 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
725 void net_if_stop_rs(struct net_if *iface);
726 #else
net_if_stop_rs(struct net_if * iface)727 static inline void net_if_stop_rs(struct net_if *iface)
728 {
729 ARG_UNUSED(iface);
730 }
731 #endif /* CONFIG_NET_IPV6_ND */
732
733 /** @cond INTERNAL_HIDDEN */
734
net_if_set_link_addr_unlocked(struct net_if * iface,uint8_t * addr,uint8_t len,enum net_link_type type)735 static inline int net_if_set_link_addr_unlocked(struct net_if *iface,
736 uint8_t *addr, uint8_t len,
737 enum net_link_type type)
738 {
739 if (net_if_flag_is_set(iface, NET_IF_UP)) {
740 return -EPERM;
741 }
742
743 net_if_get_link_addr(iface)->addr = addr;
744 net_if_get_link_addr(iface)->len = len;
745 net_if_get_link_addr(iface)->type = type;
746
747 net_hostname_set_postfix(addr, len);
748
749 return 0;
750 }
751
752 int net_if_set_link_addr_locked(struct net_if *iface,
753 uint8_t *addr, uint8_t len,
754 enum net_link_type type);
755 /** @endcond */
756
757 /**
758 * @brief Set a network interface's link address
759 *
760 * @param iface Pointer to a network interface structure
761 * @param addr A pointer to a uint8_t buffer representing the address.
762 * The buffer must remain valid throughout interface lifetime.
763 * @param len length of the address buffer
764 * @param type network bearer type of this link address
765 *
766 * @return 0 on success
767 */
net_if_set_link_addr(struct net_if * iface,uint8_t * addr,uint8_t len,enum net_link_type type)768 static inline int net_if_set_link_addr(struct net_if *iface,
769 uint8_t *addr, uint8_t len,
770 enum net_link_type type)
771 {
772 #if defined(CONFIG_NET_RAW_MODE)
773 return net_if_set_link_addr_unlocked(iface, addr, len, type);
774 #else
775 return net_if_set_link_addr_locked(iface, addr, len, type);
776 #endif
777 }
778
779 /**
780 * @brief Get an network interface's MTU
781 *
782 * @param iface Pointer to a network interface structure
783 *
784 * @return the MTU
785 */
net_if_get_mtu(struct net_if * iface)786 static inline uint16_t net_if_get_mtu(struct net_if *iface)
787 {
788 if (iface == NULL) {
789 return 0U;
790 }
791
792 return iface->if_dev->mtu;
793 }
794
795 /**
796 * @brief Set an network interface's MTU
797 *
798 * @param iface Pointer to a network interface structure
799 * @param mtu New MTU, note that we store only 16 bit mtu value.
800 */
net_if_set_mtu(struct net_if * iface,uint16_t mtu)801 static inline void net_if_set_mtu(struct net_if *iface,
802 uint16_t mtu)
803 {
804 if (iface == NULL) {
805 return;
806 }
807
808 iface->if_dev->mtu = mtu;
809 }
810
811 /**
812 * @brief Set the infinite status of the network interface address
813 *
814 * @param ifaddr IP address for network interface
815 * @param is_infinite Infinite status
816 */
net_if_addr_set_lf(struct net_if_addr * ifaddr,bool is_infinite)817 static inline void net_if_addr_set_lf(struct net_if_addr *ifaddr,
818 bool is_infinite)
819 {
820 ifaddr->is_infinite = is_infinite;
821 }
822
823 /**
824 * @brief Get an interface according to link layer address.
825 *
826 * @param ll_addr Link layer address.
827 *
828 * @return Network interface or NULL if not found.
829 */
830 struct net_if *net_if_get_by_link_addr(struct net_linkaddr *ll_addr);
831
832 /**
833 * @brief Find an interface from it's related device
834 *
835 * @param dev A valid struct device pointer to relate with an interface
836 *
837 * @return a valid struct net_if pointer on success, NULL otherwise
838 */
839 struct net_if *net_if_lookup_by_dev(const struct device *dev);
840
841 /**
842 * @brief Get network interface IP config
843 *
844 * @param iface Interface to use.
845 *
846 * @return NULL if not found or pointer to correct config settings.
847 */
net_if_config_get(struct net_if * iface)848 static inline struct net_if_config *net_if_config_get(struct net_if *iface)
849 {
850 return &iface->config;
851 }
852
853 /**
854 * @brief Remove a router from the system
855 *
856 * @param router Pointer to existing router
857 */
858 void net_if_router_rm(struct net_if_router *router);
859
860 /**
861 * @brief Get the default network interface.
862 *
863 * @return Default interface or NULL if no interfaces are configured.
864 */
865 struct net_if *net_if_get_default(void);
866
867 /**
868 * @brief Get the first network interface according to its type.
869 *
870 * @param l2 Layer 2 type of the network interface.
871 *
872 * @return First network interface of a given type or NULL if no such
873 * interfaces was found.
874 */
875 struct net_if *net_if_get_first_by_type(const struct net_l2 *l2);
876
877 #if defined(CONFIG_NET_L2_IEEE802154)
878 /**
879 * @brief Get the first IEEE 802.15.4 network interface.
880 *
881 * @return First IEEE 802.15.4 network interface or NULL if no such
882 * interfaces was found.
883 */
net_if_get_ieee802154(void)884 static inline struct net_if *net_if_get_ieee802154(void)
885 {
886 return net_if_get_first_by_type(&NET_L2_GET_NAME(IEEE802154));
887 }
888 #endif /* CONFIG_NET_L2_IEEE802154 */
889
890 /**
891 * @brief Allocate network interface IPv6 config.
892 *
893 * @details This function will allocate new IPv6 config.
894 *
895 * @param iface Interface to use.
896 * @param ipv6 Pointer to allocated IPv6 struct is returned to caller.
897 *
898 * @return 0 if ok, <0 if error
899 */
900 int net_if_config_ipv6_get(struct net_if *iface,
901 struct net_if_ipv6 **ipv6);
902
903 /**
904 * @brief Release network interface IPv6 config.
905 *
906 * @param iface Interface to use.
907 *
908 * @return 0 if ok, <0 if error
909 */
910 int net_if_config_ipv6_put(struct net_if *iface);
911
912 /**
913 * @brief Check if this IPv6 address belongs to one of the interfaces.
914 *
915 * @param addr IPv6 address
916 * @param iface Pointer to interface is returned
917 *
918 * @return Pointer to interface address, NULL if not found.
919 */
920 struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
921 struct net_if **iface);
922
923 /**
924 * @brief Check if this IPv6 address belongs to this specific interfaces.
925 *
926 * @param iface Network interface
927 * @param addr IPv6 address
928 *
929 * @return Pointer to interface address, NULL if not found.
930 */
931 struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
932 struct in6_addr *addr);
933
934 /**
935 * @brief Check if this IPv6 address belongs to one of the interface indices.
936 *
937 * @param addr IPv6 address
938 *
939 * @return >0 if address was found in given network interface index,
940 * all other values mean address was not found
941 */
942 __syscall int net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr);
943
944 /**
945 * @brief Add a IPv6 address to an interface
946 *
947 * @param iface Network interface
948 * @param addr IPv6 address
949 * @param addr_type IPv6 address type
950 * @param vlifetime Validity time for this address
951 *
952 * @return Pointer to interface address, NULL if cannot be added
953 */
954 struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
955 struct in6_addr *addr,
956 enum net_addr_type addr_type,
957 uint32_t vlifetime);
958
959 /**
960 * @brief Add a IPv6 address to an interface by index
961 *
962 * @param index Network interface index
963 * @param addr IPv6 address
964 * @param addr_type IPv6 address type
965 * @param vlifetime Validity time for this address
966 *
967 * @return True if ok, false if address could not be added
968 */
969 __syscall bool net_if_ipv6_addr_add_by_index(int index,
970 struct in6_addr *addr,
971 enum net_addr_type addr_type,
972 uint32_t vlifetime);
973
974 /**
975 * @brief Update validity lifetime time of an IPv6 address.
976 *
977 * @param ifaddr Network IPv6 address
978 * @param vlifetime Validity time for this address
979 */
980 void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr,
981 uint32_t vlifetime);
982
983 /**
984 * @brief Remove an IPv6 address from an interface
985 *
986 * @param iface Network interface
987 * @param addr IPv6 address
988 *
989 * @return True if successfully removed, false otherwise
990 */
991 bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr);
992
993 /**
994 * @brief Remove an IPv6 address from an interface by index
995 *
996 * @param index Network interface index
997 * @param addr IPv6 address
998 *
999 * @return True if successfully removed, false otherwise
1000 */
1001 __syscall bool net_if_ipv6_addr_rm_by_index(int index,
1002 const struct in6_addr *addr);
1003
1004 /**
1005 * @brief Add a IPv6 multicast address to an interface
1006 *
1007 * @param iface Network interface
1008 * @param addr IPv6 multicast address
1009 *
1010 * @return Pointer to interface multicast address, NULL if cannot be added
1011 */
1012 struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
1013 const struct in6_addr *addr);
1014
1015 /**
1016 * @brief Remove an IPv6 multicast address from an interface
1017 *
1018 * @param iface Network interface
1019 * @param addr IPv6 multicast address
1020 *
1021 * @return True if successfully removed, false otherwise
1022 */
1023 bool net_if_ipv6_maddr_rm(struct net_if *iface, const struct in6_addr *addr);
1024
1025 /**
1026 * @brief Check if this IPv6 multicast address belongs to a specific interface
1027 * or one of the interfaces.
1028 *
1029 * @param addr IPv6 address
1030 * @param iface If *iface is null, then pointer to interface is returned,
1031 * otherwise the *iface value needs to be matched.
1032 *
1033 * @return Pointer to interface multicast address, NULL if not found.
1034 */
1035 struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct in6_addr *addr,
1036 struct net_if **iface);
1037
1038 /**
1039 * @typedef net_if_mcast_callback_t
1040
1041 * @brief Define callback that is called whenever IPv6 multicast address group
1042 * is joined or left.
1043
1044 * @param iface A pointer to a struct net_if to which the multicast address is
1045 * attached.
1046 * @param addr IPv6 multicast address.
1047 * @param is_joined True if the address is joined, false if left.
1048 */
1049 typedef void (*net_if_mcast_callback_t)(struct net_if *iface,
1050 const struct in6_addr *addr,
1051 bool is_joined);
1052
1053 /**
1054 * @brief Multicast monitor handler struct.
1055 *
1056 * Stores the multicast callback information. Caller must make sure that
1057 * the variable pointed by this is valid during the lifetime of
1058 * registration. Typically this means that the variable cannot be
1059 * allocated from stack.
1060 */
1061 struct net_if_mcast_monitor {
1062 /** Node information for the slist. */
1063 sys_snode_t node;
1064
1065 /** Network interface */
1066 struct net_if *iface;
1067
1068 /** Multicast callback */
1069 net_if_mcast_callback_t cb;
1070 };
1071
1072 /**
1073 * @brief Register a multicast monitor
1074 *
1075 * @param mon Monitor handle. This is a pointer to a monitor storage structure
1076 * which should be allocated by caller, but does not need to be initialized.
1077 * @param iface Network interface
1078 * @param cb Monitor callback
1079 */
1080 void net_if_mcast_mon_register(struct net_if_mcast_monitor *mon,
1081 struct net_if *iface,
1082 net_if_mcast_callback_t cb);
1083
1084 /**
1085 * @brief Unregister a multicast monitor
1086 *
1087 * @param mon Monitor handle
1088 */
1089 void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon);
1090
1091 /**
1092 * @brief Call registered multicast monitors
1093 *
1094 * @param iface Network interface
1095 * @param addr Multicast address
1096 * @param is_joined Is this multicast address joined (true) or not (false)
1097 */
1098 void net_if_mcast_monitor(struct net_if *iface, const struct in6_addr *addr,
1099 bool is_joined);
1100
1101 /**
1102 * @brief Mark a given multicast address to be joined.
1103 *
1104 * @param addr IPv6 multicast address
1105 */
1106 void net_if_ipv6_maddr_join(struct net_if_mcast_addr *addr);
1107
1108 /**
1109 * @brief Check if given multicast address is joined or not.
1110 *
1111 * @param addr IPv6 multicast address
1112 *
1113 * @return True if address is joined, False otherwise.
1114 */
net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr * addr)1115 static inline bool net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr *addr)
1116 {
1117 NET_ASSERT(addr);
1118
1119 return addr->is_joined;
1120 }
1121
1122 /**
1123 * @brief Mark a given multicast address to be left.
1124 *
1125 * @param addr IPv6 multicast address
1126 */
1127 void net_if_ipv6_maddr_leave(struct net_if_mcast_addr *addr);
1128
1129 /**
1130 * @brief Return prefix that corresponds to this IPv6 address.
1131 *
1132 * @param iface Network interface
1133 * @param addr IPv6 address
1134 *
1135 * @return Pointer to prefix, NULL if not found.
1136 */
1137 struct net_if_ipv6_prefix *net_if_ipv6_prefix_get(struct net_if *iface,
1138 struct in6_addr *addr);
1139
1140 /**
1141 * @brief Check if this IPv6 prefix belongs to this interface
1142 *
1143 * @param iface Network interface
1144 * @param addr IPv6 address
1145 * @param len Prefix length
1146 *
1147 * @return Pointer to prefix, NULL if not found.
1148 */
1149 struct net_if_ipv6_prefix *net_if_ipv6_prefix_lookup(struct net_if *iface,
1150 struct in6_addr *addr,
1151 uint8_t len);
1152
1153 /**
1154 * @brief Add a IPv6 prefix to an network interface.
1155 *
1156 * @param iface Network interface
1157 * @param prefix IPv6 address
1158 * @param len Prefix length
1159 * @param lifetime Prefix lifetime in seconds
1160 *
1161 * @return Pointer to prefix, NULL if the prefix was not added.
1162 */
1163 struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface,
1164 struct in6_addr *prefix,
1165 uint8_t len,
1166 uint32_t lifetime);
1167
1168 /**
1169 * @brief Remove an IPv6 prefix from an interface
1170 *
1171 * @param iface Network interface
1172 * @param addr IPv6 prefix address
1173 * @param len Prefix length
1174 *
1175 * @return True if successfully removed, false otherwise
1176 */
1177 bool net_if_ipv6_prefix_rm(struct net_if *iface, struct in6_addr *addr,
1178 uint8_t len);
1179
1180 /**
1181 * @brief Set the infinite status of the prefix
1182 *
1183 * @param prefix IPv6 address
1184 * @param is_infinite Infinite status
1185 */
net_if_ipv6_prefix_set_lf(struct net_if_ipv6_prefix * prefix,bool is_infinite)1186 static inline void net_if_ipv6_prefix_set_lf(struct net_if_ipv6_prefix *prefix,
1187 bool is_infinite)
1188 {
1189 prefix->is_infinite = is_infinite;
1190 }
1191
1192 /**
1193 * @brief Set the prefix lifetime timer.
1194 *
1195 * @param prefix IPv6 address
1196 * @param lifetime Prefix lifetime in seconds
1197 */
1198 void net_if_ipv6_prefix_set_timer(struct net_if_ipv6_prefix *prefix,
1199 uint32_t lifetime);
1200
1201 /**
1202 * @brief Unset the prefix lifetime timer.
1203 *
1204 * @param prefix IPv6 address
1205 */
1206 void net_if_ipv6_prefix_unset_timer(struct net_if_ipv6_prefix *prefix);
1207
1208 /**
1209 * @brief Check if this IPv6 address is part of the subnet of our
1210 * network interface.
1211 *
1212 * @param iface Network interface. This is returned to the caller.
1213 * The iface can be NULL in which case we check all the interfaces.
1214 * @param addr IPv6 address
1215 *
1216 * @return True if address is part of our subnet, false otherwise
1217 */
1218 bool net_if_ipv6_addr_onlink(struct net_if **iface, struct in6_addr *addr);
1219
1220 /**
1221 * @brief Get the IPv6 address of the given router
1222 * @param router a network router
1223 *
1224 * @return pointer to the IPv6 address, or NULL if none
1225 */
1226 #if defined(CONFIG_NET_NATIVE_IPV6)
net_if_router_ipv6(struct net_if_router * router)1227 static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router)
1228 {
1229 return &router->address.in6_addr;
1230 }
1231 #else
net_if_router_ipv6(struct net_if_router * router)1232 static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router)
1233 {
1234 static struct in6_addr addr;
1235
1236 ARG_UNUSED(router);
1237
1238 return &addr;
1239 }
1240 #endif
1241
1242 /**
1243 * @brief Check if IPv6 address is one of the routers configured
1244 * in the system.
1245 *
1246 * @param iface Network interface
1247 * @param addr IPv6 address
1248 *
1249 * @return Pointer to router information, NULL if cannot be found
1250 */
1251 struct net_if_router *net_if_ipv6_router_lookup(struct net_if *iface,
1252 struct in6_addr *addr);
1253
1254 /**
1255 * @brief Find default router for this IPv6 address.
1256 *
1257 * @param iface Network interface. This can be NULL in which case we
1258 * go through all the network interfaces to find a suitable router.
1259 * @param addr IPv6 address
1260 *
1261 * @return Pointer to router information, NULL if cannot be found
1262 */
1263 struct net_if_router *net_if_ipv6_router_find_default(struct net_if *iface,
1264 struct in6_addr *addr);
1265
1266 /**
1267 * @brief Update validity lifetime time of a router.
1268 *
1269 * @param router Network IPv6 address
1270 * @param lifetime Lifetime of this router.
1271 */
1272 void net_if_ipv6_router_update_lifetime(struct net_if_router *router,
1273 uint16_t lifetime);
1274
1275 /**
1276 * @brief Add IPv6 router to the system.
1277 *
1278 * @param iface Network interface
1279 * @param addr IPv6 address
1280 * @param router_lifetime Lifetime of the router
1281 *
1282 * @return Pointer to router information, NULL if could not be added
1283 */
1284 struct net_if_router *net_if_ipv6_router_add(struct net_if *iface,
1285 struct in6_addr *addr,
1286 uint16_t router_lifetime);
1287
1288 /**
1289 * @brief Remove IPv6 router from the system.
1290 *
1291 * @param router Router information.
1292 *
1293 * @return True if successfully removed, false otherwise
1294 */
1295 bool net_if_ipv6_router_rm(struct net_if_router *router);
1296
1297 /**
1298 * @brief Get IPv6 hop limit specified for a given interface. This is the
1299 * default value but can be overridden by the user.
1300 *
1301 * @param iface Network interface
1302 *
1303 * @return Hop limit
1304 */
1305 uint8_t net_if_ipv6_get_hop_limit(struct net_if *iface);
1306
1307 /**
1308 * @brief Set the default IPv6 hop limit of a given interface.
1309 *
1310 * @param iface Network interface
1311 * @param hop_limit New hop limit
1312 */
1313 void net_ipv6_set_hop_limit(struct net_if *iface, uint8_t hop_limit);
1314
1315 /**
1316 * @brief Set IPv6 reachable time for a given interface
1317 *
1318 * @param iface Network interface
1319 * @param reachable_time New reachable time
1320 */
net_if_ipv6_set_base_reachable_time(struct net_if * iface,uint32_t reachable_time)1321 static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface,
1322 uint32_t reachable_time)
1323 {
1324 #if defined(CONFIG_NET_NATIVE_IPV6)
1325 if (!iface->config.ip.ipv6) {
1326 return;
1327 }
1328
1329 iface->config.ip.ipv6->base_reachable_time = reachable_time;
1330 #endif
1331 }
1332
1333 /**
1334 * @brief Get IPv6 reachable timeout specified for a given interface
1335 *
1336 * @param iface Network interface
1337 *
1338 * @return Reachable timeout
1339 */
net_if_ipv6_get_reachable_time(struct net_if * iface)1340 static inline uint32_t net_if_ipv6_get_reachable_time(struct net_if *iface)
1341 {
1342 #if defined(CONFIG_NET_NATIVE_IPV6)
1343 if (!iface->config.ip.ipv6) {
1344 return 0;
1345 }
1346
1347 return iface->config.ip.ipv6->reachable_time;
1348 #else
1349 return 0;
1350 #endif
1351 }
1352
1353 /**
1354 * @brief Calculate next reachable time value for IPv6 reachable time
1355 *
1356 * @param ipv6 IPv6 address configuration
1357 *
1358 * @return Reachable time
1359 */
1360 uint32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6);
1361
1362 /**
1363 * @brief Set IPv6 reachable time for a given interface. This requires
1364 * that base reachable time is set for the interface.
1365 *
1366 * @param ipv6 IPv6 address configuration
1367 */
net_if_ipv6_set_reachable_time(struct net_if_ipv6 * ipv6)1368 static inline void net_if_ipv6_set_reachable_time(struct net_if_ipv6 *ipv6)
1369 {
1370 #if defined(CONFIG_NET_NATIVE_IPV6)
1371 if (ipv6 == NULL) {
1372 return;
1373 }
1374
1375 ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6);
1376 #endif
1377 }
1378
1379 /**
1380 * @brief Set IPv6 retransmit timer for a given interface
1381 *
1382 * @param iface Network interface
1383 * @param retrans_timer New retransmit timer
1384 */
net_if_ipv6_set_retrans_timer(struct net_if * iface,uint32_t retrans_timer)1385 static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface,
1386 uint32_t retrans_timer)
1387 {
1388 #if defined(CONFIG_NET_NATIVE_IPV6)
1389 if (!iface->config.ip.ipv6) {
1390 return;
1391 }
1392
1393 iface->config.ip.ipv6->retrans_timer = retrans_timer;
1394 #endif
1395 }
1396
1397 /**
1398 * @brief Get IPv6 retransmit timer specified for a given interface
1399 *
1400 * @param iface Network interface
1401 *
1402 * @return Retransmit timer
1403 */
net_if_ipv6_get_retrans_timer(struct net_if * iface)1404 static inline uint32_t net_if_ipv6_get_retrans_timer(struct net_if *iface)
1405 {
1406 #if defined(CONFIG_NET_NATIVE_IPV6)
1407 if (!iface->config.ip.ipv6) {
1408 return 0;
1409 }
1410
1411 return iface->config.ip.ipv6->retrans_timer;
1412 #else
1413 return 0;
1414 #endif
1415 }
1416
1417 /**
1418 * @brief Get a IPv6 source address that should be used when sending
1419 * network data to destination.
1420 *
1421 * @param iface Interface that was used when packet was received.
1422 * If the interface is not known, then NULL can be given.
1423 * @param dst IPv6 destination address
1424 *
1425 * @return Pointer to IPv6 address to use, NULL if no IPv6 address
1426 * could be found.
1427 */
1428 #if defined(CONFIG_NET_NATIVE_IPV6)
1429 const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *iface,
1430 const struct in6_addr *dst);
1431 #else
net_if_ipv6_select_src_addr(struct net_if * iface,const struct in6_addr * dst)1432 static inline const struct in6_addr *net_if_ipv6_select_src_addr(
1433 struct net_if *iface, const struct in6_addr *dst)
1434 {
1435 ARG_UNUSED(iface);
1436 ARG_UNUSED(dst);
1437
1438 return NULL;
1439 }
1440 #endif
1441
1442 /**
1443 * @brief Get a network interface that should be used when sending
1444 * IPv6 network data to destination.
1445 *
1446 * @param dst IPv6 destination address
1447 *
1448 * @return Pointer to network interface to use, NULL if no suitable interface
1449 * could be found.
1450 */
1451 #if defined(CONFIG_NET_NATIVE_IPV6)
1452 struct net_if *net_if_ipv6_select_src_iface(const struct in6_addr *dst);
1453 #else
net_if_ipv6_select_src_iface(const struct in6_addr * dst)1454 static inline struct net_if *net_if_ipv6_select_src_iface(
1455 const struct in6_addr *dst)
1456 {
1457 ARG_UNUSED(dst);
1458
1459 return NULL;
1460 }
1461 #endif
1462
1463 /**
1464 * @brief Get a IPv6 link local address in a given state.
1465 *
1466 * @param iface Interface to use. Must be a valid pointer to an interface.
1467 * @param addr_state IPv6 address state (preferred, tentative, deprecated)
1468 *
1469 * @return Pointer to link local IPv6 address, NULL if no proper IPv6 address
1470 * could be found.
1471 */
1472 struct in6_addr *net_if_ipv6_get_ll(struct net_if *iface,
1473 enum net_addr_state addr_state);
1474
1475 /**
1476 * @brief Return link local IPv6 address from the first interface that has
1477 * a link local address matching give state.
1478 *
1479 * @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
1480 * @param iface Pointer to interface is returned
1481 *
1482 * @return Pointer to IPv6 address, NULL if not found.
1483 */
1484 struct in6_addr *net_if_ipv6_get_ll_addr(enum net_addr_state state,
1485 struct net_if **iface);
1486
1487 /**
1488 * @brief Stop IPv6 Duplicate Address Detection (DAD) procedure if
1489 * we find out that our IPv6 address is already in use.
1490 *
1491 * @param iface Interface where the DAD was running.
1492 * @param addr IPv6 address that failed DAD
1493 */
1494 void net_if_ipv6_dad_failed(struct net_if *iface, const struct in6_addr *addr);
1495
1496 /**
1497 * @brief Return global IPv6 address from the first interface that has
1498 * a global IPv6 address matching the given state.
1499 *
1500 * @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
1501 * @param iface Caller can give an interface to check. If iface is set to NULL,
1502 * then all the interfaces are checked. Pointer to interface where the IPv6
1503 * address is defined is returned to the caller.
1504 *
1505 * @return Pointer to IPv6 address, NULL if not found.
1506 */
1507 struct in6_addr *net_if_ipv6_get_global_addr(enum net_addr_state state,
1508 struct net_if **iface);
1509
1510 /**
1511 * @brief Allocate network interface IPv4 config.
1512 *
1513 * @details This function will allocate new IPv4 config.
1514 *
1515 * @param iface Interface to use.
1516 * @param ipv4 Pointer to allocated IPv4 struct is returned to caller.
1517 *
1518 * @return 0 if ok, <0 if error
1519 */
1520 int net_if_config_ipv4_get(struct net_if *iface,
1521 struct net_if_ipv4 **ipv4);
1522
1523 /**
1524 * @brief Release network interface IPv4 config.
1525 *
1526 * @param iface Interface to use.
1527 *
1528 * @return 0 if ok, <0 if error
1529 */
1530 int net_if_config_ipv4_put(struct net_if *iface);
1531
1532 /**
1533 * @brief Get IPv4 time-to-live value specified for a given interface
1534 *
1535 * @param iface Network interface
1536 *
1537 * @return Time-to-live
1538 */
1539 uint8_t net_if_ipv4_get_ttl(struct net_if *iface);
1540
1541 /**
1542 * @brief Set IPv4 time-to-live value specified to a given interface
1543 *
1544 * @param iface Network interface
1545 * @param ttl Time-to-live value
1546 */
1547 void net_if_ipv4_set_ttl(struct net_if *iface, uint8_t ttl);
1548
1549 /**
1550 * @brief Check if this IPv4 address belongs to one of the interfaces.
1551 *
1552 * @param addr IPv4 address
1553 * @param iface Interface is returned
1554 *
1555 * @return Pointer to interface address, NULL if not found.
1556 */
1557 struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
1558 struct net_if **iface);
1559
1560 /**
1561 * @brief Add a IPv4 address to an interface
1562 *
1563 * @param iface Network interface
1564 * @param addr IPv4 address
1565 * @param addr_type IPv4 address type
1566 * @param vlifetime Validity time for this address
1567 *
1568 * @return Pointer to interface address, NULL if cannot be added
1569 */
1570 struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface,
1571 struct in_addr *addr,
1572 enum net_addr_type addr_type,
1573 uint32_t vlifetime);
1574
1575 /**
1576 * @brief Remove a IPv4 address from an interface
1577 *
1578 * @param iface Network interface
1579 * @param addr IPv4 address
1580 *
1581 * @return True if successfully removed, false otherwise
1582 */
1583 bool net_if_ipv4_addr_rm(struct net_if *iface, const struct in_addr *addr);
1584
1585 /**
1586 * @brief Check if this IPv4 address belongs to one of the interface indices.
1587 *
1588 * @param addr IPv4 address
1589 *
1590 * @return >0 if address was found in given network interface index,
1591 * all other values mean address was not found
1592 */
1593 __syscall int net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr);
1594
1595 /**
1596 * @brief Add a IPv4 address to an interface by network interface index
1597 *
1598 * @param index Network interface index
1599 * @param addr IPv4 address
1600 * @param addr_type IPv4 address type
1601 * @param vlifetime Validity time for this address
1602 *
1603 * @return True if ok, false if the address could not be added
1604 */
1605 __syscall bool net_if_ipv4_addr_add_by_index(int index,
1606 struct in_addr *addr,
1607 enum net_addr_type addr_type,
1608 uint32_t vlifetime);
1609
1610 /**
1611 * @brief Remove a IPv4 address from an interface by interface index
1612 *
1613 * @param index Network interface index
1614 * @param addr IPv4 address
1615 *
1616 * @return True if successfully removed, false otherwise
1617 */
1618 __syscall bool net_if_ipv4_addr_rm_by_index(int index,
1619 const struct in_addr *addr);
1620
1621 /**
1622 * @brief Add a IPv4 multicast address to an interface
1623 *
1624 * @param iface Network interface
1625 * @param addr IPv4 multicast address
1626 *
1627 * @return Pointer to interface multicast address, NULL if cannot be added
1628 */
1629 struct net_if_mcast_addr *net_if_ipv4_maddr_add(struct net_if *iface,
1630 const struct in_addr *addr);
1631
1632 /**
1633 * @brief Remove an IPv4 multicast address from an interface
1634 *
1635 * @param iface Network interface
1636 * @param addr IPv4 multicast address
1637 *
1638 * @return True if successfully removed, false otherwise
1639 */
1640 bool net_if_ipv4_maddr_rm(struct net_if *iface, const struct in_addr *addr);
1641
1642 /**
1643 * @brief Check if this IPv4 multicast address belongs to a specific interface
1644 * or one of the interfaces.
1645 *
1646 * @param addr IPv4 address
1647 * @param iface If *iface is null, then pointer to interface is returned,
1648 * otherwise the *iface value needs to be matched.
1649 *
1650 * @return Pointer to interface multicast address, NULL if not found.
1651 */
1652 struct net_if_mcast_addr *net_if_ipv4_maddr_lookup(const struct in_addr *addr,
1653 struct net_if **iface);
1654
1655 /**
1656 * @brief Mark a given multicast address to be joined.
1657 *
1658 * @param addr IPv4 multicast address
1659 */
1660 void net_if_ipv4_maddr_join(struct net_if_mcast_addr *addr);
1661
1662 /**
1663 * @brief Check if given multicast address is joined or not.
1664 *
1665 * @param addr IPv4 multicast address
1666 *
1667 * @return True if address is joined, False otherwise.
1668 */
net_if_ipv4_maddr_is_joined(struct net_if_mcast_addr * addr)1669 static inline bool net_if_ipv4_maddr_is_joined(struct net_if_mcast_addr *addr)
1670 {
1671 NET_ASSERT(addr);
1672
1673 return addr->is_joined;
1674 }
1675
1676 /**
1677 * @brief Mark a given multicast address to be left.
1678 *
1679 * @param addr IPv4 multicast address
1680 */
1681 void net_if_ipv4_maddr_leave(struct net_if_mcast_addr *addr);
1682
1683 /**
1684 * @brief Get the IPv4 address of the given router
1685 * @param router a network router
1686 *
1687 * @return pointer to the IPv4 address, or NULL if none
1688 */
1689 #if defined(CONFIG_NET_NATIVE_IPV4)
net_if_router_ipv4(struct net_if_router * router)1690 static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router)
1691 {
1692 return &router->address.in_addr;
1693 }
1694 #else
net_if_router_ipv4(struct net_if_router * router)1695 static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router)
1696 {
1697 static struct in_addr addr;
1698
1699 ARG_UNUSED(router);
1700
1701 return &addr;
1702 }
1703 #endif
1704
1705 /**
1706 * @brief Check if IPv4 address is one of the routers configured
1707 * in the system.
1708 *
1709 * @param iface Network interface
1710 * @param addr IPv4 address
1711 *
1712 * @return Pointer to router information, NULL if cannot be found
1713 */
1714 struct net_if_router *net_if_ipv4_router_lookup(struct net_if *iface,
1715 struct in_addr *addr);
1716
1717 /**
1718 * @brief Find default router for this IPv4 address.
1719 *
1720 * @param iface Network interface. This can be NULL in which case we
1721 * go through all the network interfaces to find a suitable router.
1722 * @param addr IPv4 address
1723 *
1724 * @return Pointer to router information, NULL if cannot be found
1725 */
1726 struct net_if_router *net_if_ipv4_router_find_default(struct net_if *iface,
1727 struct in_addr *addr);
1728 /**
1729 * @brief Add IPv4 router to the system.
1730 *
1731 * @param iface Network interface
1732 * @param addr IPv4 address
1733 * @param is_default Is this router the default one
1734 * @param router_lifetime Lifetime of the router
1735 *
1736 * @return Pointer to router information, NULL if could not be added
1737 */
1738 struct net_if_router *net_if_ipv4_router_add(struct net_if *iface,
1739 struct in_addr *addr,
1740 bool is_default,
1741 uint16_t router_lifetime);
1742
1743 /**
1744 * @brief Remove IPv4 router from the system.
1745 *
1746 * @param router Router information.
1747 *
1748 * @return True if successfully removed, false otherwise
1749 */
1750 bool net_if_ipv4_router_rm(struct net_if_router *router);
1751
1752 /**
1753 * @brief Check if the given IPv4 address belongs to local subnet.
1754 *
1755 * @param iface Interface to use. Must be a valid pointer to an interface.
1756 * @param addr IPv4 address
1757 *
1758 * @return True if address is part of local subnet, false otherwise.
1759 */
1760 bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
1761 const struct in_addr *addr);
1762
1763 /**
1764 * @brief Check if the given IPv4 address is a broadcast address.
1765 *
1766 * @param iface Interface to use. Must be a valid pointer to an interface.
1767 * @param addr IPv4 address, this should be in network byte order
1768 *
1769 * @return True if address is a broadcast address, false otherwise.
1770 */
1771 bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
1772 const struct in_addr *addr);
1773
1774 /**
1775 * @brief Get a network interface that should be used when sending
1776 * IPv4 network data to destination.
1777 *
1778 * @param dst IPv4 destination address
1779 *
1780 * @return Pointer to network interface to use, NULL if no suitable interface
1781 * could be found.
1782 */
1783 #if defined(CONFIG_NET_NATIVE_IPV4)
1784 struct net_if *net_if_ipv4_select_src_iface(const struct in_addr *dst);
1785 #else
net_if_ipv4_select_src_iface(const struct in_addr * dst)1786 static inline struct net_if *net_if_ipv4_select_src_iface(
1787 const struct in_addr *dst)
1788 {
1789 ARG_UNUSED(dst);
1790
1791 return NULL;
1792 }
1793 #endif
1794
1795 /**
1796 * @brief Get a IPv4 source address that should be used when sending
1797 * network data to destination.
1798 *
1799 * @param iface Interface to use when sending the packet.
1800 * If the interface is not known, then NULL can be given.
1801 * @param dst IPv4 destination address
1802 *
1803 * @return Pointer to IPv4 address to use, NULL if no IPv4 address
1804 * could be found.
1805 */
1806 #if defined(CONFIG_NET_NATIVE_IPV4)
1807 const struct in_addr *net_if_ipv4_select_src_addr(struct net_if *iface,
1808 const struct in_addr *dst);
1809 #else
net_if_ipv4_select_src_addr(struct net_if * iface,const struct in_addr * dst)1810 static inline const struct in_addr *net_if_ipv4_select_src_addr(
1811 struct net_if *iface, const struct in_addr *dst)
1812 {
1813 ARG_UNUSED(iface);
1814 ARG_UNUSED(dst);
1815
1816 return NULL;
1817 }
1818 #endif
1819
1820 /**
1821 * @brief Get a IPv4 link local address in a given state.
1822 *
1823 * @param iface Interface to use. Must be a valid pointer to an interface.
1824 * @param addr_state IPv4 address state (preferred, tentative, deprecated)
1825 *
1826 * @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
1827 * could be found.
1828 */
1829 struct in_addr *net_if_ipv4_get_ll(struct net_if *iface,
1830 enum net_addr_state addr_state);
1831
1832 /**
1833 * @brief Get a IPv4 global address in a given state.
1834 *
1835 * @param iface Interface to use. Must be a valid pointer to an interface.
1836 * @param addr_state IPv4 address state (preferred, tentative, deprecated)
1837 *
1838 * @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
1839 * could be found.
1840 */
1841 struct in_addr *net_if_ipv4_get_global_addr(struct net_if *iface,
1842 enum net_addr_state addr_state);
1843
1844 /**
1845 * @brief Set IPv4 netmask for an interface.
1846 *
1847 * @param iface Interface to use.
1848 * @param netmask IPv4 netmask
1849 */
1850 void net_if_ipv4_set_netmask(struct net_if *iface,
1851 const struct in_addr *netmask);
1852
1853 /**
1854 * @brief Set IPv4 netmask for an interface index.
1855 *
1856 * @param index Network interface index
1857 * @param netmask IPv4 netmask
1858 *
1859 * @return True if netmask was added, false otherwise.
1860 */
1861 __syscall bool net_if_ipv4_set_netmask_by_index(int index,
1862 const struct in_addr *netmask);
1863
1864 /**
1865 * @brief Set IPv4 gateway for an interface.
1866 *
1867 * @param iface Interface to use.
1868 * @param gw IPv4 address of an gateway
1869 */
1870 void net_if_ipv4_set_gw(struct net_if *iface, const struct in_addr *gw);
1871
1872 /**
1873 * @brief Set IPv4 gateway for an interface index.
1874 *
1875 * @param index Network interface index
1876 * @param gw IPv4 address of an gateway
1877 *
1878 * @return True if gateway was added, false otherwise.
1879 */
1880 __syscall bool net_if_ipv4_set_gw_by_index(int index, const struct in_addr *gw);
1881
1882 /**
1883 * @brief Get a network interface that should be used when sending
1884 * IPv6 or IPv4 network data to destination.
1885 *
1886 * @param dst IPv6 or IPv4 destination address
1887 *
1888 * @return Pointer to network interface to use. Note that the function
1889 * will return the default network interface if the best network interface
1890 * is not found.
1891 */
1892 struct net_if *net_if_select_src_iface(const struct sockaddr *dst);
1893
1894 /**
1895 * @typedef net_if_link_callback_t
1896 * @brief Define callback that is called after a network packet
1897 * has been sent.
1898 * @param iface A pointer to a struct net_if to which the the net_pkt was sent to.
1899 * @param dst Link layer address of the destination where the network packet was sent.
1900 * @param status Send status, 0 is ok, < 0 error.
1901 */
1902 typedef void (*net_if_link_callback_t)(struct net_if *iface,
1903 struct net_linkaddr *dst,
1904 int status);
1905
1906 /**
1907 * @brief Link callback handler struct.
1908 *
1909 * Stores the link callback information. Caller must make sure that
1910 * the variable pointed by this is valid during the lifetime of
1911 * registration. Typically this means that the variable cannot be
1912 * allocated from stack.
1913 */
1914 struct net_if_link_cb {
1915 /** Node information for the slist. */
1916 sys_snode_t node;
1917
1918 /** Link callback */
1919 net_if_link_callback_t cb;
1920 };
1921
1922 /**
1923 * @brief Register a link callback.
1924 *
1925 * @param link Caller specified handler for the callback.
1926 * @param cb Callback to register.
1927 */
1928 void net_if_register_link_cb(struct net_if_link_cb *link,
1929 net_if_link_callback_t cb);
1930
1931 /**
1932 * @brief Unregister a link callback.
1933 *
1934 * @param link Caller specified handler for the callback.
1935 */
1936 void net_if_unregister_link_cb(struct net_if_link_cb *link);
1937
1938 /**
1939 * @brief Call a link callback function.
1940 *
1941 * @param iface Network interface.
1942 * @param lladdr Destination link layer address
1943 * @param status 0 is ok, < 0 error
1944 */
1945 void net_if_call_link_cb(struct net_if *iface, struct net_linkaddr *lladdr,
1946 int status);
1947
1948 /**
1949 * @brief Check if received network packet checksum calculation can be avoided
1950 * or not. For example many ethernet devices support network packet offloading
1951 * in which case the IP stack does not need to calculate the checksum.
1952 *
1953 * @param iface Network interface
1954 *
1955 * @return True if checksum needs to be calculated, false otherwise.
1956 */
1957 bool net_if_need_calc_rx_checksum(struct net_if *iface);
1958
1959 /**
1960 * @brief Check if network packet checksum calculation can be avoided or not
1961 * when sending the packet. For example many ethernet devices support network
1962 * packet offloading in which case the IP stack does not need to calculate the
1963 * checksum.
1964 *
1965 * @param iface Network interface
1966 *
1967 * @return True if checksum needs to be calculated, false otherwise.
1968 */
1969 bool net_if_need_calc_tx_checksum(struct net_if *iface);
1970
1971 /**
1972 * @brief Get interface according to index
1973 *
1974 * @details This is a syscall only to provide access to the object for purposes
1975 * of assigning permissions.
1976 *
1977 * @param index Interface index
1978 *
1979 * @return Pointer to interface or NULL if not found.
1980 */
1981 __syscall struct net_if *net_if_get_by_index(int index);
1982
1983 /**
1984 * @brief Get interface index according to pointer
1985 *
1986 * @param iface Pointer to network interface
1987 *
1988 * @return Interface index
1989 */
1990 int net_if_get_by_iface(struct net_if *iface);
1991
1992 /**
1993 * @typedef net_if_cb_t
1994 * @brief Callback used while iterating over network interfaces
1995 *
1996 * @param iface Pointer to current network interface
1997 * @param user_data A valid pointer to user data or NULL
1998 */
1999 typedef void (*net_if_cb_t)(struct net_if *iface, void *user_data);
2000
2001 /**
2002 * @brief Go through all the network interfaces and call callback
2003 * for each interface.
2004 *
2005 * @param cb User-supplied callback function to call
2006 * @param user_data User specified data
2007 */
2008 void net_if_foreach(net_if_cb_t cb, void *user_data);
2009
2010 /**
2011 * @brief Bring interface up
2012 *
2013 * @param iface Pointer to network interface
2014 *
2015 * @return 0 on success
2016 */
2017 int net_if_up(struct net_if *iface);
2018
2019 /**
2020 * @brief Check if interface is up.
2021 *
2022 * @param iface Pointer to network interface
2023 *
2024 * @return True if interface is up, False if it is down.
2025 */
net_if_is_up(struct net_if * iface)2026 static inline bool net_if_is_up(struct net_if *iface)
2027 {
2028 NET_ASSERT(iface);
2029
2030 return net_if_flag_is_set(iface, NET_IF_UP);
2031 }
2032
2033 /**
2034 * @brief Bring interface down
2035 *
2036 * @param iface Pointer to network interface
2037 *
2038 * @return 0 on success
2039 */
2040 int net_if_down(struct net_if *iface);
2041
2042 #if defined(CONFIG_NET_PKT_TIMESTAMP) && defined(CONFIG_NET_NATIVE)
2043 /**
2044 * @typedef net_if_timestamp_callback_t
2045 * @brief Define callback that is called after a network packet
2046 * has been timestamped.
2047 * @param "struct net_pkt *pkt" A pointer on a struct net_pkt which has
2048 * been timestamped after being sent.
2049 */
2050 typedef void (*net_if_timestamp_callback_t)(struct net_pkt *pkt);
2051
2052 /**
2053 * @brief Timestamp callback handler struct.
2054 *
2055 * Stores the timestamp callback information. Caller must make sure that
2056 * the variable pointed by this is valid during the lifetime of
2057 * registration. Typically this means that the variable cannot be
2058 * allocated from stack.
2059 */
2060 struct net_if_timestamp_cb {
2061 /** Node information for the slist. */
2062 sys_snode_t node;
2063
2064 /** Packet for which the callback is needed.
2065 * A NULL value means all packets.
2066 */
2067 struct net_pkt *pkt;
2068
2069 /** Net interface for which the callback is needed.
2070 * A NULL value means all interfaces.
2071 */
2072 struct net_if *iface;
2073
2074 /** Timestamp callback */
2075 net_if_timestamp_callback_t cb;
2076 };
2077
2078 /**
2079 * @brief Register a timestamp callback.
2080 *
2081 * @param handle Caller specified handler for the callback.
2082 * @param pkt Net packet for which the callback is registered. NULL for all
2083 * packets.
2084 * @param iface Net interface for which the callback is. NULL for all
2085 * interfaces.
2086 * @param cb Callback to register.
2087 */
2088 void net_if_register_timestamp_cb(struct net_if_timestamp_cb *handle,
2089 struct net_pkt *pkt,
2090 struct net_if *iface,
2091 net_if_timestamp_callback_t cb);
2092
2093 /**
2094 * @brief Unregister a timestamp callback.
2095 *
2096 * @param handle Caller specified handler for the callback.
2097 */
2098 void net_if_unregister_timestamp_cb(struct net_if_timestamp_cb *handle);
2099
2100 /**
2101 * @brief Call a timestamp callback function.
2102 *
2103 * @param pkt Network buffer.
2104 */
2105 void net_if_call_timestamp_cb(struct net_pkt *pkt);
2106
2107 /*
2108 * @brief Add timestamped TX buffer to be handled
2109 *
2110 * @param pkt Timestamped buffer
2111 */
2112 void net_if_add_tx_timestamp(struct net_pkt *pkt);
2113 #endif /* CONFIG_NET_PKT_TIMESTAMP */
2114
2115 /**
2116 * @brief Set network interface into promiscuous mode
2117 *
2118 * @details Note that not all network technologies will support this.
2119 *
2120 * @param iface Pointer to network interface
2121 *
2122 * @return 0 on success, <0 if error
2123 */
2124 int net_if_set_promisc(struct net_if *iface);
2125
2126 /**
2127 * @brief Set network interface into normal mode
2128 *
2129 * @param iface Pointer to network interface
2130 */
2131 void net_if_unset_promisc(struct net_if *iface);
2132
2133 /**
2134 * @brief Check if promiscuous mode is set or not.
2135 *
2136 * @param iface Pointer to network interface
2137 *
2138 * @return True if interface is in promisc mode,
2139 * False if interface is not in in promiscuous mode.
2140 */
2141 bool net_if_is_promisc(struct net_if *iface);
2142
2143 /**
2144 * @brief Check if there are any pending TX network data for a given network
2145 * interface.
2146 *
2147 * @param iface Pointer to network interface
2148 *
2149 * @return True if there are pending TX network packets for this network
2150 * interface, False otherwise.
2151 */
net_if_are_pending_tx_packets(struct net_if * iface)2152 static inline bool net_if_are_pending_tx_packets(struct net_if *iface)
2153 {
2154 #if defined(CONFIG_NET_POWER_MANAGEMENT)
2155 return !!iface->tx_pending;
2156 #else
2157 ARG_UNUSED(iface);
2158
2159 return false;
2160 #endif
2161 }
2162
2163 #ifdef CONFIG_NET_POWER_MANAGEMENT
2164 /**
2165 * @brief Suspend a network interface from a power management perspective
2166 *
2167 * @param iface Pointer to network interface
2168 *
2169 * @return 0 on success, or -EALREADY/-EBUSY as possible errors.
2170 */
2171 int net_if_suspend(struct net_if *iface);
2172
2173 /**
2174 * @brief Resume a network interface from a power management perspective
2175 *
2176 * @param iface Pointer to network interface
2177 *
2178 * @return 0 on success, or -EALREADY as a possible error.
2179 */
2180 int net_if_resume(struct net_if *iface);
2181
2182 /**
2183 * @brief Check if the network interface is suspended or not.
2184 *
2185 * @param iface Pointer to network interface
2186 *
2187 * @return True if interface is suspended, False otherwise.
2188 */
2189 bool net_if_is_suspended(struct net_if *iface);
2190 #endif /* CONFIG_NET_POWER_MANAGEMENT */
2191
2192 /** @cond INTERNAL_HIDDEN */
2193 struct net_if_api {
2194 void (*init)(struct net_if *iface);
2195 };
2196
2197 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
2198 #define NET_IF_DHCPV4_INIT .dhcpv4.state = NET_DHCPV4_DISABLED,
2199 #else
2200 #define NET_IF_DHCPV4_INIT
2201 #endif
2202
2203 #define NET_IF_CONFIG_INIT \
2204 .config = { \
2205 .ip = { \
2206 }, \
2207 NET_IF_DHCPV4_INIT \
2208 }
2209
2210 #define NET_IF_GET_NAME(dev_name, sfx) __net_if_##dev_name##_##sfx
2211 #define NET_IF_DEV_GET_NAME(dev_name, sfx) __net_if_dev_##dev_name##_##sfx
2212
2213 #define NET_IF_GET(dev_name, sfx) \
2214 ((struct net_if *)&NET_IF_GET_NAME(dev_name, sfx))
2215
2216 #define NET_IF_INIT(dev_name, sfx, _l2, _mtu, _num_configs) \
2217 static STRUCT_SECTION_ITERABLE(net_if_dev, \
2218 NET_IF_DEV_GET_NAME(dev_name, sfx)) = { \
2219 .dev = &(DEVICE_NAME_GET(dev_name)), \
2220 .l2 = &(NET_L2_GET_NAME(_l2)), \
2221 .l2_data = &(NET_L2_GET_DATA(dev_name, sfx)), \
2222 .mtu = _mtu, \
2223 }; \
2224 static Z_DECL_ALIGN(struct net_if) \
2225 NET_IF_GET_NAME(dev_name, sfx)[_num_configs] \
2226 __used __in_section(_net_if, static, \
2227 dev_name) = { \
2228 [0 ... (_num_configs - 1)] = { \
2229 .if_dev = &(NET_IF_DEV_GET_NAME(dev_name, sfx)), \
2230 NET_IF_CONFIG_INIT \
2231 } \
2232 }
2233
2234 #define NET_IF_OFFLOAD_INIT(dev_name, sfx, _mtu) \
2235 static STRUCT_SECTION_ITERABLE(net_if_dev, \
2236 NET_IF_DEV_GET_NAME(dev_name, sfx)) = { \
2237 .dev = &(DEVICE_NAME_GET(dev_name)), \
2238 .mtu = _mtu, \
2239 }; \
2240 static Z_DECL_ALIGN(struct net_if) \
2241 NET_IF_GET_NAME(dev_name, sfx)[NET_IF_MAX_CONFIGS] \
2242 __used __in_section(_net_if, static, \
2243 dev_name) = { \
2244 [0 ... (NET_IF_MAX_CONFIGS - 1)] = { \
2245 .if_dev = &(NET_IF_DEV_GET_NAME(dev_name, sfx)), \
2246 NET_IF_CONFIG_INIT \
2247 } \
2248 }
2249
2250 /** @endcond */
2251
2252 /* Network device initialization macros */
2253
2254 #define Z_NET_DEVICE_INIT(node_id, dev_name, drv_name, init_fn, \
2255 pm_control_fn, data, cfg, prio, api, l2, \
2256 l2_ctx_type, mtu) \
2257 Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
2258 pm_control_fn, data, \
2259 cfg, POST_KERNEL, prio, api); \
2260 NET_L2_DATA_INIT(dev_name, 0, l2_ctx_type); \
2261 NET_IF_INIT(dev_name, 0, l2, mtu, NET_IF_MAX_CONFIGS)
2262
2263 /**
2264 * @def NET_DEVICE_INIT
2265 *
2266 * @brief Create a network interface and bind it to network device.
2267 *
2268 * @param dev_name Network device name.
2269 * @param drv_name The name this instance of the driver exposes to
2270 * the system.
2271 * @param init_fn Address to the init function of the driver.
2272 * @param pm_control_fn Pointer to pm_control function.
2273 * Can be NULL if not implemented.
2274 * @param data Pointer to the device's private data.
2275 * @param cfg The address to the structure containing the
2276 * configuration information for this instance of the driver.
2277 * @param prio The initialization level at which configuration occurs.
2278 * @param api Provides an initial pointer to the API function struct
2279 * used by the driver. Can be NULL.
2280 * @param l2 Network L2 layer for this network interface.
2281 * @param l2_ctx_type Type of L2 context data.
2282 * @param mtu Maximum transfer unit in bytes for this network interface.
2283 */
2284 #define NET_DEVICE_INIT(dev_name, drv_name, init_fn, pm_control_fn, \
2285 data, cfg, prio, api, l2, \
2286 l2_ctx_type, mtu) \
2287 Z_NET_DEVICE_INIT(DT_INVALID_NODE, dev_name, drv_name, init_fn, \
2288 pm_control_fn, data, cfg, prio, api, l2, \
2289 l2_ctx_type, mtu)
2290
2291 /**
2292 * @def NET_DEVICE_DT_DEFINE
2293 *
2294 * @brief Like NET_DEVICE_INIT but taking metadata from a devicetree node.
2295 * Create a network interface and bind it to network device.
2296 *
2297 * @param node_id The devicetree node identifier.
2298 * @param init_fn Address to the init function of the driver.
2299 * @param pm_control_fn Pointer to pm_control function.
2300 * Can be NULL if not implemented.
2301 * @param data Pointer to the device's private data.
2302 * @param cfg The address to the structure containing the
2303 * configuration information for this instance of the driver.
2304 * @param prio The initialization level at which configuration occurs.
2305 * @param api Provides an initial pointer to the API function struct
2306 * used by the driver. Can be NULL.
2307 * @param l2 Network L2 layer for this network interface.
2308 * @param l2_ctx_type Type of L2 context data.
2309 * @param mtu Maximum transfer unit in bytes for this network interface.
2310 */
2311 #define NET_DEVICE_DT_DEFINE(node_id, init_fn, pm_control_fn, data, cfg, \
2312 prio, api, l2, l2_ctx_type, mtu) \
2313 Z_NET_DEVICE_INIT(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
2314 DT_PROP_OR(node_id, label, ""), init_fn, \
2315 pm_control_fn, data, cfg, prio, api, l2, \
2316 l2_ctx_type, mtu)
2317
2318 /**
2319 * @def NET_DEVICE_DT_INST_DEFINE
2320 *
2321 * @brief Like NET_DEVICE_DT_DEFINE for an instance of a DT_DRV_COMPAT compatible
2322 *
2323 * @param inst instance number. This is replaced by
2324 * <tt>DT_DRV_COMPAT(inst)</tt> in the call to NET_DEVICE_DT_DEFINE.
2325 *
2326 * @param ... other parameters as expected by NET_DEVICE_DT_DEFINE.
2327 */
2328 #define NET_DEVICE_DT_INST_DEFINE(inst, ...) \
2329 NET_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
2330
2331 #define Z_NET_DEVICE_INIT_INSTANCE(node_id, dev_name, drv_name, \
2332 instance, init_fn, pm_control_fn, \
2333 data, cfg, prio, api, l2, \
2334 l2_ctx_type, mtu) \
2335 Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
2336 pm_control_fn, data, cfg, POST_KERNEL, \
2337 prio, api); \
2338 NET_L2_DATA_INIT(dev_name, instance, l2_ctx_type); \
2339 NET_IF_INIT(dev_name, instance, l2, mtu, NET_IF_MAX_CONFIGS)
2340
2341 /**
2342 * @def NET_DEVICE_INIT_INSTANCE
2343 *
2344 * @brief Create multiple network interfaces and bind them to network device.
2345 * If your network device needs more than one instance of a network interface,
2346 * use this macro below and provide a different instance suffix each time
2347 * (0, 1, 2, ... or a, b, c ... whatever works for you)
2348 *
2349 * @param dev_name Network device name.
2350 * @param drv_name The name this instance of the driver exposes to
2351 * the system.
2352 * @param instance Instance identifier.
2353 * @param init_fn Address to the init function of the driver.
2354 * @param pm_control_fn Pointer to pm_control function.
2355 * Can be NULL if not implemented.
2356 * @param data Pointer to the device's private data.
2357 * @param cfg The address to the structure containing the
2358 * configuration information for this instance of the driver.
2359 * @param prio The initialization level at which configuration occurs.
2360 * @param api Provides an initial pointer to the API function struct
2361 * used by the driver. Can be NULL.
2362 * @param l2 Network L2 layer for this network interface.
2363 * @param l2_ctx_type Type of L2 context data.
2364 * @param mtu Maximum transfer unit in bytes for this network interface.
2365 */
2366 #define NET_DEVICE_INIT_INSTANCE(dev_name, drv_name, instance, init_fn, \
2367 pm_control_fn, data, cfg, prio, \
2368 api, l2, l2_ctx_type, mtu) \
2369 Z_NET_DEVICE_INIT_INSTANCE(DT_INVALID_NODE, dev_name, drv_name, \
2370 instance, init_fn, pm_control_fn, \
2371 data, cfg, prio, api, l2, \
2372 l2_ctx_type, mtu)
2373
2374 /**
2375 * @def NET_DEVICE_DT_DEFINE_INSTANCE
2376 *
2377 * @brief Like NET_DEVICE_OFFLOAD_INIT but taking metadata from a devicetree.
2378 * Create multiple network interfaces and bind them to network device.
2379 * If your network device needs more than one instance of a network interface,
2380 * use this macro below and provide a different instance suffix each time
2381 * (0, 1, 2, ... or a, b, c ... whatever works for you)
2382 *
2383 * @param node_id The devicetree node identifier.
2384 * @param instance Instance identifier.
2385 * @param init_fn Address to the init function of the driver.
2386 * @param pm_control_fn Pointer to pm_control function.
2387 * Can be NULL if not implemented.
2388 * @param data Pointer to the device's private data.
2389 * @param cfg The address to the structure containing the
2390 * configuration information for this instance of the driver.
2391 * @param prio The initialization level at which configuration occurs.
2392 * @param api Provides an initial pointer to the API function struct
2393 * used by the driver. Can be NULL.
2394 * @param l2 Network L2 layer for this network interface.
2395 * @param l2_ctx_type Type of L2 context data.
2396 * @param mtu Maximum transfer unit in bytes for this network interface.
2397 */
2398 #define NET_DEVICE_DT_DEFINE_INSTANCE(node_id, instance, init_fn, \
2399 pm_control_fn, data, cfg, prio, \
2400 api, l2, l2_ctx_type, mtu) \
2401 Z_NET_DEVICE_INIT_INSTANCE(node_id, node_id, DT_LABEL(node_id), \
2402 instance, init_fn, pm_control_fn, \
2403 data, cfg, prio, api, l2, \
2404 l2_ctx_type, mtu)
2405
2406 /**
2407 * @def NET_DEVICE_DT_INST_DEFINE_INSTANCE
2408 *
2409 * @brief Like NET_DEVICE_DT_DEFINE_INSTANCE for an instance of a DT_DRV_COMPAT
2410 * compatible
2411 *
2412 * @param inst instance number. This is replaced by
2413 * <tt>DT_DRV_COMPAT(inst)</tt> in the call to NET_DEVICE_DT_DEFINE_INSTANCE.
2414 *
2415 * @param ... other parameters as expected by NET_DEVICE_DT_DEFINE_INSTANCE.
2416 */
2417 #define NET_DEVICE_DT_INST_DEFINE_INSTANCE(inst, ...) \
2418 NET_DEVICE_DT_DEFINE_INSTANCE(DT_DRV_INST(inst), __VA_ARGS__)
2419
2420 #define Z_NET_DEVICE_OFFLOAD_INIT(node_id, dev_name, drv_name, init_fn, \
2421 pm_control_fn, data, cfg, prio, \
2422 api, mtu) \
2423 Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
2424 pm_control_fn, data, cfg, POST_KERNEL, prio, api);\
2425 NET_IF_OFFLOAD_INIT(dev_name, 0, mtu)
2426
2427 /**
2428 * @def NET_DEVICE_OFFLOAD_INIT
2429 *
2430 * @brief Create a offloaded network interface and bind it to network device.
2431 * The offloaded network interface is implemented by a device vendor HAL or
2432 * similar.
2433 *
2434 * @param dev_name Network device name.
2435 * @param drv_name The name this instance of the driver exposes to
2436 * the system.
2437 * @param init_fn Address to the init function of the driver.
2438 * @param pm_control_fn Pointer to pm_control function.
2439 * Can be NULL if not implemented.
2440 * @param data Pointer to the device's private data.
2441 * @param cfg The address to the structure containing the
2442 * configuration information for this instance of the driver.
2443 * @param prio The initialization level at which configuration occurs.
2444 * @param api Provides an initial pointer to the API function struct
2445 * used by the driver. Can be NULL.
2446 * @param mtu Maximum transfer unit in bytes for this network interface.
2447 */
2448 #define NET_DEVICE_OFFLOAD_INIT(dev_name, drv_name, init_fn, \
2449 pm_control_fn, data, cfg, prio, api, mtu)\
2450 Z_NET_DEVICE_OFFLOAD_INIT(DT_INVALID_NODE, dev_name, drv_name, \
2451 init_fn, pm_control_fn, data, cfg, prio,\
2452 api, mtu)
2453
2454 /**
2455 * @def NET_DEVICE_DT_OFFLOAD_DEFINE
2456 *
2457 * @brief Like NET_DEVICE_OFFLOAD_INIT but taking metadata from a devicetree
2458 * node. Create a offloaded network interface and bind it to network device.
2459 * The offloaded network interface is implemented by a device vendor HAL or
2460 * similar.
2461 *
2462 * @param node_id The devicetree node identifier.
2463 * @param init_fn Address to the init function of the driver.
2464 * @param pm_control_fn Pointer to pm_control function.
2465 * Can be NULL if not implemented.
2466 * @param data Pointer to the device's private data.
2467 * @param cfg The address to the structure containing the
2468 * configuration information for this instance of the driver.
2469 * @param prio The initialization level at which configuration occurs.
2470 * @param api Provides an initial pointer to the API function struct
2471 * used by the driver. Can be NULL.
2472 * @param mtu Maximum transfer unit in bytes for this network interface.
2473 */
2474 #define NET_DEVICE_DT_OFFLOAD_DEFINE(node_id, init_fn, pm_control_fn, \
2475 data, cfg, prio, api, mtu) \
2476 Z_NET_DEVICE_OFFLOAD_INIT(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
2477 DT_PROP_OR(node_id, label, NULL), \
2478 init_fn, pm_control_fn, data, cfg, \
2479 prio, api, mtu)
2480
2481 /**
2482 * @def NET_DEVICE_DT_INST_OFFLOAD_DEFINE
2483 *
2484 * @brief Like NET_DEVICE_DT_OFFLOAD_DEFINE for an instance of a DT_DRV_COMPAT
2485 * compatible
2486 *
2487 * @param inst instance number. This is replaced by
2488 * <tt>DT_DRV_COMPAT(inst)</tt> in the call to NET_DEVICE_DT_OFFLOAD_DEFINE.
2489 *
2490 * @param ... other parameters as expected by NET_DEVICE_DT_OFFLOAD_DEFINE.
2491 */
2492 #define NET_DEVICE_DT_INST_OFFLOAD_DEFINE(inst, ...) \
2493 NET_DEVICE_DT_OFFLOAD_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
2494
2495 #ifdef __cplusplus
2496 }
2497 #endif
2498
2499 #include <syscalls/net_if.h>
2500
2501 /**
2502 * @}
2503 */
2504
2505 #endif /* ZEPHYR_INCLUDE_NET_NET_IF_H_ */
2506