_nib-internal.h
1 /*
2  * Copyright (C) 2017 Freie Universit├Ąt Berlin
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
19 #ifndef PRIV_NIB_INTERNAL_H
20 #define PRIV_NIB_INTERNAL_H
21 
22 #include <assert.h>
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <string.h>
26 #include <kernel_defines.h>
27 
28 #include "bitfield.h"
29 #include "evtimer_msg.h"
30 #include "kernel_types.h"
31 #include "mutex.h"
32 #include "net/eui64.h"
33 #include "net/ipv6/addr.h"
34 #ifdef MODULE_GNRC_IPV6
35 #include "net/gnrc/ipv6.h"
36 #endif
37 #include "net/gnrc/ipv6/nib/ft.h"
38 #include "net/gnrc/ipv6/nib/nc.h"
39 #include "net/gnrc/ipv6/nib/conf.h"
40 #include "net/gnrc/pktqueue.h"
41 #include "net/gnrc/sixlowpan/ctx.h"
42 #include "net/ndp.h"
43 #include "random.h"
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 
54 #define _EMPTY (0x00)
55 #define _NC (0x01)
56 #define _DC (0x02)
57 #define _PL (0x04)
58 #define _DRL (0x08)
59 #define _FT (0x10)
60 #define _DAD (0x20)
61 #define _DST (0x40)
70 #define _PFX_ON_LINK (0x0001)
71 #define _PFX_SLAAC (0x0002)
72 
77 #define _NIB_IF_MASK (GNRC_IPV6_NIB_NC_INFO_IFACE_MASK)
78 
82 #define _NIB_IF_POS (GNRC_IPV6_NIB_NC_INFO_IFACE_POS)
83 
87 #define _NIB_IF_MAX (_NIB_IF_MASK >> _NIB_IF_POS)
88 
93 typedef struct _nib_onl_entry {
94  struct _nib_onl_entry *next;
95 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || defined(DOXYGEN)
96 
102 #endif
103 
107 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LR) || defined(DOXYGEN)
108 
113  eui64_t eui64;
114 #endif
115 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) || defined(DOXYGEN)
116 
122 #endif
123 
145 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || defined(DOXYGEN)
147 #endif
148 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LR) || defined(DOXYGEN)
150 #endif
151 
157  uint16_t info;
166  uint8_t mode;
167 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) || defined(DOXYGEN)
168 
173  uint8_t ns_sent;
180  uint8_t l2addr_len;
181 #endif
183 
187 typedef struct {
188  _nib_onl_entry_t *next_hop;
192  evtimer_msg_event_t rtr_timeout;
194 
198 typedef struct {
199  _nib_onl_entry_t *next_hop;
204  evtimer_msg_event_t pfx_timeout;
205 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER)
206 
209  evtimer_msg_event_t route_timeout;
210 #endif
211  uint8_t mode;
213  uint8_t pfx_len;
215  uint16_t flags;
216  uint32_t valid_until;
218  uint32_t pref_until;
221 
226 typedef struct {
227  ipv6_addr_t addr;
228  uint32_t version;
230  uint32_t valid_until;
232  evtimer_msg_event_t timeout;
244 
248 extern evtimer_msg_t _nib_evtimer;
249 
258 extern _nib_dr_entry_t *_prime_def_router;
259 
263 void _nib_init(void);
264 
268 void _nib_acquire(void);
269 
273 void _nib_release(void);
274 
282 static inline unsigned _nib_onl_get_if(const _nib_onl_entry_t *node)
283 {
284  return (node->info & _NIB_IF_MASK) >> _NIB_IF_POS;
285 }
286 
293 static inline void _nib_onl_set_if(_nib_onl_entry_t *node, unsigned iface)
294 {
295  assert(iface <= _NIB_IF_MAX);
296  node->info &= ~(_NIB_IF_MASK);
297  node->info |= ((iface << _NIB_IF_POS) & _NIB_IF_MASK);
298 }
299 
311 _nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface);
312 
321 static inline bool _nib_onl_clear(_nib_onl_entry_t *node)
322 {
323  if (node->mode == _EMPTY) {
324  memset(node, 0, sizeof(_nib_onl_entry_t));
325  return true;
326  }
327  return false;
328 }
329 
337 _nib_onl_entry_t *_nib_onl_iter(const _nib_onl_entry_t *last);
338 
350 _nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface);
351 
371 _nib_onl_entry_t *_nib_nc_add(const ipv6_addr_t *addr, unsigned iface,
372  uint16_t cstate);
373 
379 void _nib_nc_remove(_nib_onl_entry_t *node);
380 
389 void _nib_nc_get(const _nib_onl_entry_t *node, gnrc_ipv6_nib_nc_t *nce);
390 
398 void _nib_nc_set_reachable(_nib_onl_entry_t *node);
399 
410 static inline _nib_onl_entry_t *_nib_dad_add(const ipv6_addr_t *addr)
411 {
412  assert(addr != NULL);
413  _nib_onl_entry_t *node = _nib_onl_alloc(addr, 0);
414 
415  if (node != NULL) {
416  node->mode |= (_DAD);
417  }
418  return node;
419 }
420 
426 static inline void _nib_dad_remove(_nib_onl_entry_t *node)
427 {
428  node->mode &= ~(_DAD);
429  _nib_onl_clear(node);
430 }
431 
445 _nib_dr_entry_t *_nib_drl_add(const ipv6_addr_t *addr, unsigned iface);
446 
454 void _nib_drl_remove(_nib_dr_entry_t *nib_dr);
455 
463 _nib_dr_entry_t *_nib_drl_iter(const _nib_dr_entry_t *last);
464 
477 _nib_dr_entry_t *_nib_drl_get(const ipv6_addr_t *router_addr, unsigned iface);
478 
488 void _nib_drl_ft_get(const _nib_dr_entry_t *drl, gnrc_ipv6_nib_ft_t *fte);
489 
498 _nib_dr_entry_t *_nib_drl_get_dr(void);
499 
517 _nib_offl_entry_t *_nib_offl_alloc(const ipv6_addr_t *next_hop, unsigned iface,
518  const ipv6_addr_t *pfx, unsigned pfx_len);
519 
525 void _nib_offl_clear(_nib_offl_entry_t *dst);
526 
534 _nib_offl_entry_t *_nib_offl_iter(const _nib_offl_entry_t *last);
535 
544 bool _nib_offl_is_entry(const _nib_offl_entry_t *entry);
545 
564 static inline _nib_offl_entry_t *_nib_offl_add(const ipv6_addr_t *next_hop,
565  unsigned iface,
566  const ipv6_addr_t *pfx,
567  unsigned pfx_len, uint8_t mode)
568 {
569  _nib_offl_entry_t *nib_offl = _nib_offl_alloc(next_hop, iface, pfx, pfx_len);
570 
571  if (nib_offl != NULL) {
572  nib_offl->mode |= mode;
573  }
574  return nib_offl;
575 }
576 
582 static inline void _nib_offl_remove(_nib_offl_entry_t *nib_offl, uint8_t mode)
583 {
584  nib_offl->mode &= ~mode;
585  _nib_offl_clear(nib_offl);
586 }
587 
588 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_DC) || DOXYGEN
589 
605 static inline _nib_offl_entry_t *_nib_dc_add(const ipv6_addr_t *next_hop,
606  unsigned iface,
607  const ipv6_addr_t *dst)
608 {
609  assert((next_hop != NULL) && (dst != NULL));
610  return _nib_offl_add(next_hop, iface, dst, IPV6_ADDR_BIT_LEN, _DC);
611 }
612 
622 static inline void _nib_dc_remove(_nib_offl_entry_t *nib_offl)
623 {
624  _nib_offl_remove(nib_offl, _DC);
625 }
626 #endif /* CONFIG_GNRC_IPV6_NIB_DC */
627 
649 _nib_offl_entry_t *_nib_pl_add(unsigned iface,
650  const ipv6_addr_t *pfx,
651  unsigned pfx_len,
652  uint32_t valid_ltime,
653  uint32_t pref_ltime);
654 
662 void _nib_pl_remove(_nib_offl_entry_t *nib_offl);
663 
664 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || DOXYGEN
665 
685 static inline _nib_offl_entry_t *_nib_ft_add(const ipv6_addr_t *next_hop,
686  unsigned iface,
687  const ipv6_addr_t *pfx,
688  unsigned pfx_len)
689 {
690  return _nib_offl_add(next_hop, iface, pfx, pfx_len, _FT);
691 }
692 
702 static inline void _nib_ft_remove(_nib_offl_entry_t *nib_offl)
703 {
704  _nib_offl_remove(nib_offl, _FT);
705 }
706 #endif /* CONFIG_GNRC_IPV6_NIB_ROUTER */
707 
708 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) || defined(DOXYGEN)
709 
719 _nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr);
720 
728 void _nib_abr_remove(const ipv6_addr_t *addr);
729 
739 void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl);
740 
753 _nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
754  const _nib_offl_entry_t *last);
755 
764 _nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last);
765 #endif
766 
776 void _nib_ft_get(const _nib_offl_entry_t *dst, gnrc_ipv6_nib_ft_t *fte);
777 
792 int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *ctx,
793  gnrc_ipv6_nib_ft_t *entry);
794 
804 uint32_t _evtimer_lookup(const void *ctx, uint16_t type);
805 
814 static inline void _evtimer_add(void *ctx, int16_t type,
815  evtimer_msg_event_t *event, uint32_t offset)
816 {
817 #ifdef MODULE_GNRC_IPV6
818  kernel_pid_t target_pid = gnrc_ipv6_pid;
819 #else
820  kernel_pid_t target_pid = KERNEL_PID_LAST; /* just for testing */
821 #endif
822  evtimer_del((evtimer_t *)(&_nib_evtimer), (evtimer_event_t *)event);
823  event->event.next = NULL;
824  event->event.offset = offset;
825  event->msg.type = type;
826  event->msg.content.ptr = ctx;
827  evtimer_add_msg(&_nib_evtimer, event, target_pid);
828 }
829 
830 #ifdef __cplusplus
831 }
832 #endif
833 
834 #endif /* PRIV_NIB_INTERNAL_H */
835 
Types used by the kernel.
EUI-64 data type definition.
Definitions for IPv6 addresses.
Context buffer definitions.
Forwarding table definitions.
bitfields operations on bitfields of arbitrary length
Forwarding table entry view on NIB.
Definition: ft.h:35
void evtimer_del(evtimer_t *evtimer, evtimer_event_t *event)
Removes an event from an event timer.
evtimer_msg_event_t reply_rs
Event for GNRC_IPV6_NIB_REPLY_RS.
Neighbor cache entry view on NIB.
Definition: nc.h:142
event structure
Definition: event.h:139
uint16_t info
Information flags.
uint8_t ns_sent
Neighbor solicitations sent for probing.
ipv6_addr_t ipv6
Neighbors IPv6 address.
uint8_t mode
NIB entry mode.
uint8_t l2addr[CONFIG_GNRC_IPV6_NIB_L2ADDR_MAX_LEN]
Link-layer address of _nib_onl_entry_t::next_hop.
Neighbor cache definitions.
int16_t kernel_pid_t
Unique process identifier.
Definition: kernel_types.h:83
On-link NIB entry.
Definition: _nib-internal.h:94
struct _nib_onl_entry * next
next removable entry
Definition: _nib-internal.h:95
POSIX.1-2008 compliant version of the assert macro.
Event timer.
Definition: evtimer.h:71
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:104
evtimer_msg_event_t addr_reg_timeout
Event for GNRC_IPV6_NIB_ADDR_REG_TIMEOUT.
eui64_t eui64
The neighbors EUI-64 (used for DAD)
Configuration macro definitions for neighbor information base.
Definitions for GNRC&#39;s IPv6 implementation.
IPC-based evtimer definitions.
#define CONFIG_GNRC_IPV6_NIB_OFFL_NUMOF
Number of off-link entries in NIB.
Definition: conf.h:271
data type for packet queue nodes
Definition: pktqueue.h:37
evtimer_msg_event_t nud_timeout
Event for GNRC_IPV6_NIB_SND_UC_NS, GNRC_IPV6_NIB_SND_MC_NS, GNRC_IPV6_NIB_REACH_TIMEOUT and GNRC_IPV6...
#define BITFIELD(NAME, SIZE)
Declare a bitfield of a given size.
Definition: bitfield.h:46
#define IPV6_ADDR_BIT_LEN
Length of an IPv6 address in bit.
Definition: addr.h:43
#define GNRC_SIXLOWPAN_CTX_SIZE
maximum number of entries in context buffer
Definition: ctx.h:38
gnrc_pktqueue_t * pktqueue
queue for packets currently in address resolution
Mutex for thread synchronization.
evtimer_msg_event_t snd_na
Event for GNRC_IPV6_NIB_SND_NA.
Common macros and compiler attributes/pragmas configuration.
Internal NIB-representation of the authoritative border router for multihop prefix and 6LoWPAN contex...
IPC-message event.
Definition: evtimer_msg.h:40
Type to represent parts (either headers or payload) of a packet, called snips.
Definition: pkt.h:107
Data type to represent an IPv6 address.
Definition: addr.h:74
Data type to represent an EUI-64.
Definition: eui64.h:55
Packet queue definitions.
IPv6 neighbor discovery message type definitions.
Common interface to the software PRNG.
Default route NIB entry.
uint8_t l2addr_len
length in bytes of _nib_onl_entry_t::l2addr
Off-link NIB entry.
static void evtimer_add_msg(evtimer_msg_t *evtimer, evtimer_msg_event_t *event, kernel_pid_t target_pid)
Adds event to an event timer that handles events via IPC.
Definition: evtimer_msg.h:53
kernel_pid_t gnrc_ipv6_pid
The PID to the IPv6 thread.
Generic event.
Definition: evtimer.h:58
#define KERNEL_PID_LAST
The last valid PID (inclusive).
Definition: kernel_types.h:73
uint8_t mode
mode of the off-link entry
#define CONFIG_GNRC_IPV6_NIB_L2ADDR_MAX_LEN
Maximum link-layer address length (aligned)
Definition: conf.h:241