Blame view

RIOT/sys/include/net/gnrc/ndp.h 20 KB
a752c7ab   elopes   add first test an...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  /*
   * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
   *
   * This file is subject to the terms and conditions of the GNU Lesser General
   * Public License v2.1. See the file LICENSE in the top level directory for
   * more details.
   */
  
  /**
   * @defgroup    net_gnrc_ndp  IPv6 Neighbor discovery
   * @ingroup     net_gnrc_icmpv6
   * @brief       GNRC's IPv6 Neighbor Discovery implementation
   * @{
   *
   * @file
   * @brief       Definitions for GNRC's IPv6 Neighbor Discovery
   *
   * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
   */
  
  #ifndef NET_GNRC_NDP_H
  #define NET_GNRC_NDP_H
  
  #include <inttypes.h>
  #include <stdlib.h>
  
  #include "byteorder.h"
  #include "net/ndp.h"
  #include "net/gnrc/pkt.h"
  #include "net/gnrc/icmpv6.h"
  #include "net/ipv6/addr.h"
  #include "net/gnrc/ipv6/nc.h"
  #include "net/gnrc/ipv6/netif.h"
  
  #include "net/gnrc/ndp/host.h"
  #include "net/gnrc/ndp/internal.h"
  #include "net/gnrc/ndp/router.h"
  #include "net/gnrc/ndp/node.h"
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /** Message type for router timeouts */
  #define GNRC_NDP_MSG_RTR_TIMEOUT                (0x0210)
  /** Message type for address timeouts */
  #define GNRC_NDP_MSG_ADDR_TIMEOUT               (0x0211)
  /** Message type for multicast neighbor solicitation retransmissions */
  #define GNRC_NDP_MSG_NBR_SOL_RETRANS            (0x0212)
  /** Message type for periodic router advertisements */
  #define GNRC_NDP_MSG_RTR_ADV_RETRANS            (0x0213)
  /** Message type for delayed router advertisements */
  #define GNRC_NDP_MSG_RTR_ADV_DELAY              (0x0214)
  /** Message type for delayed router advertisements in a 6LoWPAN
   * 6LoWPAN needs a special handling, because router advertisements are only
   * sent after a short randomized delay, but not periodically. */
  #define GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY    (0x0215)
  /** Message type for periodic router solicitations */
  #define GNRC_NDP_MSG_RTR_SOL_RETRANS            (0x0216)
  /** Message type for neighbor cache state timeouts */
  #define GNRC_NDP_MSG_NC_STATE_TIMEOUT           (0x0217)
  
  /**
   * @name    Host constants
   * @{
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-10">
   *              RFC 4861, section 10
   *          </a>
   */
  /**
   * @brief   Upper bound for randomised delay in seconds for initial
   *          router solicitation transmissions
   */
  #define GNRC_NDP_MAX_RTR_SOL_DELAY      (1U)
  
  /**
   * @brief   Interval in seconds between initial router solicitation
   *          transmissions
   */
  #define GNRC_NDP_MAX_RTR_SOL_INT        (4U)
  
  /**
   * @brief   Maximum number of  initial router solicitation transmissions
   */
  #define GNRC_NDP_MAX_RTR_SOL_NUMOF      (3U)
  /** @} */
  
  /**
   * @name    Node constants
   * @{
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-10">
   *              RFC 4861, section 10
   *          </a>
   */
  /**
   * @brief   Maximum number of unanswered multicast neighbor solicitations
   *          before address resolution is considered failed.
   */
  #define GNRC_NDP_MAX_MC_NBR_SOL_NUMOF   (3U)
  
  /**
   * @brief   Maximum number of unanswered unicast neighbor solicitations before
   *          an address is considered unreachable.
   */
  #define GNRC_NDP_MAX_UC_NBR_SOL_NUMOF   (3U)
  
  /**
   * @brief   Upper bound of randomized delay in seconds for a solicited
   *          neighbor advertisement transmission for an anycast target.
   */
  #define GNRC_NDP_MAX_AC_TGT_DELAY       (1U)
  
  /**
   * @brief   Maximum number of unsolicited neighbor advertisements before on
   *          link-layer address change.
   */
  #define GNRC_NDP_MAX_NBR_ADV_NUMOF      (3U)
  
  /**
   * @brief   Base value in mircoseconds for computing randomised
   *          reachable time.
   */
  #define GNRC_NDP_REACH_TIME             (30U * US_PER_SEC)
  
  /**
   * @brief   Time in mircoseconds between retransmissions of neighbor
   *          solicitations to a neighbor.
   */
  #define GNRC_NDP_RETRANS_TIMER          (1U * US_PER_SEC)
  
  /**
   * @brief   Delay in seconds for neighbor cache entry between entering
   *          DELAY state and entering PROBE state if no reachability
   *          confirmation has been received.
   */
  #define GNRC_NDP_FIRST_PROBE_DELAY      (5U)
  
  /**
   * @brief   Lower bound for randomised reachable time calculation.
   */
  #define GNRC_NDP_MIN_RAND               (5U)
  
  /**
   * @brief   Upper bound for randomised reachable time calculation.
   */
  #define GNRC_NDP_MAX_RAND               (15U)
  /** @} */
  
  /**
   * @name    Router constants
   * @{
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-10">
   *              RFC 4861, section 10
   *          </a>
   */
  /**
   * @brief   Initial router advertisement interval in seconds
   */
  #define GNRC_NDP_MAX_INIT_RTR_ADV_INT   (16U)
  
  /**
   * @brief   Maximum number of initial router advertisement transmissions
   */
  #define GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF (3U)
  
  /**
   * @brief   Maximum number of final router advertisement transmissions
   */
  #define GNRC_NDP_MAX_FIN_RTR_ADV_NUMOF  (3U)
  
  /**
   * @brief   Minimum delay in seconds between router advertisement
   *          transmissions
   */
  #define GNRC_NDP_MIN_RTR_ADV_DELAY      (3U)
  
  /**
   * @brief   Upper bound for randomised delay in microseconds between router
   *          solicitation reception and responding router advertisement
   *          transmission.
   */
  #define GNRC_NDP_MAX_RTR_ADV_DELAY      (500U * US_PER_MS)
  /** @} */
  
  /**
   * @brief   Handles received neighbor solicitations.
   *
   * @param[in] iface         The receiving interface.
   * @param[in] pkt           The received packet.
   * @param[in] ipv6          The IPv6 header in @p pkt.
   * @param[in] nbr_sol       The neighbor solicitation in @p pkt.
   * @param[in] icmpv6_size   The overall size of the neighbor solicitation.
   */
  void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                               ipv6_hdr_t *ipv6, ndp_nbr_sol_t *nbr_sol,
                               size_t icmpv6_size);
  
  /**
   * @brief   Handles received neighbor advertisements.
   *
   * @param[in] iface         The receiving interface.
   * @param[in] pkt           The received packet.
   * @param[in] ipv6          The IPv6 header in @p pkt.
   * @param[in] nbr_adv       The neighbor advertisement in @p pkt.
   * @param[in] icmpv6_size   The overall size of the neighbor advertisement.
   */
  void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                               ipv6_hdr_t *ipv6, ndp_nbr_adv_t *nbr_adv,
                               size_t icmpv6_size);
  
  #if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
  /**
   * @brief   Handles received router solicitations.
   *
   * @param[in] iface         The receiving interface.
   * @param[in] pkt           The received packet.
   * @param[in] ipv6          The IPv6 header in @p pkt.
   * @param[in] rtr_sol       The router solicitation in @p pkt.
   * @param[in] icmpv6_size   The overall size of the router solicitation.
   */
  void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                               ipv6_hdr_t *ipv6, ndp_rtr_sol_t *rtr_sol,
                               size_t icmpv6_size);
  #else
  /**
   * @brief   A host *must* silently discard all received router solicitations.
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-6.2.6">
   *              RFC 4861, section 6.2.6
   *          </a>
   *
   * This macro is primarily an optimization to not go into the function defined
   * above.
   */
  #define gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6, rtr_sol, size)
  #endif
  
  /**
   * @brief   Handles received router advertisements
   *
   * @todo    As router check consistency as described in RFC 4861, section 6.2.3
   *
   * @param[in] iface         The receiving interface.
   * @param[in] pkt           The received packet.
   * @param[in] ipv6          The IPv6 header in @p pkt.
   * @param[in] rtr_adv       The router advertisement in @p pkt.
   * @param[in] icmpv6_size   The overall size of the router advertisement.
   */
  void gnrc_ndp_rtr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                               ipv6_hdr_t *ipv6, ndp_rtr_adv_t *rtr_adv,
                               size_t icmpv6_size);
  
  /**
   * @brief   Retransmits a multicast neighbor solicitation for an incomplete or
   *          probing neighbor cache entry @p nc_entry,
   *          if nc_entry::probes_remaining > 0.
   *
   * @details If nc_entry::probes_remaining > 0 it will be decremented. If it
   *          reaches 0 it the entry @p nc_entry will be removed from the
   *          neighbor cache.
   *
   * @param[in]   nc_entry    A neighbor cache entry. Will be ignored if its state
   *                          is not @ref GNRC_IPV6_NC_STATE_INCOMPLETE or
   *                          @ref GNRC_IPV6_NC_STATE_PROBE.
   */
  void gnrc_ndp_retrans_nbr_sol(gnrc_ipv6_nc_t *nc_entry);
  
  /**
   * @brief   Event handler for a neighbor cache state timeout.
   *
   * @param[in]   nc_entry    A neighbor cache entry.
   */
  void gnrc_ndp_state_timeout(gnrc_ipv6_nc_t *nc_entry);
  
  /**
   * @brief   NDP interface initialization.
   *
   * @param[in] iface     An IPv6 interface descriptor. Must not be NULL.
   */
  void gnrc_ndp_netif_add(gnrc_ipv6_netif_t *iface);
  
  /**
   * @brief   NDP interface removal.
   *
   * @param[in] iface     An IPv6 interface descriptor. Must not be NULL.
   */
  void gnrc_ndp_netif_remove(gnrc_ipv6_netif_t *iface);
  
  /**
   * @brief   Get link-layer address and interface for next hop to destination
   *          IPv6 address.
   *
   * @param[out] l2addr           The link-layer for the next hop to @p dst.
   * @param[out] l2addr_len       Length of @p l2addr.
   * @param[in] iface             The interface to search the next hop on.
   *                              May be @ref KERNEL_PID_UNDEF if not specified.
   * @param[in] dst               An IPv6 address to search the next hop for.
   * @param[in] pkt               Packet to send to @p dst. Leave NULL if you
   *                              just want to get the addresses.
   *
   * @return  The PID of the interface, on success.
   * @return  -EHOSTUNREACH, if @p dst is not reachable.
   * @return  -ENOBUFS, if @p l2addr_len was smaller than the resulting @p l2addr
   *          would be long.
   */
  kernel_pid_t gnrc_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
                                        kernel_pid_t iface, ipv6_addr_t *dst,
                                        gnrc_pktsnip_t *pkt);
  
  /**
   * @brief   Builds a neighbor solicitation message for sending.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.3">
   *          RFC 4861, section 4.3
   *      </a>
   *
   * @param[in] tgt       The target address.
   * @param[in] options   Options to append to the router solicitation.
   *
   * @return  The resulting ICMPv6 packet on success.
   * @return  NULL, on failure.
   */
  gnrc_pktsnip_t *gnrc_ndp_nbr_sol_build(ipv6_addr_t *tgt, gnrc_pktsnip_t *options);
  
  /**
   * @brief   Builds a neighbor advertisement message for sending.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.4">
   *          RFC 4861, section 4.4
   *      </a>
   *
   * @param[in] flags     Neighbor advertisement flags:
   *                      @ref NDP_NBR_ADV_FLAGS_R == 1 indicates, that the
   *                      sender is a router,
   *                      @ref NDP_NBR_ADV_FLAGS_S == 1 indicates that the
   *                      advertisement was sent in response to a neighbor
   *                      solicitation,
   *                      @ref NDP_NBR_ADV_FLAGS_O == 1 indicates that the
   *                      advertisement should override an existing cache entry
   *                      and update the cached link-layer address.
   * @param[in] tgt       For solicited advertisements, the Target Address field
   *                      in the neighbor solicitaton.
   *                      For and unsolicited advertisement, the address whose
   *                      link-layer address has changed.
   *                      MUST NOT be multicast.
   * @param[in] options   Options to append to the neighbor advertisement.
   *
   * @return  The resulting ICMPv6 packet on success.
   * @return  NULL, on failure.
   */
  gnrc_pktsnip_t *gnrc_ndp_nbr_adv_build(uint8_t flags, ipv6_addr_t *tgt,
                                         gnrc_pktsnip_t *options);
  
  /**
   * @brief   Builds a router solicitation message for sending.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1">
   *          RFC 4861, section 4.1
   *      </a>
   *
   * @param[in] options   Options to append to the router solicitation.
   *
   * @return  The resulting ICMPv6 packet on success.
   * @return  NULL, on failure.
   */
  gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);
  
  /**
   * @brief   Builds a router solicitation message for sending.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1">
   *          RFC 4861, section 4.1
   *      </a>
   *
   * @param[in] options   Options to append to the router solicitation.
   *
   * @return  The resulting ICMPv6 packet on success.
   * @return  NULL, on failure.
   */
  gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);
  
  #if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
  /**
   * @brief   Builds a router advertisement message for sending.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.2">
   *          RFC 4861, section 4.2
   *      </a>
   *
   * @note    The source address for the packet MUST be the link-local address
   *          of the interface.
   *
   * @param[in] cur_hl        Default hop limit for outgoing IP packets, 0 if
   *                          unspecified by this router.
   * @param[in] flags         Flags as defined above.
   *                          @ref NDP_RTR_ADV_FLAGS_M == 1 indicates, that the
   *                          addresses are managed by DHCPv6,
   *                          @ref NDP_RTR_ADV_FLAGS_O == 1 indicates that other
   *                          configuration information is available via DHCPv6.
   * @param[in] ltime         Lifetime of the default router in seconds.
   * @param[in] reach_time    Time in milliseconds a node should assume a neighbor
   *                          reachable. 0 means unspecified by the router.
   * @param[in] retrans_timer Time in milliseconds between retransmitted
   *                          neighbor solicitations. 0 means unspecified by
   *                          the router.
   * @param[in] options       Options to append to the router advertisement.
   *
   * @return  The resulting ICMPv6 packet on success.
   * @return  NULL, on failure.
   */
  gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags, uint16_t ltime,
                                         uint32_t reach_time, uint32_t retrans_timer,
                                         gnrc_pktsnip_t *options);
  #else
  /**
   * @brief   A host *must not* send router advertisements at any time (so why build them?)
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
   *              RFC 4861, section 6.3.4
   *          </a>
   *
   * This macro is primarily an optimization to not go into the function defined
   * above.
   */
  #define gnrc_ndp_rtr_adv_build(cur_hl, flags, ltime, reach_time, retrans_timer, options) (NULL)
  #endif
  
  /**
   * @brief   Builds a generic NDP option.
   *
   * @param[in] type  Type of the option.
   * @param[in] size  Size in byte of the option (will be rounded up to the next
   *                  multiple of 8).
   * @param[in] next  More options in the packet. NULL, if there are none.
   *
   * @return  The packet snip list of options, on success
   * @return  NULL, if packet buffer is full
   */
  gnrc_pktsnip_t *gnrc_ndp_opt_build(uint8_t type, size_t size, gnrc_pktsnip_t *next);
  
  /**
   * @brief   Builds the source link-layer address option.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.1">
   *          RFC 4861, section 4.6.1
   *      </a>
   *
   * @note    Must only be used with neighbor solicitations, router solicitations,
   *          and router advertisements. This is not checked however, since
   *          hosts should silently ignore it in other NDP messages.
   *
   * @param[in] l2addr        A link-layer address of variable length.
   * @param[in] l2addr_len    Length of @p l2addr.
   * @param[in] next          More options in the packet. NULL, if there are none.
   *
   * @return  The packet snip list of options, on success
   * @return  NULL, if packet buffer is full
   */
  gnrc_pktsnip_t *gnrc_ndp_opt_sl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
                                          gnrc_pktsnip_t *next);
  
  /**
   * @brief   Builds the target link-layer address option.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.1">
   *          RFC 4861, section 4.6.1
   *      </a>
   *
   * @note    Must only be used with neighbor advertisemnents and redirect packets.
   *          This is not checked however, since hosts should silently ignore it
   *          in other NDP messages.
   *
   * @param[in] l2addr        A link-layer address of variable length.
   * @param[in] l2addr_len    Length of @p l2addr.
   * @param[in] next          More options in the packet. NULL, if there are none.
   *
   * @return  The pkt snip list of options, on success
   * @return  NULL, if packet buffer is full
   */
  gnrc_pktsnip_t *gnrc_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
                                          gnrc_pktsnip_t *next);
  
  #if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
  /**
   * @brief   Builds the prefix information option.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.2">
   *          RFC 4861, section 4.6.2
   *      </a>
   *
   * @note    Must only be used with router advertisemnents. This is not checked
   *          however, since nodes should silently ignore it in other NDP messages.
   *
   * @param[in] prefix_len    The length of @p prefix in bits. Must be between
   *                          0 and 128.
   * @param[in] flags         Flags as defined above.
   *                          @ref NDP_OPT_PI_FLAGS_L == 1 indicates, that
   *                          @p prefix can be used for on-link determination,
   *                          @ref NDP_OPT_PI_FLAGS_A == 1 indicates, that
   *                          @p prefix can be used for stateless address
   *                          configuration.
   * @param[in] valid_ltime   Length of time in seconds that @p prefix is valid.
   *                          UINT32_MAX represents infinity.
   * @param[in] pref_ltime    Length of time in seconds that addresses using
   *                          @p prefix remain prefered. UINT32_MAX represents
   *                          infinity.
   * @param[in] prefix        An IPv6 address or a prefix of an IPv6 address.
   * @param[in] next          More options in the packet. NULL, if there are none.
   *
   * @return  The packet snip list of options, on success
   * @return  NULL, if packet buffer is full
   */
  gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(uint8_t prefix_len, uint8_t flags,
                                        uint32_t valid_ltime, uint32_t pref_ltime,
                                        ipv6_addr_t *prefix, gnrc_pktsnip_t *next);
  
  /**
   * @brief   Builds the MTU option.
   *
   * @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.4">
   *          RFC 4861, section 4.6.4
   *      </a>
   *
   * @note    Must only be used with router advertisemnents. This is not checked
   *          however, since nodes should silently ignore it in other NDP messages.
   *
   * @param[in] mtu           The recommended MTU for the link.
   * @param[in] next          More options in the packet. NULL, if there are none.
   *
   * @return  The packet snip list of options, on success
   * @return  NULL, if packet buffer is full
   */
  gnrc_pktsnip_t *gnrc_ndp_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next);
  #else
  /**
   * @brief   A host *must not* send router advertisements at any time (so why build their options?)
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
   *              RFC 4861, section 6.3.4
   *          </a>
   *
   * This macro is primarily an optimization to not go into the function defined
   * above.
   */
  #define gnrc_ndp_opt_pi_build(prefix_len, flags, valid_ltime, pref_ltime, prefix, next) (NULL)
  
  /**
   * @brief   A host *must not* send router advertisements at any time (so why build their options?)
   * @see     <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
   *              RFC 4861, section 6.3.4
   *          </a>
   *
   * This macro is primarily an optimization to not go into the function defined
   * above.
   */
  #define gnrc_ndp_opt_mtu_build(mtu, next)   (NULL)
  #endif
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* NET_GNRC_NDP_H */
  /**
   * @}
   */