nc.h
8.68 KB
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
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* 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_ipv6_nib_nc Neighbor Cache
* @ingroup net_gnrc_ipv6_nib
* @brief Neighbor cache component of neighbor information base
* @{
*
* @file
* @brief Neighbor cache definitions
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_IPV6_NIB_NC_H
#define NET_GNRC_IPV6_NIB_NC_H
#include <stdbool.h>
#include <stdint.h>
#include "net/eui64.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/ipv6/nib/conf.h"
#include "net/ipv6/addr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Values for gnrc_ipv6_nib_nc_t::info
* @anchor net_gnrc_ipv6_nib_nc_info
* @name Info values
* @{
*/
/**
* @brief Mask for neighbor unreachability detection (NUD) states
*
* @see [RFC 4861, section 7.3.2](https://tools.ietf.org/html/rfc4861#section-7.3.2)
* @see [RFC 7048](https://tools.ietf.org/html/rfc7048)
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK (0x0007)
/**
* @brief Not managed by NUD
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED (0x0000)
/**
* @brief Entry is not reachable
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE (0x0001)
/**
* @brief Address resolution is currently performed
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE (0x0002)
/**
* @brief Address might not be reachable
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE (0x0003)
/**
* @brief NUD will be performed in a moment
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY (0x0004)
/**
* @brief NUD is performed
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE (0x0005)
/**
* @brief Entry is reachable
*/
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE (0x0006)
/**
* @brief gnrc_ipv6_nib_t::next_hop is router
*
* This flag indicates that gnrc_ipv6_nib_t::next_hop is a router, but it does
* not necessarily indicate that it is in the default router list! A neighbor
* that has this flag unset however **must not** appear in the default router
* list.
*
* @see [RFC 4861, Appendix D](https://tools.ietf.org/html/rfc4861#page-91)
*/
#define GNRC_IPV6_NIB_NC_INFO_IS_ROUTER (0x0008)
/**
* @brief Mask for interface identifier
*/
#define GNRC_IPV6_NIB_NC_INFO_IFACE_MASK (0x01f0)
/**
* @brief Shift position of interface identifier
*/
#define GNRC_IPV6_NIB_NC_INFO_IFACE_POS (4)
/**
* @brief Mask for 6LoWPAN address registration (6Lo-AR) states
*
* @see [RFC 6775, section 3.5](https://tools.ietf.org/html/rfc6775#section-3.5)
*/
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_MASK (0x0600)
/**
* @brief Shift position of address registration states
*/
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_POS (9)
/**
* @brief Not managed by 6Lo-AR (address can be removed when memory is low
*/
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_GC (0x0000)
/**
* @brief Address registration still pending at upstream router
*/
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_TENTATIVE (0x0200)
/**
* @brief Address is registered
*/
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED (0x0400)
/**
* @brief Address was added manually
*/
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL (0x0600)
/** @} */
/**
* @brief Neighbor cache entry view on NIB
*/
typedef struct {
ipv6_addr_t ipv6; /**< Neighbor's IPv6 address */
/**
* @brief Neighbor's link-layer address
*/
uint8_t l2addr[GNRC_IPV6_NIB_L2ADDR_MAX_LEN];
/**
* @brief Neighbor information as defined in
* @ref net_gnrc_ipv6_nib_nc_info "info values"
*/
uint16_t info;
uint8_t l2addr_len; /**< Length of gnrc_ipv6_nib_nc_t::l2addr in bytes */
} gnrc_ipv6_nib_nc_t;
/**
* @brief Gets neighbor unreachability state from entry
*
* @param[in] entry A neighbor cache entry.
*
* @return The neighbor unreachability state of @p entry.
*/
static inline unsigned gnrc_ipv6_nib_nc_get_nud_state(const gnrc_ipv6_nib_nc_t *entry)
{
return (entry->info & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK);
}
/**
* @brief Gets router flag of a neighbor.
*
* @param[in] entry A neighbor cache entry.
*
* @return true, if @p entry is a router.
* @return false, if @p entry is not a router.
*/
static inline bool gnrc_ipv6_nib_nc_is_router(const gnrc_ipv6_nib_nc_t *entry)
{
return (entry->info & GNRC_IPV6_NIB_NC_INFO_IS_ROUTER);
}
/**
* @brief Gets interface from entry
*
* @param[in] entry A neighbor cache entry
*
* @return The interface identifier of @p entry.
* @return 0 if no interface is identified for @p entry.
*/
static inline unsigned gnrc_ipv6_nib_nc_get_iface(const gnrc_ipv6_nib_nc_t *entry)
{
return (entry->info & GNRC_IPV6_NIB_NC_INFO_IFACE_MASK) >>
GNRC_IPV6_NIB_NC_INFO_IFACE_POS;
}
/**
* @brief Gets address registration state of an entry
*
* @param[in] entry A neighbor cache entry
*
* @return The address registration state of @p entry.
*/
static inline unsigned gnrc_ipv6_nib_nc_get_ar_state(const gnrc_ipv6_nib_nc_t *entry)
{
return (entry->info & GNRC_IPV6_NIB_NC_INFO_AR_STATE_MASK);
}
/**
* @brief Adds an unmanaged neighbor entry to NIB
*
* @pre `(ipv6 != NULL) && (l2addr != NULL)`
* @pre `l2addr_len <= GNRC_IPV6_NIB_L2ADDR_MAX_LEN`
* @pre `(iface > KERNEL_PID_UNDEF) && (iface <= KERNEL_PID_LAST)`
*
* @param[in] ipv6 The neighbor's IPv6 address.
* @param[in] iface The interface to the neighbor.
* @param[in] l2addr The neighbor's L2 address.
* @param[in] l2addr_len Length of @p l2addr.
*
* A neighbor cache entry created this way is marked as persistent.
* Also, a non-persistent neighbor or destination cache entry already in the
* NIB might be removed to make room for the new entry.
* If an entry pointing to the same IPv6 address as @p ipv6 exists already it
* will be overwritten and marked as unmanaged.
*
* If @ref GNRC_IPV6_NIB_CONF_ARSM != 0 @p l2addr and @p l2addr_len won't be set.
*
* @return 0 on success.
* @return -ENOMEM, if no space is left in neighbor cache.
*/
int gnrc_ipv6_nib_nc_set(const ipv6_addr_t *ipv6, unsigned iface,
const uint8_t *l2addr, size_t l2addr_len);
/**
* @brief Deletes neighbor with address @p ipv6 from NIB
*
* @pre `ipv6 != NULL`
*
* @param[in] ipv6 The neighbor's IPv6 address.
*
* If the @p ipv6 can't be found for a neighbor in the NIB nothing happens.
*/
void gnrc_ipv6_nib_nc_del(const ipv6_addr_t *ipv6);
/**
* @brief Mark neighbor with address @p ipv6 as reachable
*
* @pre `ipv6 != NULL`
*
* @param[in] ipv6 A neighbor's IPv6 address. May not be NULL.
*
* This function shall be called if an upper layer gets reachability
* confirmation via its own means (e.g. a TCP connection build-up or
* confirmation). Unmanaged neighbor cache entries (i.e. entries created using
* @ref gnrc_ipv6_nib_nc_set()) or entries whose next-hop are not yet in the
* neighbor cache are ignored.
*
* Entries in state @ref GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED are not
* affected by this, since they are assumed to always be reachable and kept out
* of the NUD state-machine
*/
void gnrc_ipv6_nib_nc_mark_reachable(const ipv6_addr_t *ipv6);
/**
* @brief Iterates over all neighbor cache entries in the NIB
*
* @pre `(state != NULL) && (nce != NULL)`
*
* @param[in] iface Restrict iteration to entries on this interface.
* 0 for any interface.
* @param[in,out] state Iteration state of the neighbor cache. Must point to
* a NULL pointer to start iteration.
* @param[out] nce The next neighbor cache entry.
*
* Usage example:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
* #include "net/gnrc/ipv6/nib/nc.h"
*
* int main(void) {
* void *state = NULL;
* gnrc_ipv6_nib_nc_t nce;
*
* puts("My neighbors:");
* while (gnrc_ipv6_nib_nc_iter(0, &state, &nce)) {
* gnrc_ipv6_nib_nc_print(&nce);
* }
* return 0;
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @note The list may change during iteration.
*
* @return true, if iteration can be continued.
* @return false, if @p nce is the last neighbor cache entry in the NIB.
*/
bool gnrc_ipv6_nib_nc_iter(unsigned iface, void **state,
gnrc_ipv6_nib_nc_t *nce);
/**
* @brief Prints a neighbor cache entry
*
* @pre `nce != NULL`
*
* @param[in] nce A neighbor cache entry.
*/
void gnrc_ipv6_nib_nc_print(gnrc_ipv6_nib_nc_t *nce);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_IPV6_NIB_NC_H */
/** @} */