Blame view

RIOT/sys/include/net/gnrc/ipv6/nc.h 10.2 KB
a752c7ab   elopes   add first test an...
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 NET_GNRC_IPV6_NC_H
  #define NET_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 /* NET_GNRC_IPV6_NC_H */
  /**
   * @}
   */