nc.h
10.2 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
314
315
316
317
318
319
/*
* 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_ipv6_nc IPv6 neighbor cache
* @ingroup net_gnrc_ipv6
* @brief Translates IPv6 addresses to link layer addresses.
* @{
*
* @file
* @brief Neighbor cache definitions.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef GNRC_IPV6_NC_H_
#define GNRC_IPV6_NC_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "kernel_types.h"
#include "net/eui64.h"
#include "net/ipv6/addr.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/pktqueue.h"
#include "xtimer.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GNRC_IPV6_NC_SIZE
/**
* @brief The size of the neighbor cache
*/
#define GNRC_IPV6_NC_SIZE (GNRC_NETIF_NUMOF * 8)
#endif
#ifndef GNRC_IPV6_NC_L2_ADDR_MAX
/**
* @brief The maximum size of a link layer address
*/
#define GNRC_IPV6_NC_L2_ADDR_MAX (8)
#endif
/**
* @{
* @name Flag definitions for gnrc_ipv6_nc_t
*/
/**
* @{
* @brief States of a neighbor cache entry.
*
* @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.2">
* RFC 4861, section 7.3.2
* </a>
*/
#define GNRC_IPV6_NC_STATE_MASK (0x07) /**< Mask for neighbor cache state */
#define GNRC_IPV6_NC_STATE_POS (0) /**< Shift of neighbor cache state */
#define GNRC_IPV6_NC_STATE_UNMANAGED (0x00) /**< The entry is not manage by NDP */
/**
* @brief The entry is unreachable
*
* @see <a href="http://tools.ietf.org/html/rfc7048#section-3">
* RFC 7048, section 3
* </a>
*/
#define GNRC_IPV6_NC_STATE_UNREACHABLE (0x01)
#define GNRC_IPV6_NC_STATE_INCOMPLETE (0x02) /**< Address resolution is performed */
#define GNRC_IPV6_NC_STATE_STALE (0x03) /**< The entry is stale */
#define GNRC_IPV6_NC_STATE_DELAY (0x04) /**< The entry was stale but packet was sent out */
#define GNRC_IPV6_NC_STATE_PROBE (0x05) /**< Periodic reachabality confirmation */
#define GNRC_IPV6_NC_STATE_REACHABLE (0x07) /**< The entry is reachable */
/**
* @}
*/
#define GNRC_IPV6_NC_IS_ROUTER (0x08) /**< The neighbor is a router */
#define GNRC_IPV6_NC_TYPE_MASK (0x30) /**< Mask for neighbor cache state */
/**
* @{
* @brief States of a neighbor cache entry.
*
* @see <a href="http://tools.ietf.org/html/rfc6775#section-3.5">
* RFC 6775, section 3.5
* </a>
*/
/**
* @brief The entry has no type
*
* @details The node sents multicast Neighbor Solicitations for hosts.
*/
#define GNRC_IPV6_NC_TYPE_NONE (0x00)
#define GNRC_IPV6_NC_TYPE_GC (0x10) /**< The entry is marked for removal */
#define GNRC_IPV6_NC_TYPE_TENTATIVE (0x20) /**< The entry is temporary */
#define GNRC_IPV6_NC_TYPE_REGISTERED (0x30) /**< The entry is registered */
/**
* @}
*/
/**
* @}
*/
/**
* @brief Neighbor cache entry as defined in
* <a href="http://tools.ietf.org/html/rfc4861#section-5.1">
* RFC 4861, section 5.1
* </a>.
*/
typedef struct {
#ifdef MODULE_GNRC_NDP_NODE
gnrc_pktqueue_t *pkts; /**< Packets waiting for address resolution */
#endif
ipv6_addr_t ipv6_addr; /**< IPv6 address of the neighbor */
uint8_t l2_addr[GNRC_IPV6_NC_L2_ADDR_MAX]; /**< Link layer address of the neighbor */
uint8_t l2_addr_len; /**< Length of gnrc_ipv6_nc_t::l2_addr */
uint8_t flags; /**< Flags as defined above */
kernel_pid_t iface; /**< PID to the interface where the neighbor is */
xtimer_t rtr_timeout; /**< timeout timer for router flag */
msg_t rtr_timeout_msg; /**< msg_t for gnrc_ipv6_nc_t::rtr_timeout */
/**
* @brief (Re)Transmission timer for neighbor solicitations of this entry and
* timeout for states.
*/
xtimer_t nbr_sol_timer;
msg_t nbr_sol_msg; /**< msg_t for gnrc_ipv6_nc_t::nbr_sol_timer */
/**
* @brief Delay timer for neighbor advertisements of this entry.
*
* @note Only needed for delayed anycast neighbor advertisements
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-7.2.7">
* RFC 4861, section 7.2.7
* </a>
*/
xtimer_t nbr_adv_timer;
msg_t nbr_adv_msg; /**< msg_t for gnrc_ipv6_nc_t::nbr_adv_timer */
#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER)
xtimer_t rtr_adv_timer; /**< Timer for periodic router advertisements */
msg_t rtr_adv_msg; /**< msg_t for gnrc_ipv6_nc_t::rtr_adv_timer */
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
xtimer_t type_timeout; /**< Timer for type transmissions */
msg_t type_timeout_msg; /**< msg_t for gnrc_ipv6_nc_t::type_timeout */
eui64_t eui64; /**< the unique EUI-64 of the neighbor (might be
* different from L2 address, if l2_addr_len == 2) */
#endif
uint8_t probes_remaining; /**< remaining number of unanswered probes */
/**
* @}
*/
} gnrc_ipv6_nc_t;
/**
* @brief Initializes neighbor cache
*/
void gnrc_ipv6_nc_init(void);
/**
* @brief Adds a neighbor to the neighbor cache
*
* @param[in] iface PID to the interface where the neighbor is.
* @param[in] ipv6_addr IPv6 address of the neighbor. Must not be NULL.
* @param[in] l2_addr Link layer address of the neighbor. NULL if unknown.
* @param[in] l2_addr_len Length of @p l2_addr, must be lesser than or equal
* to GNRC_IPV6_L2_ADDR_MAX. 0 if unknown.
* @param[in] flags Flags for the entry
*
* @return Pointer to new neighbor cache entry on success
* @return NULL, on failure
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_add(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr,
const void *l2_addr, size_t l2_addr_len, uint8_t flags);
/**
* @brief Removes a neighbor from the neighbor cache
*
* @param[in] iface PID to the interface where the neighbor is. If it
* is KERNEL_PID_UNDEF it will be removed for all
* interfaces.
* @param[in] ipv6_addr IPv6 address of the neighbor
*/
void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr);
/**
* @brief Searches for any neighbor cache entry fitting the @p ipv6_addr.
*
* @param[in] iface PID to the interface where the neighbor is. If it
* is KERNEL_PID_UNDEF it will be searched on all
* interfaces.
* @param[in] ipv6_addr An IPv6 address
*
* @return The neighbor cache entry, if one is found.
* @return NULL, if none is found.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_get(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr);
/**
* @brief Gets next entry in neighbor cache after @p prev.
*
* @param[in] prev Previous entry. NULL to start iteration.
*
* @return The next entry in neighbor cache.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next(gnrc_ipv6_nc_t *prev);
/**
* @brief Gets next reachable router entry in neighbor cache after @p prev.
*
* @param[in] prev Previous router entry. NULL to start iteration.
*
* @return The next reachable router entry in neighbor cache.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next_router(gnrc_ipv6_nc_t *prev);
/**
* @brief Returns the state of a neighbor cache entry.
*
* @param[in] entry A neighbor cache entry
*
* @return The state of the neighbor cache entry as defined by its flags.
*/
static inline uint8_t gnrc_ipv6_nc_get_state(const gnrc_ipv6_nc_t *entry)
{
return (entry->flags & GNRC_IPV6_NC_STATE_MASK);
}
/**
* @brief Returns the type of a neighbor cache entry.
*
* @param[in] entry A neighbor cache entry
*
* @return The type of the neighbor cache entry as defined by its flags.
*/
static inline uint8_t gnrc_ipv6_nc_get_type(const gnrc_ipv6_nc_t *entry)
{
return (entry->flags & GNRC_IPV6_NC_TYPE_MASK);
}
/**
* @brief Checks if an entry is reachable (do not confuse with
* @ref GNRC_IPV6_NC_STATE_REACHABLE).
*
* @param[in] entry A neighbor cache entry
*
* @return true, if you can send packets to @p entry
* @return false, if you can't send packets to @p entry
*/
static inline bool gnrc_ipv6_nc_is_reachable(const gnrc_ipv6_nc_t *entry)
{
switch (gnrc_ipv6_nc_get_state(entry)) {
case GNRC_IPV6_NC_STATE_UNREACHABLE:
case GNRC_IPV6_NC_STATE_INCOMPLETE:
return false;
default:
return true;
}
}
/**
* @brief Marks an entry as still reachable, if one with a fitting @p ipv6_addr
* can be found.
*
* @details This function can be used by upper layer protocols for neighbor
* discovery optimization to confirm that there was a reachability
* confirmation (e. g. an ACK in TCP) from the neighbor.
*
* @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.1">
* RFC 4861, section 7.3.1
* </a>
*
* @param[in] ipv6_addr An IPv6 address
*
* @return The neighbor cache entry, if one is found.
* @return NULL, if none is found.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr);
/**
* @brief Gets link-layer address from neighbor cache entry if neighbor is reachable.
*
* @pre (l2_addr != NULL) && (l2_addr_len != NULL)
*
* @param[out] l2_addr The link layer address of @p entry. Must not be NULL.
* @param[out] l2_addr_len Length of @p l2_addr. Must not be NULL.
* @param[in] entry A neighbor cache entry
*
* @return PID to the interface where the neighbor is.
* @return KERNEL_PID_UNDEF, if @p entry == NULL or the neighbor is not reachable.
*/
kernel_pid_t gnrc_ipv6_nc_get_l2_addr(uint8_t *l2_addr, uint8_t *l2_addr_len,
const gnrc_ipv6_nc_t *entry);
#ifdef __cplusplus
}
#endif
#endif /* GNRC_IPV6_NC_H_ */
/**
* @}
*/