1 /** @file
2  @brief IPv6 data handler
3 
4  This is not to be included by the application.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef __IPV6_H
14 #define __IPV6_H
15 
16 #include <zephyr/types.h>
17 
18 #include <zephyr/net/net_ip.h>
19 #include <zephyr/net/net_pkt.h>
20 #include <zephyr/net/net_if.h>
21 #include <zephyr/net/net_context.h>
22 
23 #include "icmpv6.h"
24 #include "nbr.h"
25 
26 #define NET_IPV6_ND_HOP_LIMIT 255
27 #define NET_IPV6_ND_INFINITE_LIFETIME 0xFFFFFFFF
28 
29 #define NET_IPV6_DEFAULT_PREFIX_LEN 64
30 
31 #define NET_MAX_RS_COUNT 3
32 
33 #define NET_IPV6_DSCP_MASK 0xFC
34 #define NET_IPV6_DSCP_OFFSET 2
35 #define NET_IPV6_ECN_MASK 0x03
36 
37 /**
38  * @brief Bitmaps for IPv6 extension header processing
39  *
40  * When processing extension headers, we record which one we have seen.
41  * This is done as the network packet cannot have twice the same header,
42  * except for destination option.
43  * This information is stored in bitfield variable.
44  * The order of the bitmap is the order recommended in RFC 2460.
45  */
46 #define NET_IPV6_EXT_HDR_BITMAP_HBHO   0x01
47 #define NET_IPV6_EXT_HDR_BITMAP_DESTO1 0x02
48 #define NET_IPV6_EXT_HDR_BITMAP_ROUTING        0x04
49 #define NET_IPV6_EXT_HDR_BITMAP_FRAG   0x08
50 #define NET_IPV6_EXT_HDR_BITMAP_AH     0x10
51 #define NET_IPV6_EXT_HDR_BITMAP_ESP    0x20
52 #define NET_IPV6_EXT_HDR_BITMAP_DESTO2 0x40
53 
54 /**
55  * @brief Destination and Hop By Hop extension headers option types
56  */
57 #define NET_IPV6_EXT_HDR_OPT_PAD1  0
58 #define NET_IPV6_EXT_HDR_OPT_PADN  1
59 #define NET_IPV6_EXT_HDR_OPT_RPL   0x63
60 
61 /**
62  * @brief Multicast Listener Record v2 record types.
63  */
64 #define NET_IPV6_MLDv2_MODE_IS_INCLUDE        1
65 #define NET_IPV6_MLDv2_MODE_IS_EXCLUDE        2
66 #define NET_IPV6_MLDv2_CHANGE_TO_INCLUDE_MODE 3
67 #define NET_IPV6_MLDv2_CHANGE_TO_EXCLUDE_MODE 4
68 #define NET_IPV6_MLDv2_ALLOW_NEW_SOURCES      5
69 #define NET_IPV6_MLDv2_BLOCK_OLD_SOURCES      6
70 
71 /* State of the neighbor */
72 enum net_ipv6_nbr_state {
73 	NET_IPV6_NBR_STATE_INCOMPLETE,
74 	NET_IPV6_NBR_STATE_REACHABLE,
75 	NET_IPV6_NBR_STATE_STALE,
76 	NET_IPV6_NBR_STATE_DELAY,
77 	NET_IPV6_NBR_STATE_PROBE,
78 	NET_IPV6_NBR_STATE_STATIC,
79 };
80 
81 const char *net_ipv6_nbr_state2str(enum net_ipv6_nbr_state state);
82 
83 /**
84  * @brief IPv6 neighbor information.
85  */
86 struct net_ipv6_nbr_data {
87 	/** Any pending packet waiting ND to finish. */
88 	struct k_fifo pending_queue;
89 
90 	/** IPv6 address. */
91 	struct in6_addr addr;
92 
93 	/** Reachable timer. */
94 	int64_t reachable;
95 
96 	/** Reachable timeout */
97 	int32_t reachable_timeout;
98 
99 	/** Neighbor Solicitation reply timer */
100 	int64_t send_ns;
101 
102 	/** State of the neighbor discovery */
103 	enum net_ipv6_nbr_state state;
104 
105 	/** Link metric for the neighbor */
106 	uint16_t link_metric;
107 
108 	/** How many times we have sent NS */
109 	uint8_t ns_count;
110 
111 	/** Is the neighbor a router */
112 	bool is_router : 1;
113 
114 	/** Have we initialized the pending queue */
115 	bool pending_queue_initialized : 1;
116 
117 #if defined(CONFIG_NET_IPV6_NBR_CACHE) || defined(CONFIG_NET_IPV6_ND)
118 	/** Stale counter used to removed oldest nbr in STALE state,
119 	 *  when table is full.
120 	 */
121 	uint32_t stale_counter;
122 #endif
123 };
124 
net_ipv6_nbr_data(struct net_nbr * nbr)125 static inline struct net_ipv6_nbr_data *net_ipv6_nbr_data(struct net_nbr *nbr)
126 {
127 	return (struct net_ipv6_nbr_data *)nbr->data;
128 }
129 
130 #if defined(CONFIG_NET_IPV6_DAD)
131 int net_ipv6_start_dad(struct net_if *iface, struct net_if_addr *ifaddr);
132 #endif
133 
134 int net_ipv6_send_ns(struct net_if *iface, struct net_pkt *pending,
135 		     const struct in6_addr *src, const struct in6_addr *dst,
136 		     const struct in6_addr *tgt, bool is_my_address);
137 
138 int net_ipv6_send_rs(struct net_if *iface);
139 int net_ipv6_start_rs(struct net_if *iface);
140 
141 int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
142 		     const struct in6_addr *dst, const struct in6_addr *tgt,
143 		     uint8_t flags);
144 
145 
net_ipv6_is_nexthdr_upper_layer(uint8_t nexthdr)146 static inline bool net_ipv6_is_nexthdr_upper_layer(uint8_t nexthdr)
147 {
148 	return (nexthdr == IPPROTO_ICMPV6 || nexthdr == IPPROTO_UDP ||
149 		nexthdr == IPPROTO_TCP ||
150 		(IS_ENABLED(CONFIG_NET_L2_VIRTUAL) &&
151 		 ((nexthdr == IPPROTO_IPV6) || (nexthdr == IPPROTO_IPIP))));
152 }
153 
154 /**
155  * @brief Create IPv6 packet in provided net_pkt.
156  *
157  * @param pkt Network packet
158  * @param src Source IPv6 address
159  * @param dst Destination IPv6 address
160  *
161  * @return 0 on success, negative errno otherwise.
162  */
163 #if defined(CONFIG_NET_NATIVE_IPV6)
164 int net_ipv6_create(struct net_pkt *pkt,
165 		    const struct in6_addr *src,
166 		    const struct in6_addr *dst);
167 #else
net_ipv6_create(struct net_pkt * pkt,const struct in6_addr * src,const struct in6_addr * dst)168 static inline int net_ipv6_create(struct net_pkt *pkt,
169 				  const struct in6_addr *src,
170 				  const struct in6_addr *dst)
171 {
172 	ARG_UNUSED(pkt);
173 	ARG_UNUSED(src);
174 	ARG_UNUSED(dst);
175 
176 	return -ENOTSUP;
177 }
178 #endif
179 
180 /**
181  * @brief Finalize IPv6 packet. It should be called right before
182  * sending the packet and after all the data has been added into
183  * the packet. This function will set the length of the
184  * packet and calculate the higher protocol checksum if needed.
185  *
186  * @param pkt Network packet
187  * @param next_header_proto Protocol type of the next header after IPv6 header.
188  *
189  * @return 0 on success, negative errno otherwise.
190  */
191 #if defined(CONFIG_NET_NATIVE_IPV6)
192 int net_ipv6_finalize(struct net_pkt *pkt, uint8_t next_header_proto);
193 #else
net_ipv6_finalize(struct net_pkt * pkt,uint8_t next_header_proto)194 static inline int net_ipv6_finalize(struct net_pkt *pkt,
195 				    uint8_t next_header_proto)
196 {
197 	ARG_UNUSED(pkt);
198 	ARG_UNUSED(next_header_proto);
199 
200 	return -ENOTSUP;
201 }
202 #endif
203 
204 /**
205  * @brief Send MLDv2 report message with a single entry.
206  *
207  * @param iface Network interface where message is sent
208  * @param addr Multicast group
209  * @param mode MLDv2 mode (NET_IPV6_MLDv2_MODE_IS_INCLUDE NET_IPV6_MLDv2_MODE_IS_EXCLUDE)
210  *
211  * @return Return 0 if leaving is done, <0 otherwise.
212  */
213 #if defined(CONFIG_NET_IPV6_MLD)
214 int net_ipv6_mld_send_single(struct net_if *iface, const struct in6_addr *addr, uint8_t mode);
215 #else
216 static inline int
net_ipv6_mld_send_single(struct net_if * iface,const struct in6_addr * addr,uint8_t mode)217 net_ipv6_mld_send_single(struct net_if *iface, const struct in6_addr *addr, uint8_t mode)
218 {
219 	ARG_UNUSED(iface);
220 	ARG_UNUSED(addr);
221 	ARG_UNUSED(mode);
222 
223 	return -ENOTSUP;
224 }
225 #endif /* CONFIG_NET_IPV6_MLD */
226 
227 /**
228  * @typedef net_nbr_cb_t
229  * @brief Callback used while iterating over neighbors.
230  *
231  * @param nbr A valid pointer on current neighbor.
232  * @param user_data A valid pointer on some user data or NULL
233  */
234 typedef void (*net_nbr_cb_t)(struct net_nbr *nbr, void *user_data);
235 
236 /**
237  * @brief Make sure the link layer address is set according to
238  * destination address. If the ll address is not yet known, then
239  * start neighbor discovery to find it out. If ND needs to be done
240  * then the returned packet is the Neighbor Solicitation message
241  * and the original message is sent after Neighbor Advertisement
242  * message is received.
243  *
244  * @param pkt Network packet
245  *
246  * @return Return a verdict.
247  */
248 #if defined(CONFIG_NET_IPV6_NBR_CACHE) && defined(CONFIG_NET_NATIVE_IPV6)
249 enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt);
250 #else
net_ipv6_prepare_for_send(struct net_pkt * pkt)251 static inline enum net_verdict net_ipv6_prepare_for_send(struct net_pkt *pkt)
252 {
253 	return NET_OK;
254 }
255 #endif
256 
257 /**
258  * @brief Lock IPv6 Neighbor table mutex
259  *
260  * Neighbor table mutex is used by IPv6 Neighbor cache and IPv6 Routing module.
261  * Mutex shall be held whenever accessing or manipulating neighbor or routing
262  * table entries (for example when obtaining a pointer to the neighbor table
263  * entry). Neighbor and Routing API functions will lock the mutex when called.
264  */
265 void net_ipv6_nbr_lock(void);
266 
267 /**
268  * @brief Unlock IPv6 Neighbor table mutex
269  */
270 void net_ipv6_nbr_unlock(void);
271 
272 /**
273  * @brief Look for a neighbor from it's address on an iface
274  *
275  * @param iface A valid pointer on a network interface
276  * @param addr The IPv6 address to match
277  *
278  * @return A valid pointer on a neighbor on success, NULL otherwise
279  */
280 #if defined(CONFIG_NET_IPV6_NBR_CACHE) && defined(CONFIG_NET_NATIVE_IPV6)
281 struct net_nbr *net_ipv6_nbr_lookup(struct net_if *iface,
282 				    struct in6_addr *addr);
283 #else
net_ipv6_nbr_lookup(struct net_if * iface,struct in6_addr * addr)284 static inline struct net_nbr *net_ipv6_nbr_lookup(struct net_if *iface,
285 						  struct in6_addr *addr)
286 {
287 	return NULL;
288 }
289 #endif
290 
291 /**
292  * @brief Get neighbor from its index.
293  *
294  * @param iface Network interface to match. If NULL, then use
295  * whatever interface there is configured for the neighbor address.
296  * @param idx Index of the link layer address in the address array
297  *
298  * @return A valid pointer on a neighbor on success, NULL otherwise
299  */
300 struct net_nbr *net_ipv6_get_nbr(struct net_if *iface, uint8_t idx);
301 
302 /**
303  * @brief Look for a neighbor from it's link local address index
304  *
305  * @param iface Network interface to match. If NULL, then use
306  * whatever interface there is configured for the neighbor address.
307  * @param idx Index of the link layer address in the address array
308  *
309  * @return A valid pointer on a neighbor on success, NULL otherwise
310  */
311 #if defined(CONFIG_NET_IPV6_NBR_CACHE) && defined(CONFIG_NET_NATIVE_IPV6)
312 struct in6_addr *net_ipv6_nbr_lookup_by_index(struct net_if *iface,
313 					      uint8_t idx);
314 #else
315 static inline
net_ipv6_nbr_lookup_by_index(struct net_if * iface,uint8_t idx)316 struct in6_addr *net_ipv6_nbr_lookup_by_index(struct net_if *iface,
317 					      uint8_t idx)
318 {
319 	return NULL;
320 }
321 #endif
322 
323 /**
324  * @brief Add a neighbor to neighbor cache
325  *
326  * Add a neighbor to the cache after performing a lookup and in case
327  * there exists an entry in the cache update its state and lladdr.
328  *
329  * @param iface A valid pointer on a network interface
330  * @param addr Neighbor IPv6 address
331  * @param lladdr Neighbor link layer address
332  * @param is_router Set to true if the neighbor is a router, false
333  * otherwise
334  * @param state Initial state of the neighbor entry in the cache
335  *
336  * @return A valid pointer on a neighbor on success, NULL otherwise
337  */
338 #if defined(CONFIG_NET_IPV6_NBR_CACHE) && defined(CONFIG_NET_NATIVE_IPV6)
339 struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
340 				 const struct in6_addr *addr,
341 				 const struct net_linkaddr *lladdr,
342 				 bool is_router,
343 				 enum net_ipv6_nbr_state state);
344 #else
net_ipv6_nbr_add(struct net_if * iface,const struct in6_addr * addr,const struct net_linkaddr * lladdr,bool is_router,enum net_ipv6_nbr_state state)345 static inline struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
346 					       const struct in6_addr *addr,
347 					       const struct net_linkaddr *lladdr,
348 					       bool is_router,
349 					       enum net_ipv6_nbr_state state)
350 {
351 	return NULL;
352 }
353 #endif
354 
355 /**
356  * @brief Remove a neighbor from neighbor cache.
357  *
358  * @param iface A valid pointer on a network interface
359  * @param addr Neighbor IPv6 address
360  *
361  * @return True if neighbor could be removed, False otherwise
362  */
363 #if defined(CONFIG_NET_IPV6_NBR_CACHE) && defined(CONFIG_NET_NATIVE_IPV6)
364 bool net_ipv6_nbr_rm(struct net_if *iface, struct in6_addr *addr);
365 #else
net_ipv6_nbr_rm(struct net_if * iface,struct in6_addr * addr)366 static inline bool net_ipv6_nbr_rm(struct net_if *iface, struct in6_addr *addr)
367 {
368 	return true;
369 }
370 #endif
371 
372 /**
373  * @brief Go through all the neighbors and call callback for each of them.
374  *
375  * @param cb User supplied callback function to call.
376  * @param user_data User specified data.
377  */
378 #if defined(CONFIG_NET_IPV6_NBR_CACHE) && defined(CONFIG_NET_NATIVE_IPV6)
379 void net_ipv6_nbr_foreach(net_nbr_cb_t cb, void *user_data);
380 #else /* CONFIG_NET_IPV6_NBR_CACHE */
net_ipv6_nbr_foreach(net_nbr_cb_t cb,void * user_data)381 static inline void net_ipv6_nbr_foreach(net_nbr_cb_t cb, void *user_data)
382 {
383 	return;
384 }
385 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
386 
387 /**
388  * @brief Provide a reachability hint for IPv6 Neighbor Discovery.
389  *
390  * This function is intended for upper-layer protocols to inform the IPv6
391  * Neighbor Discovery process about the active link to a specific neighbor.
392  * By signaling recent "forward progress" event, such as the reception of
393  * an ACK, this function can help reducing unnecessary ND traffic as per the
394  * guidelines in RFC 4861 (section 7.3).
395  *
396  * @param iface A pointer to the network interface.
397  * @param ipv6_addr Pointer to the IPv6 address of the neighbor node.
398  */
399 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
400 void net_ipv6_nbr_reachability_hint(struct net_if *iface, const struct in6_addr *ipv6_addr);
401 #else
net_ipv6_nbr_reachability_hint(struct net_if * iface,const struct in6_addr * ipv6_addr)402 static inline void net_ipv6_nbr_reachability_hint(struct net_if *iface,
403 						  const struct in6_addr *ipv6_addr)
404 {
405 	ARG_UNUSED(iface);
406 	ARG_UNUSED(ipv6_addr);
407 }
408 #endif
409 
410 /**
411  * @brief Set the neighbor reachable timer.
412  *
413  * @param iface A valid pointer on a network interface
414  * @param nbr Neighbor struct pointer
415  */
416 #if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
417 void net_ipv6_nbr_set_reachable_timer(struct net_if *iface,
418 				      struct net_nbr *nbr);
419 
420 #else /* CONFIG_NET_IPV6_ND */
net_ipv6_nbr_set_reachable_timer(struct net_if * iface,struct net_nbr * nbr)421 static inline void net_ipv6_nbr_set_reachable_timer(struct net_if *iface,
422 						    struct net_nbr *nbr)
423 {
424 }
425 #endif
426 
427 #if defined(CONFIG_NET_IPV6_FRAGMENT)
428 /** Store pending IPv6 fragment information that is needed for reassembly. */
429 struct net_ipv6_reassembly {
430 	/** IPv6 source address of the fragment */
431 	struct in6_addr src;
432 
433 	/** IPv6 destination address of the fragment */
434 	struct in6_addr dst;
435 
436 	/**
437 	 * Timeout for cancelling the reassembly. The timer is used
438 	 * also to detect if this reassembly slot is used or not.
439 	 */
440 	struct k_work_delayable timer;
441 
442 	/** Pointers to pending fragments */
443 	struct net_pkt *pkt[CONFIG_NET_IPV6_FRAGMENT_MAX_PKT];
444 
445 	/** IPv6 fragment identification */
446 	uint32_t id;
447 };
448 #else
449 struct net_ipv6_reassembly;
450 #endif
451 
452 /**
453  * @typedef net_ipv6_frag_cb_t
454  * @brief Callback used while iterating over pending IPv6 fragments.
455  *
456  * @param reass IPv6 fragment reassembly struct
457  * @param user_data A valid pointer on some user data or NULL
458  */
459 typedef void (*net_ipv6_frag_cb_t)(struct net_ipv6_reassembly *reass,
460 				   void *user_data);
461 
462 /**
463  * @brief Go through all the currently pending IPv6 fragments.
464  *
465  * @param cb Callback to call for each pending IPv6 fragment.
466  * @param user_data User specified data or NULL.
467  */
468 void net_ipv6_frag_foreach(net_ipv6_frag_cb_t cb, void *user_data);
469 
470 /**
471  * @brief Find the last IPv6 extension header in the network packet.
472  *
473  * @param pkt Network head packet.
474  * @param next_hdr_off Offset of the next header field that points
475  * to last header. This is returned to caller.
476  * @param last_hdr_off Offset of the last header field in the packet.
477  * This is returned to caller.
478  *
479  * @return 0 on success, a negative errno otherwise.
480  */
481 int net_ipv6_find_last_ext_hdr(struct net_pkt *pkt, uint16_t *next_hdr_off,
482 			       uint16_t *last_hdr_off);
483 
484 /**
485  * @brief Handles IPv6 fragmented packets.
486  *
487  * @param pkt     Network head packet.
488  * @param hdr     The IPv6 header of the current packet
489  * @param nexthdr IPv6 next header after fragment header part
490  *
491  * @return Return verdict about the packet
492  */
493 #if defined(CONFIG_NET_IPV6_FRAGMENT) && defined(CONFIG_NET_NATIVE_IPV6)
494 enum net_verdict net_ipv6_handle_fragment_hdr(struct net_pkt *pkt,
495 					      struct net_ipv6_hdr *hdr,
496 					      uint8_t nexthdr);
497 #else
498 static inline
net_ipv6_handle_fragment_hdr(struct net_pkt * pkt,struct net_ipv6_hdr * hdr,uint8_t nexthdr)499 enum net_verdict net_ipv6_handle_fragment_hdr(struct net_pkt *pkt,
500 					      struct net_ipv6_hdr *hdr,
501 					      uint8_t nexthdr)
502 {
503 	ARG_UNUSED(pkt);
504 	ARG_UNUSED(hdr);
505 	ARG_UNUSED(nexthdr);
506 
507 	return NET_DROP;
508 }
509 #endif /* CONFIG_NET_IPV6_FRAGMENT */
510 
511 #if defined(CONFIG_NET_NATIVE_IPV6)
512 void net_ipv6_init(void);
513 void net_ipv6_nbr_init(void);
514 #if defined(CONFIG_NET_IPV6_MLD)
515 void net_ipv6_mld_init(void);
516 #else
517 #define net_ipv6_mld_init(...)
518 #endif
519 #else
520 #define net_ipv6_init(...)
521 #define net_ipv6_nbr_init(...)
522 #endif
523 
524 /**
525  * @brief Decode DSCP value from TC field.
526  *
527  * @param tc TC field value from the IPv6 header.
528  *
529  * @return Decoded DSCP value.
530  */
net_ipv6_get_dscp(uint8_t tc)531 static inline uint8_t net_ipv6_get_dscp(uint8_t tc)
532 {
533 	return (tc & NET_IPV6_DSCP_MASK) >> NET_IPV6_DSCP_OFFSET;
534 }
535 
536 /**
537  * @brief Encode DSCP value into TC field.
538  *
539  * @param tc A pointer to the TC field.
540  * @param dscp DSCP value to set.
541  */
net_ipv6_set_dscp(uint8_t * tc,uint8_t dscp)542 static inline void net_ipv6_set_dscp(uint8_t *tc, uint8_t dscp)
543 {
544 	*tc &= ~NET_IPV6_DSCP_MASK;
545 	*tc |= (dscp << NET_IPV6_DSCP_OFFSET) & NET_IPV6_DSCP_MASK;
546 }
547 
548 /**
549  * @brief Convert DSCP value to priority.
550  *
551  * @param dscp DSCP value.
552  */
net_ipv6_dscp_to_priority(uint8_t dscp)553 static inline uint8_t net_ipv6_dscp_to_priority(uint8_t dscp)
554 {
555 	return dscp >> 3;
556 }
557 
558 /**
559  * @brief Decode ECN value from TC field.
560  *
561  * @param tc TC field value from the IPv6 header.
562  *
563  * @return Decoded ECN value.
564  */
net_ipv6_get_ecn(uint8_t tc)565 static inline uint8_t net_ipv6_get_ecn(uint8_t tc)
566 {
567 	return tc & NET_IPV6_ECN_MASK;
568 }
569 
570 /**
571  * @brief Encode ECN value into TC field.
572  *
573  * @param tc A pointer to the TC field.
574  * @param ecn ECN value to set.
575  */
net_ipv6_set_ecn(uint8_t * tc,uint8_t ecn)576 static inline void net_ipv6_set_ecn(uint8_t *tc, uint8_t ecn)
577 {
578 	*tc &= ~NET_IPV6_ECN_MASK;
579 	*tc |= ecn & NET_IPV6_ECN_MASK;
580 }
581 
582 /**
583  * @brief Start IPv6 privacy extension procedure.
584  *
585  * @param iface Interface to use.
586  * @param prefix IPv6 prefix to use.
587  * @param vlifetime Lifetime of this IPv6 prefix (in seconds).
588  * @param preferred_lifetime Preferred lifetime of this IPv6 prefix (in seconds)
589  */
590 #if defined(CONFIG_NET_IPV6_PE)
591 void net_ipv6_pe_start(struct net_if *iface, const struct in6_addr *prefix,
592 		       uint32_t vlifetime, uint32_t preferred_lifetime);
593 
594 #else
net_ipv6_pe_start(struct net_if * iface,const struct in6_addr * prefix,uint32_t vlifetime,uint32_t preferred_lifetime)595 static inline void net_ipv6_pe_start(struct net_if *iface,
596 				     const struct in6_addr *prefix,
597 				     uint32_t vlifetime,
598 				     uint32_t preferred_lifetime)
599 {
600 	ARG_UNUSED(iface);
601 	ARG_UNUSED(prefix);
602 	ARG_UNUSED(vlifetime);
603 	ARG_UNUSED(preferred_lifetime);
604 }
605 #endif /* CONFIG_NET_IPV6_PE */
606 
607 /**
608  * @brief Check if maximum number of Duplicate Address Detection (DAD) requests
609  *        have been done.
610  *
611  * @param count Number of DAD requests done.
612  *
613  * @return Return True if DAD can continue, False if max amount of DAD
614  *         requests have been done.
615  */
616 #if defined(CONFIG_NET_IPV6_PE)
617 bool net_ipv6_pe_check_dad(int count);
618 #else
net_ipv6_pe_check_dad(int count)619 static inline bool net_ipv6_pe_check_dad(int count)
620 {
621 	ARG_UNUSED(count);
622 
623 	return false;
624 }
625 #endif /* CONFIG_NET_IPV6_PE */
626 
627 /**
628  * @brief Initialize IPv6 privacy extension support for a network interface.
629  *
630  * @param iface Network interface
631  *
632  * @return Return 0 if ok or <0 if there is an error.
633  */
634 #if defined(CONFIG_NET_IPV6_PE)
635 int net_ipv6_pe_init(struct net_if *iface);
636 #else
net_ipv6_pe_init(struct net_if * iface)637 static inline int net_ipv6_pe_init(struct net_if *iface)
638 {
639 	iface->pe_enabled = false;
640 	iface->pe_prefer_public = false;
641 
642 	return 0;
643 }
644 #endif /* CONFIG_NET_IPV6_PE */
645 
646 typedef void (*net_ipv6_pe_filter_cb_t)(struct in6_addr *prefix,
647 					bool is_denylist,
648 					void *user_data);
649 
650 /**
651  * @brief Go through all the IPv6 privacy extension filters and call callback
652  * for each IPv6 prefix.
653  *
654  * @param cb User supplied callback function to call.
655  * @param user_data User specified data.
656  *
657  * @return Total number of filters found.
658  */
659 #if defined(CONFIG_NET_IPV6_PE)
660 int net_ipv6_pe_filter_foreach(net_ipv6_pe_filter_cb_t cb, void *user_data);
661 #else
net_ipv6_pe_filter_foreach(net_ipv6_pe_filter_cb_t cb,void * user_data)662 static inline int net_ipv6_pe_filter_foreach(net_ipv6_pe_filter_cb_t cb,
663 					     void *user_data)
664 {
665 	ARG_UNUSED(cb);
666 	ARG_UNUSED(user_data);
667 
668 	return 0;
669 }
670 #endif
671 
672 #endif /* __IPV6_H */
673