_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 
27 #include "bitfield.h"
28 #include "evtimer_msg.h"
29 #include "sched.h"
30 #include "mutex.h"
31 #include "net/eui64.h"
32 #include "kernel_defines.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 #include "timex.h"
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
55 #define _EMPTY (0x00)
56 #define _NC (0x01)
57 #define _DC (0x02)
58 #define _PL (0x04)
59 #define _DRL (0x08)
60 #define _FT (0x10)
61 #define _DAD (0x20)
62 #define _DST (0x40)
71 #define _PFX_ON_LINK (0x0001)
72 #define _PFX_SLAAC (0x0002)
78 #define _NIB_IF_MASK (GNRC_IPV6_NIB_NC_INFO_IFACE_MASK)
79 
83 #define _NIB_IF_POS (GNRC_IPV6_NIB_NC_INFO_IFACE_POS)
84 
88 #define _NIB_IF_MAX (_NIB_IF_MASK >> _NIB_IF_POS)
89 
94 typedef struct _nib_onl_entry {
95  struct _nib_onl_entry *next;
96 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || defined(DOXYGEN)
103 #endif
108 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LR) || defined(DOXYGEN)
115 #endif
116 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) || defined(DOXYGEN)
123 #endif
146 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || defined(DOXYGEN)
148 #endif
149 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LR) || defined(DOXYGEN)
151 #endif
152 
158  uint16_t info;
159 
167  uint8_t mode;
168 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) || defined(DOXYGEN)
174  uint8_t ns_sent;
175 
181  uint8_t l2addr_len;
182 #endif
183 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || defined(DOXYGEN)
184  uint8_t pktqueue_len;
185 #endif
187 
191 typedef struct {
198 
202 typedef struct {
209 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER)
213  evtimer_msg_event_t route_timeout;
214 #endif
215  uint8_t mode;
217  uint8_t pfx_len;
219  uint16_t flags;
220  uint32_t valid_until;
222  uint32_t pref_until;
225 
230 typedef struct {
232  uint32_t version;
234  uint32_t valid_until_ms;
248 
252 extern evtimer_msg_t _nib_evtimer;
253 
262 extern _nib_dr_entry_t *_prime_def_router;
263 
273 uint32_t _evtimer_lookup(const void *ctx, uint16_t type);
274 
280 static inline void _evtimer_del(evtimer_msg_event_t *event)
281 {
282  evtimer_del(&_nib_evtimer, &event->event);
283 }
284 
293 static inline void _evtimer_add(void *ctx, int16_t type,
294  evtimer_msg_event_t *event, uint32_t offset)
295 {
296 #ifdef MODULE_GNRC_IPV6
297  kernel_pid_t target_pid = gnrc_ipv6_pid;
298 #else
299  kernel_pid_t target_pid = KERNEL_PID_LAST; /* just for testing */
300 #endif
301  _evtimer_del(event);
302  event->event.next = NULL;
303  event->event.offset = offset;
304  event->msg.type = type;
305  event->msg.content.ptr = ctx;
306  evtimer_add_msg(&_nib_evtimer, event, target_pid);
307 }
308 
312 void _nib_init(void);
313 
317 void _nib_acquire(void);
318 
322 void _nib_release(void);
323 
331 static inline unsigned _nib_onl_get_if(const _nib_onl_entry_t *node)
332 {
333  return (node->info & _NIB_IF_MASK) >> _NIB_IF_POS;
334 }
335 
342 static inline void _nib_onl_set_if(_nib_onl_entry_t *node, unsigned iface)
343 {
344  assert(iface <= _NIB_IF_MAX);
345  node->info &= ~(_NIB_IF_MASK);
346  node->info |= ((iface << _NIB_IF_POS) & _NIB_IF_MASK);
347 }
348 
360 _nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface);
361 
370 static inline bool _nib_onl_clear(_nib_onl_entry_t *node)
371 {
372  if (node->mode == _EMPTY) {
373  memset(node, 0, sizeof(_nib_onl_entry_t));
374  return true;
375  }
376  return false;
377 }
378 
386 _nib_onl_entry_t *_nib_onl_iter(const _nib_onl_entry_t *last);
387 
399 _nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface);
400 
412 static inline _nib_onl_entry_t *_nib_onl_nc_get(const ipv6_addr_t *addr, unsigned iface)
413 {
414  _nib_onl_entry_t *nce = _nib_onl_get(addr, iface);
415  if (nce && (nce->mode & _NC)) {
416  return nce;
417  }
418  return NULL;
419 }
420 
440 _nib_onl_entry_t *_nib_nc_add(const ipv6_addr_t *addr, unsigned iface,
441  uint16_t cstate);
442 
448 void _nib_nc_remove(_nib_onl_entry_t *node);
449 
458 void _nib_nc_get(const _nib_onl_entry_t *node, gnrc_ipv6_nib_nc_t *nce);
459 
467 void _nib_nc_set_reachable(_nib_onl_entry_t *node);
468 
479 static inline _nib_onl_entry_t *_nib_dad_add(const ipv6_addr_t *addr)
480 {
481  assert(addr != NULL);
482  _nib_onl_entry_t *node = _nib_onl_alloc(addr, 0);
483 
484  if (node != NULL) {
485  node->mode |= (_DAD);
486  }
487  return node;
488 }
489 
495 static inline void _nib_dad_remove(_nib_onl_entry_t *node)
496 {
497  node->mode &= ~(_DAD);
498  _nib_onl_clear(node);
499 }
500 
514 _nib_dr_entry_t *_nib_drl_add(const ipv6_addr_t *addr, unsigned iface);
515 
523 void _nib_drl_remove(_nib_dr_entry_t *nib_dr);
524 
532 _nib_dr_entry_t *_nib_drl_iter(const _nib_dr_entry_t *last);
533 
547 _nib_dr_entry_t *_nib_drl_get(const ipv6_addr_t *router_addr, unsigned iface);
548 
558 void _nib_drl_ft_get(const _nib_dr_entry_t *drl, gnrc_ipv6_nib_ft_t *fte);
559 
568 _nib_dr_entry_t *_nib_drl_get_dr(void);
569 
587 _nib_offl_entry_t *_nib_offl_alloc(const ipv6_addr_t *next_hop, unsigned iface,
588  const ipv6_addr_t *pfx, unsigned pfx_len);
589 
595 void _nib_offl_clear(_nib_offl_entry_t *dst);
596 
604 _nib_offl_entry_t *_nib_offl_iter(const _nib_offl_entry_t *last);
605 
614 bool _nib_offl_is_entry(const _nib_offl_entry_t *entry);
615 
634 static inline _nib_offl_entry_t *_nib_offl_add(const ipv6_addr_t *next_hop,
635  unsigned iface,
636  const ipv6_addr_t *pfx,
637  unsigned pfx_len, uint8_t mode)
638 {
639  _nib_offl_entry_t *nib_offl = _nib_offl_alloc(next_hop, iface, pfx, pfx_len);
640 
641  if (nib_offl != NULL) {
642  nib_offl->mode |= mode;
643  }
644  return nib_offl;
645 }
646 
652 static inline void _nib_offl_remove(_nib_offl_entry_t *nib_offl, uint8_t mode)
653 {
654  nib_offl->mode &= ~mode;
655  _nib_offl_clear(nib_offl);
656 }
657 
658 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_DC) || DOXYGEN
675 static inline _nib_offl_entry_t *_nib_dc_add(const ipv6_addr_t *next_hop,
676  unsigned iface,
677  const ipv6_addr_t *dst)
678 {
679  assert((next_hop != NULL) && (dst != NULL));
680  return _nib_offl_add(next_hop, iface, dst, IPV6_ADDR_BIT_LEN, _DC);
681 }
682 
692 static inline void _nib_dc_remove(_nib_offl_entry_t *nib_offl)
693 {
694  _nib_offl_remove(nib_offl, _DC);
695 }
696 #endif /* CONFIG_GNRC_IPV6_NIB_DC */
697 
719 _nib_offl_entry_t *_nib_pl_add(unsigned iface,
720  const ipv6_addr_t *pfx,
721  unsigned pfx_len,
722  uint32_t valid_ltime,
723  uint32_t pref_ltime);
724 
732 void _nib_pl_remove(_nib_offl_entry_t *nib_offl);
733 
742 void _nib_offl_remove_prefix(_nib_offl_entry_t *pfx);
743 
744 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || DOXYGEN
765 static inline _nib_offl_entry_t *_nib_ft_add(const ipv6_addr_t *next_hop,
766  unsigned iface,
767  const ipv6_addr_t *pfx,
768  unsigned pfx_len)
769 {
770  return _nib_offl_add(next_hop, iface, pfx, pfx_len, _FT);
771 }
772 
782 static inline void _nib_ft_remove(_nib_offl_entry_t *nib_offl)
783 {
784  _evtimer_del(&nib_offl->route_timeout);
785  _nib_offl_remove(nib_offl, _FT);
786 }
787 #endif /* CONFIG_GNRC_IPV6_NIB_ROUTER */
788 
789 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) || defined(DOXYGEN)
800 _nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr);
801 
809 void _nib_abr_remove(const ipv6_addr_t *addr);
810 
820 void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl);
821 
834 _nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
835  const _nib_offl_entry_t *last);
836 
845 _nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last);
846 #else
847 #define _nib_abr_iter(abr) NULL
848 #endif
849 
859 void _nib_ft_get(const _nib_offl_entry_t *dst, gnrc_ipv6_nib_ft_t *fte);
860 
875 int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *ctx,
876  gnrc_ipv6_nib_ft_t *entry);
877 
878 #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || DOXYGEN
884 void _nbr_flush_pktqueue(_nib_onl_entry_t *node);
885 
893 gnrc_pktqueue_t *_nbr_pop_pkt(_nib_onl_entry_t *node);
894 
906 void _nbr_push_pkt(_nib_onl_entry_t *node, gnrc_pktqueue_t *pkt);
907 #else
908 #define _nbr_flush_pktqueue(node) ((void)node)
909 #define _nbr_pop_pkt(node) ((void)node, NULL)
910 #define _nbr_push_pkt(node, pkt) ((void)node, (void)pkt)
911 #endif
912 
913 #ifdef __cplusplus
914 }
915 #endif
916 
917 #endif /* PRIV_NIB_INTERNAL_H */
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:136
bitfields operations on bitfields of arbitrary length
Context buffer definitions.
EUI-64 data type definition.
IPC-based evtimer definitions.
Forwarding table definitions.
Definitions for GNRC's IPv6 implementation.
#define KERNEL_PID_LAST
The last valid PID (inclusive).
Definition: sched.h:120
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:139
#define CONFIG_GNRC_IPV6_NIB_L2ADDR_MAX_LEN
Maximum link-layer address length (aligned)
Definition: conf.h:261
#define CONFIG_GNRC_IPV6_NIB_OFFL_NUMOF
Number of off-link entries in NIB.
Definition: conf.h:303
kernel_pid_t gnrc_ipv6_pid
The PID to the IPv6 thread.
#define GNRC_SIXLOWPAN_CTX_SIZE
maximum number of entries in context buffer
Definition: ctx.h:40
#define IPV6_ADDR_BIT_LEN
Length of an IPv6 address in bit.
Definition: addr.h:42
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
void evtimer_del(evtimer_t *evtimer, evtimer_event_t *event)
Removes an event from an event timer.
Definitions for IPv6 addresses.
Configuration macro definitions for neighbor information base.
Common macros and compiler attributes/pragmas configuration.
Mutex for thread synchronization.
Neighbor cache definitions.
IPv6 neighbor discovery message type definitions.
Packet queue definitions.
Common interface to the software PRNG.
Scheduler API definition.
Internal NIB-representation of the authoritative border router for multihop prefix and 6LoWPAN contex...
ipv6_addr_t addr
The address of the border router.
BITFIELD(pfxs, CONFIG_GNRC_IPV6_NIB_OFFL_NUMOF)
Bitfield marking the prefixes in the NIB's off-link entries disseminated by _nib_abr_entry_t::addr.
uint32_t valid_until_ms
timestamp (in ms) until which information is valid (needs resolution in minutes an 16 bits of them)
evtimer_msg_event_t timeout
timeout of the information
BITFIELD(ctxs, GNRC_SIXLOWPAN_CTX_SIZE)
Bitfield marking the contexts disseminated by _nib_abr_entry_t::addr.
uint32_t version
last received version of the info of the _nib_abr_entry_t::addr
Default route NIB entry.
evtimer_msg_event_t rtr_timeout
Event for GNRC_IPV6_NIB_RTR_TIMEOUT.
_nib_onl_entry_t * next_hop
next hop to destination
Off-link NIB entry.
ipv6_addr_t pfx
prefix to the destination
uint32_t valid_until
timestamp (in ms) until which the prefix valid (UINT32_MAX means forever)
uint8_t mode
mode of the off-link entry
uint8_t pfx_len
prefix-length in bits of _nib_onl_entry_t::pfx
uint32_t pref_until
timestamp (in ms) until which the prefix preferred (UINT32_MAX means forever)
evtimer_msg_event_t pfx_timeout
Event for GNRC_IPV6_NIB_PFX_TIMEOUT.
uint16_t flags
[flags](net_gnrc_ipv6_nib_offl_flags
_nib_onl_entry_t * next_hop
next hop to destination
On-link NIB entry .
Definition: _nib-internal.h:94
uint8_t mode
NIB entry mode.
uint8_t ns_sent
Neighbor solicitations sent for probing.
evtimer_msg_event_t addr_reg_timeout
Event for GNRC_IPV6_NIB_ADDR_REG_TIMEOUT.
gnrc_pktqueue_t * pktqueue
queue for packets currently in address resolution
uint8_t l2addr_len
length in bytes of _nib_onl_entry_t::l2addr
eui64_t eui64
The neighbors EUI-64 (used for DAD)
struct _nib_onl_entry * next
next removable entry
Definition: _nib-internal.h:95
uint8_t l2addr[CONFIG_GNRC_IPV6_NIB_L2ADDR_MAX_LEN]
Link-layer address of _nib_onl_entry_t::next_hop.
evtimer_msg_event_t reply_rs
Event for GNRC_IPV6_NIB_REPLY_RS.
ipv6_addr_t ipv6
Neighbors IPv6 address.
uint16_t info
Information flags.
evtimer_msg_event_t snd_na
Event for GNRC_IPV6_NIB_SND_NA.
uint8_t pktqueue_len
Number of queued packets (in pktqueue)
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...
event structure
Definition: event.h:148
IPC-message event.
Definition: evtimer_msg.h:40
Event timer.
Definition: evtimer.h:69
Forwarding table entry view on NIB.
Definition: ft.h:35
Neighbor cache entry view on NIB.
Definition: nc.h:142
data type for packet queue nodes
Definition: pktqueue.h:37
Type to represent parts (either headers or payload) of a packet, called snips.
Definition: pkt.h:108
Utility library for comparing and computing timestamps.
Data type to represent an EUI-64.
Definition: eui64.h:55
Data type to represent an IPv6 address.
Definition: addr.h:72