Loading...
Searching...
No Matches
_nib-internal.h
1/*
2 * SPDX-FileCopyrightText: 2017 Freie Universität Berlin
3 * SPDX-License-Identifier: LGPL-2.1-only
4 */
5
6#pragma once
7
18
19#include <assert.h>
20#include <stdbool.h>
21#include <stdint.h>
22#include <string.h>
23
24#include "bitfield.h"
25#include "evtimer_msg.h"
26#include "sched.h"
27#include "mutex.h"
28#include "net/eui64.h"
29#include "kernel_defines.h"
30#include "net/ipv6/addr.h"
31#ifdef MODULE_GNRC_IPV6
32#include "net/gnrc/ipv6.h"
33#endif
37#include "net/gnrc/pktqueue.h"
39#include "net/ndp.h"
40#include "random.h"
41#include "timex.h"
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
52#define _EMPTY (0x00)
53#define _NC (0x01)
54#define _DC (0x02)
55#define _PL (0x04)
56#define _DRL (0x08)
57#define _FT (0x10)
58#define _DAD (0x20)
59#define _DST (0x40)
62
68#define _PFX_ON_LINK (0x0001)
69#define _PFX_SLAAC (0x0002)
71
75#define _NIB_IF_MASK (GNRC_IPV6_NIB_NC_INFO_IFACE_MASK)
76
80#define _NIB_IF_POS (GNRC_IPV6_NIB_NC_INFO_IFACE_POS)
81
85#define _NIB_IF_MAX (_NIB_IF_MASK >> _NIB_IF_POS)
86
91typedef struct _nib_onl_entry {
93#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || defined(DOXYGEN)
100#endif
105#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LR) || defined(DOXYGEN)
112#endif
113#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) || defined(DOXYGEN)
120#endif
143#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || defined(DOXYGEN)
145#endif
146#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_6LR) || defined(DOXYGEN)
148#endif
149
155 uint16_t info;
156
164 uint8_t mode;
165#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ARSM) || defined(DOXYGEN)
171 uint8_t ns_sent;
172
178 uint8_t l2addr_len;
179#endif
180#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || defined(DOXYGEN)
181 uint8_t pktqueue_len;
182#endif
183} _nib_onl_entry_t;
184
188typedef struct {
189 _nib_onl_entry_t *next_hop;
195
199typedef struct {
200 _nib_onl_entry_t *next_hop;
206#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER)
210 evtimer_msg_event_t route_timeout;
211#endif
212 uint8_t mode;
214 uint8_t pfx_len;
216 uint16_t flags;
217 uint32_t valid_until;
219 uint32_t pref_until;
222
245
249extern evtimer_msg_t _nib_evtimer;
250
259extern _nib_dr_entry_t *_prime_def_router;
260
270uint32_t _evtimer_lookup(const void *ctx, uint16_t type);
271
277static inline void _evtimer_del(evtimer_msg_event_t *event)
278{
279 evtimer_del(&_nib_evtimer, &event->event);
280}
281
290static inline void _evtimer_add(void *ctx, int16_t type,
291 evtimer_msg_event_t *event, uint32_t offset)
292{
293#ifdef MODULE_GNRC_IPV6
294 kernel_pid_t target_pid = gnrc_ipv6_pid;
295#else
296 kernel_pid_t target_pid = KERNEL_PID_LAST; /* just for testing */
297#endif
298 _evtimer_del(event);
299 event->event.next = NULL;
300 event->event.offset = offset;
301 event->msg.type = type;
302 event->msg.content.ptr = ctx;
303 evtimer_add_msg(&_nib_evtimer, event, target_pid);
304}
305
309void _nib_init(void);
310
314void _nib_acquire(void);
315
319void _nib_release(void);
320
328static inline unsigned _nib_onl_get_if(const _nib_onl_entry_t *node)
329{
330 return (node->info & _NIB_IF_MASK) >> _NIB_IF_POS;
331}
332
339static inline void _nib_onl_set_if(_nib_onl_entry_t *node, unsigned iface)
340{
341 assert(iface <= _NIB_IF_MAX);
342 node->info &= ~(_NIB_IF_MASK);
343 node->info |= ((iface << _NIB_IF_POS) & _NIB_IF_MASK);
344}
345
357_nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface);
358
367static inline bool _nib_onl_clear(_nib_onl_entry_t *node)
368{
369 if (node->mode == _EMPTY) {
370 memset(node, 0, sizeof(_nib_onl_entry_t));
371 return true;
372 }
373 return false;
374}
375
383_nib_onl_entry_t *_nib_onl_iter(const _nib_onl_entry_t *last);
384
396_nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface);
397
409static inline _nib_onl_entry_t *_nib_onl_nc_get(const ipv6_addr_t *addr, unsigned iface)
410{
411 _nib_onl_entry_t *nce = _nib_onl_get(addr, iface);
412 if (nce && (nce->mode & _NC)) {
413 return nce;
414 }
415 return NULL;
416}
417
437_nib_onl_entry_t *_nib_nc_add(const ipv6_addr_t *addr, unsigned iface,
438 uint16_t cstate);
439
445void _nib_nc_remove(_nib_onl_entry_t *node);
446
455void _nib_nc_get(const _nib_onl_entry_t *node, gnrc_ipv6_nib_nc_t *nce);
456
464void _nib_nc_set_reachable(_nib_onl_entry_t *node);
465
476static inline _nib_onl_entry_t *_nib_dad_add(const ipv6_addr_t *addr)
477{
478 assert(addr != NULL);
479 _nib_onl_entry_t *node = _nib_onl_alloc(addr, 0);
480
481 if (node != NULL) {
482 node->mode |= (_DAD);
483 }
484 return node;
485}
486
492static inline void _nib_dad_remove(_nib_onl_entry_t *node)
493{
494 node->mode &= ~(_DAD);
495 _nib_onl_clear(node);
496}
497
511_nib_dr_entry_t *_nib_drl_add(const ipv6_addr_t *addr, unsigned iface);
512
520void _nib_drl_remove(_nib_dr_entry_t *nib_dr);
521
529_nib_dr_entry_t *_nib_drl_iter(const _nib_dr_entry_t *last);
530
544_nib_dr_entry_t *_nib_drl_get(const ipv6_addr_t *router_addr, unsigned iface);
545
555void _nib_drl_ft_get(const _nib_dr_entry_t *drl, gnrc_ipv6_nib_ft_t *fte);
556
565_nib_dr_entry_t *_nib_drl_get_dr(void);
566
584_nib_offl_entry_t *_nib_offl_alloc(const ipv6_addr_t *next_hop, unsigned iface,
585 const ipv6_addr_t *pfx, unsigned pfx_len);
586
592void _nib_offl_clear(_nib_offl_entry_t *dst);
593
601_nib_offl_entry_t *_nib_offl_iter(const _nib_offl_entry_t *last);
602
611bool _nib_offl_is_entry(const _nib_offl_entry_t *entry);
612
631static inline _nib_offl_entry_t *_nib_offl_add(const ipv6_addr_t *next_hop,
632 unsigned iface,
633 const ipv6_addr_t *pfx,
634 unsigned pfx_len, uint8_t mode)
635{
636 _nib_offl_entry_t *nib_offl = _nib_offl_alloc(next_hop, iface, pfx, pfx_len);
637
638 if (nib_offl != NULL) {
639 nib_offl->mode |= mode;
640 }
641 return nib_offl;
642}
643
649static inline void _nib_offl_remove(_nib_offl_entry_t *nib_offl, uint8_t mode)
650{
651 nib_offl->mode &= ~mode;
652 _nib_offl_clear(nib_offl);
653}
654
655#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_DC) || DOXYGEN
672static inline _nib_offl_entry_t *_nib_dc_add(const ipv6_addr_t *next_hop,
673 unsigned iface,
674 const ipv6_addr_t *dst)
675{
676 assert((next_hop != NULL) && (dst != NULL));
677 return _nib_offl_add(next_hop, iface, dst, IPV6_ADDR_BIT_LEN, _DC);
678}
679
689static inline void _nib_dc_remove(_nib_offl_entry_t *nib_offl)
690{
691 _nib_offl_remove(nib_offl, _DC);
692}
693#endif /* CONFIG_GNRC_IPV6_NIB_DC */
694
716_nib_offl_entry_t *_nib_pl_add(unsigned iface,
717 const ipv6_addr_t *pfx,
718 unsigned pfx_len,
719 uint32_t valid_ltime,
720 uint32_t pref_ltime);
721
729void _nib_pl_remove(_nib_offl_entry_t *nib_offl);
730
739void _nib_offl_remove_prefix(_nib_offl_entry_t *pfx);
740
741#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER) || DOXYGEN
762static inline _nib_offl_entry_t *_nib_ft_add(const ipv6_addr_t *next_hop,
763 unsigned iface,
764 const ipv6_addr_t *pfx,
765 unsigned pfx_len)
766{
767 return _nib_offl_add(next_hop, iface, pfx, pfx_len, _FT);
768}
769
779static inline void _nib_ft_remove(_nib_offl_entry_t *nib_offl)
780{
781 _evtimer_del(&nib_offl->route_timeout);
782 _nib_offl_remove(nib_offl, _FT);
783}
784#endif /* CONFIG_GNRC_IPV6_NIB_ROUTER */
785
786#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_MULTIHOP_P6C) || defined(DOXYGEN)
797_nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr);
798
806void _nib_abr_remove(const ipv6_addr_t *addr);
807
817void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl);
818
831_nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
832 const _nib_offl_entry_t *last);
833
842_nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last);
843#else
844#define _nib_abr_iter(abr) NULL
845#define _nib_abr_add_pfx(abr, pfx) (void)abr
846#endif
847
857void _nib_ft_get(const _nib_offl_entry_t *dst, gnrc_ipv6_nib_ft_t *fte);
858
873int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *pkt,
874 gnrc_ipv6_nib_ft_t *fte);
875
876#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_QUEUE_PKT) || DOXYGEN
882void _nbr_flush_pktqueue(_nib_onl_entry_t *node);
883
891gnrc_pktqueue_t *_nbr_pop_pkt(_nib_onl_entry_t *node);
892
904void _nbr_push_pkt(_nib_onl_entry_t *node, gnrc_pktqueue_t *pkt);
905#else
906#define _nbr_flush_pktqueue(node) ((void)node)
907#define _nbr_pop_pkt(node) ((void)node, NULL)
908#define _nbr_push_pkt(node, pkt) ((void)node, (void)pkt)
909#endif
910
911#ifdef __cplusplus
912}
913#endif
914
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition assert.h:143
Bitfield 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:115
int16_t kernel_pid_t
Unique process identifier.
Definition sched.h:134
#define CONFIG_GNRC_IPV6_NIB_L2ADDR_MAX_LEN
Maximum link-layer address length (aligned)
Definition conf.h:278
#define CONFIG_GNRC_IPV6_NIB_OFFL_NUMOF
Number of off-link entries in NIB.
Definition conf.h:320
kernel_pid_t gnrc_ipv6_pid
The PID to the IPv6 thread.
struct gnrc_pktsnip gnrc_pktsnip_t
Type to represent parts (either headers or payload) of a packet, called snips.
struct gnrc_pktqueue gnrc_pktqueue_t
data type for packet queue nodes
#define GNRC_SIXLOWPAN_CTX_SIZE
maximum number of entries in context buffer
Definition ctx.h:37
#define IPV6_ADDR_BIT_LEN
Length of an IPv6 address in bit.
Definition addr.h:36
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:50
evtimer_t evtimer_msg_t
IPC-message event timer.
Definition evtimer_msg.h:31
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.
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 .
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
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:142
IPC-message event.
Definition evtimer_msg.h:37
Forwarding table entry view on NIB.
Definition ft.h:32
Neighbor cache entry view on NIB.
Definition nc.h:140
Utility library for comparing and computing timestamps.
Data type to represent an EUI-64.
Definition eui64.h:52
Data type to represent an IPv6 address.
Definition addr.h:64