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