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