uip-ds6.h 12.6 KB
Newer Older
1
/**
Simon Duquennoy's avatar
Simon Duquennoy committed
2
 * \addtogroup uip
3
4
5
6
7
 * @{
 */

/**
 * \file
8
 *    Header file for IPv6-related data structures
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
 * \author Mathilde Durvy <mdurvy@cisco.com>
 * \author Julien Abeille <jabeille@cisco.com>
 *
 */
/*
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *
 */
41

42
43
#ifndef UIP_DS6_H_
#define UIP_DS6_H_
44

45
#include "net/ipv6/uip.h"
46
#include "sys/stimer.h"
47
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
48
49
#include "net/ipv6/uip-nd6.h"
#include "net/ipv6/uip-ds6-nbr.h"
50
#include "net/ipv6/uip-ds6-route.h"
51
52
53

/*--------------------------------------------------*/
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
54
 * Default Router List, Unicast address list, multicast address list, anycast address list),
55
56
57
58
 * we define:
 * - the number of elements requested by the user in contiki configuration (name suffixed by _NBU)
 * - the number of elements assigned by the system (name suffixed by _NBS)
 * - the total number of elements is the sum (name suffixed by _NB)
59
60
 * The routing table definitions can be found in uip-ds6-route.h
 * The Neighbor cache definitions can be found in nbr-table.h
61
62
63
64
65
66
*/

/* Default router list */
#define UIP_DS6_DEFRT_NBS 0
#ifndef UIP_CONF_DS6_DEFRT_NBU
#define UIP_DS6_DEFRT_NBU 2
67
#else
68
#define UIP_DS6_DEFRT_NBU UIP_CONF_DS6_DEFRT_NBU
69
#endif
70
71
#define UIP_DS6_DEFRT_NB UIP_DS6_DEFRT_NBS + UIP_DS6_DEFRT_NBU

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
/* Default prefix */
#ifdef UIP_CONF_DS6_DEFAULT_PREFIX
#define UIP_DS6_DEFAULT_PREFIX UIP_CONF_DS6_DEFAULT_PREFIX
#else
/* From RFC4193, section 3.1:
 *  | 7 bits |1|  40 bits   |  16 bits  |          64 bits           |
 *  +--------+-+------------+-----------+----------------------------+
 *  | Prefix |L| Global ID  | Subnet ID |        Interface ID        |
 *  +--------+-+------------+-----------+----------------------------+
 *     Prefix            FC00::/7 prefix to identify Local IPv6 unicast
 *                       addresses.
 *     L                 Set to 1 if the prefix is locally assigned.
 *                       Set to 0 may be defined in the future.  See
 *                       Section 3.2 for additional information.
 *     Global ID         40-bit global identifier used to create a
 *                       globally unique prefix.  See Section 3.2 for
 *                       additional information.
 *
 * We set prefix to 0xfc00 and set the local bit, resulting in 0xfd00.
 * For high probability of network uniqueness, Global ID must be generated
 * pseudo-randomly. As this is a hard-coded default prefix, we simply use
 * a Global ID of 0. For real deployments, make sure to install a pseudo-random
 * Global ID, e.g. in a RPL network, by configuring it at the root.
 */
#define UIP_DS6_DEFAULT_PREFIX 0xfd00
#endif /* UIP_CONF_DS6_DEFAULT_PREFIX */

#define UIP_DS6_DEFAULT_PREFIX_0 ((UIP_DS6_DEFAULT_PREFIX >> 8) & 0xff)
#define UIP_DS6_DEFAULT_PREFIX_1 (UIP_DS6_DEFAULT_PREFIX & 0xff)

102
/* Prefix list */
103
#define UIP_DS6_PREFIX_NBS  1
104
105
#ifndef UIP_CONF_DS6_PREFIX_NBU
#define UIP_DS6_PREFIX_NBU  2
106
#else
107
#define UIP_DS6_PREFIX_NBU UIP_CONF_DS6_PREFIX_NBU
108
#endif
109
110
111
112
113
114
#define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU

/* Unicast address list*/
#define UIP_DS6_ADDR_NBS 1
#ifndef UIP_CONF_DS6_ADDR_NBU
#define UIP_DS6_ADDR_NBU 2
115
#else
116
#define UIP_DS6_ADDR_NBU UIP_CONF_DS6_ADDR_NBU
117
#endif
118
119
120
121
#define UIP_DS6_ADDR_NB UIP_DS6_ADDR_NBS + UIP_DS6_ADDR_NBU

/* Multicast address list */
#if UIP_CONF_ROUTER
122
#define UIP_DS6_MADDR_NBS 2 + UIP_DS6_ADDR_NB   /* all routers + all nodes + one solicited per unicast */
123
#else
124
#define UIP_DS6_MADDR_NBS 1 + UIP_DS6_ADDR_NB   /* all nodes + one solicited per unicast */
125
126
127
#endif
#ifndef UIP_CONF_DS6_MADDR_NBU
#define UIP_DS6_MADDR_NBU 0
128
#else
129
#define UIP_DS6_MADDR_NBU UIP_CONF_DS6_MADDR_NBU
130
#endif
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#define UIP_DS6_MADDR_NB UIP_DS6_MADDR_NBS + UIP_DS6_MADDR_NBU

/* Anycast address list */
#if UIP_CONF_ROUTER
#define UIP_DS6_AADDR_NBS UIP_DS6_PREFIX_NB - 1 /* One per non link local prefix (subnet prefix anycast address) */
#else
#define UIP_DS6_AADDR_NBS 0
#endif
#ifndef UIP_CONF_DS6_AADDR_NBU
#define UIP_DS6_AADDR_NBU 0
#else
#define UIP_DS6_AADDR_NBU UIP_CONF_DS6_AADDR_NBU
#endif
#define UIP_DS6_AADDR_NB UIP_DS6_AADDR_NBS + UIP_DS6_AADDR_NBU

146
147
148
149
150
151
152
/*--------------------------------------------------*/
/* Should we use LinkLayer acks in NUD ?*/
#ifndef UIP_CONF_DS6_LL_NUD
#define UIP_DS6_LL_NUD 0
#else
#define UIP_DS6_LL_NUD UIP_CONF_DS6_LL_NUD
#endif
153
154
155
156

/** \brief Possible states for the an address  (RFC 4862) */
#define ADDR_TENTATIVE 0
#define ADDR_PREFERRED 1
157
#define ADDR_DEPRECATED 2
158
159
160
161
162
163
164
165

/** \brief How the address was acquired: Autoconf, DHCP or manually */
#define  ADDR_ANYTYPE 0
#define  ADDR_AUTOCONF 1
#define  ADDR_DHCP 2
#define  ADDR_MANUAL 3

/** \brief General DS6 definitions */
166
/** Period for uip-ds6 periodic task*/
Jens Dede's avatar
Jens Dede committed
167
#ifndef UIP_DS6_CONF_PERIOD
168
169
#define UIP_DS6_PERIOD   (CLOCK_SECOND/10)
#else
Jens Dede's avatar
Jens Dede committed
170
171
172
#define UIP_DS6_PERIOD UIP_DS6_CONF_PERIOD
#endif

173
174
175
176
#define FOUND 0
#define FREESPACE 1
#define NOSPACE 2
/*--------------------------------------------------*/
177

178
#if UIP_CONF_IPV6_QUEUE_PKT
179
#include "net/ipv6/uip-packetqueue.h"
180
#endif                          /*UIP_CONF_QUEUE_PKT */
181
182
183
184

/** \brief A prefix list entry */
#if UIP_CONF_ROUTER
typedef struct uip_ds6_prefix {
185
  uint8_t isused;
186
187
188
  uip_ipaddr_t ipaddr;
  uint8_t length;
  uint8_t advertise;
189
190
  uint32_t vlifetime;
  uint32_t plifetime;
191
  uint8_t l_a_reserved; /**< on-link and autonomous flags + 6 reserved bits */
192
} uip_ds6_prefix_t;
193
194
195
196
197
198
199
#else /* UIP_CONF_ROUTER */
typedef struct uip_ds6_prefix {
  uint8_t isused;
  uip_ipaddr_t ipaddr;
  uint8_t length;
  struct stimer vlifetime;
  uint8_t isinfinite;
200
201
} uip_ds6_prefix_t;
#endif /*UIP_CONF_ROUTER */
202
203
204
205
206
207
208
209
210

/** * \brief Unicast address structure */
typedef struct uip_ds6_addr {
  uint8_t isused;
  uip_ipaddr_t ipaddr;
  uint8_t state;
  uint8_t type;
  uint8_t isinfinite;
  struct stimer vlifetime;
211
#if UIP_ND6_DEF_MAXDADNS > 0
212
213
  struct timer dadtimer;
  uint8_t dadnscount;
214
#endif /* UIP_ND6_DEF_MAXDADNS > 0 */
215
} uip_ds6_addr_t;
216
217
218
219
220

/** \brief Anycast address  */
typedef struct uip_ds6_aaddr {
  uint8_t isused;
  uip_ipaddr_t ipaddr;
221
} uip_ds6_aaddr_t;
222
223
224
225
226

/** \brief A multicast address */
typedef struct uip_ds6_maddr {
  uint8_t isused;
  uip_ipaddr_t ipaddr;
227
} uip_ds6_maddr_t;
228
229
230
231

/** \brief  Interface structure (contains all the interface variables) */
typedef struct uip_ds6_netif {
  uint32_t link_mtu;
232
  uint8_t cur_hop_limit;
233
  uint32_t base_reachable_time; /* in msec */
234
235
  uint32_t reachable_time;      /* in msec */
  uint32_t retrans_timer;       /* in msec */
236
  uint8_t maxdadns;
Adam Dunkels's avatar
Adam Dunkels committed
237
#if UIP_DS6_ADDR_NB
238
  uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB];
Adam Dunkels's avatar
Adam Dunkels committed
239
240
#endif /* UIP_DS6_ADDR_NB */
#if UIP_DS6_AADDR_NB
241
  uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB];
Adam Dunkels's avatar
Adam Dunkels committed
242
243
#endif /* UIP_DS6_AADDR_NB */
#if UIP_DS6_MADDR_NB
244
  uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB];
Adam Dunkels's avatar
Adam Dunkels committed
245
#endif /* UIP_DS6_MADDR_NB */
246
} uip_ds6_netif_t;
247
248
249
250
251

/** \brief Generic type for a DS6, to use a common loop though all DS */
typedef struct uip_ds6_element {
  uint8_t isused;
  uip_ipaddr_t ipaddr;
252
} uip_ds6_element_t;
253
254
255


/*---------------------------------------------------------------------------*/
256
extern uip_ds6_netif_t uip_ds6_if;
257
extern struct etimer uip_ds6_timer_periodic;
258

259
#if UIP_CONF_ROUTER
260
extern uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB];
261
262
263
264
265
266
267
268
269
270
271
272
#else /* UIP_CONF_ROUTER */
extern struct etimer uip_ds6_timer_rs;
#endif /* UIP_CONF_ROUTER */


/*---------------------------------------------------------------------------*/
/** \brief Initialize data structures */
void uip_ds6_init(void);

/** \brief Periodic processing of data structures */
void uip_ds6_periodic(void);

273
/** \brief Generic loop routine on an abstract data structure, which generalizes
274
 * all data structures used in DS6 */
275
276
uint8_t uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
                          uint16_t elementsize, uip_ipaddr_t *ipaddr,
277
                          uint8_t ipaddrlen,
278
                          uip_ds6_element_t **out_element);
279
280
281
282
283
284
285

/** @} */


/** \name Prefix list basic routines */
/** @{ */
#if UIP_CONF_ROUTER
286
uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length,
287
288
289
                                     uint8_t advertise, uint8_t flags,
                                     unsigned long vtime,
                                     unsigned long ptime);
290
#else /* UIP_CONF_ROUTER */
291
uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length,
292
                                     unsigned long interval);
293
#endif /* UIP_CONF_ROUTER */
294
295
void uip_ds6_prefix_rm(uip_ds6_prefix_t *prefix);
uip_ds6_prefix_t *uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr,
296
                                        uint8_t ipaddrlen);
297
uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr);
298

299
300
301
302
/** @} */

/** \name Unicast address list basic routines */
/** @{ */
Tommy Sparber's avatar
Tommy Sparber committed
303
/** \brief Add a unicast address to the interface */
304
uip_ds6_addr_t *uip_ds6_addr_add(uip_ipaddr_t *ipaddr,
305
                                 unsigned long vlifetime, uint8_t type);
306
307
void uip_ds6_addr_rm(uip_ds6_addr_t *addr);
uip_ds6_addr_t *uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr);
308
uip_ds6_addr_t *uip_ds6_get_link_local(int8_t state);
309
uip_ds6_addr_t *uip_ds6_get_global(int8_t state);
310

311
312
313
314
/** @} */

/** \name Multicast address list basic routines */
/** @{ */
315
uip_ds6_maddr_t *uip_ds6_maddr_add(const uip_ipaddr_t *ipaddr);
316
void uip_ds6_maddr_rm(uip_ds6_maddr_t *maddr);
317
uip_ds6_maddr_t *uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr);
318

319
320
321
322
/** @} */

/** \name Anycast address list basic routines */
/** @{ */
323
324
325
uip_ds6_aaddr_t *uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr);
void uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr);
uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr);
326

327
328
329
330
/** @} */


/** \brief set the last 64 bits of an IP address based on the MAC address */
331
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);
332

333
334
335
/** \brief Build a link-layer address from an IPv6 address based on its UUID64 */
void uip_ds6_set_lladdr_from_iid(uip_lladdr_t *lladdr, const uip_ipaddr_t *ipaddr);

336
/** \brief Get the number of matching bits of two addresses */
337
uint8_t get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst);
338

339
#if UIP_ND6_DEF_MAXDADNS >0
340
/** \brief Perform Duplicate Address Selection on one address */
341
void uip_ds6_dad(uip_ds6_addr_t *ifaddr);
342
343

/** \brief Callback when DAD failed */
344
int uip_ds6_dad_failed(uip_ds6_addr_t *ifaddr);
345
#endif /* UIP_ND6_DEF_MAXDADNS */
346
347

/** \brief Source address selection, see RFC 3484 */
348
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst);
349
350
351
352
353
354
355
356
357
358
359

#if UIP_CONF_ROUTER
#if UIP_ND6_SEND_RA
/** \brief Send a RA as an asnwer to a RS */
void uip_ds6_send_ra_sollicited(void);

/** \brief Send a periodic RA */
void uip_ds6_send_ra_periodic(void);
#endif /* UIP_ND6_SEND_RA */
#else /* UIP_CONF_ROUTER */
/** \brief Send periodic RS to find router */
360
void uip_ds6_send_rs(void);
361
362
363
364
365
366
367
368
369
370
371
372
373
#endif /* UIP_CONF_ROUTER */

/** \brief Compute the reachable time based on base reachable time, see RFC 4861*/
uint32_t uip_ds6_compute_reachable_time(void); /** \brief compute random reachable timer */

/** \name Macros to check if an IP address (unicast, multicast or anycast) is mine */
/** @{ */
#define uip_ds6_is_my_addr(addr)  (uip_ds6_addr_lookup(addr) != NULL)
#define uip_ds6_is_my_maddr(addr) (uip_ds6_maddr_lookup(addr) != NULL)
#define uip_ds6_is_my_aaddr(addr) (uip_ds6_aaddr_lookup(addr) != NULL)
/** @} */
/** @} */

374
#endif /* UIP_DS6_H_ */