Contiki-Inga 3.x
rpl-private.h
1 /*
2  * Copyright (c) 2010, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  */
31 
32 /**
33  * \file Private declarations for ContikiRPL.
34  *
35  * \author Joakim Eriksson <joakime@sics.se>
36  * \author Nicolas Tsiftes <nvt@sics.se>
37  */
38 
39 #ifndef RPL_PRIVATE_H
40 #define RPL_PRIVATE_H
41 
42 #include "net/rpl/rpl.h"
43 
44 #include "lib/list.h"
45 #include "net/ip/uip.h"
46 #include "sys/clock.h"
47 #include "sys/ctimer.h"
48 #include "net/ipv6/uip-ds6.h"
50 
51 /*---------------------------------------------------------------------------*/
52 /** \brief Is IPv6 address addr the link-local, all-RPL-nodes
53  multicast address? */
54 #define uip_is_addr_linklocal_rplnodes_mcast(addr) \
55  ((addr)->u8[0] == 0xff) && \
56  ((addr)->u8[1] == 0x02) && \
57  ((addr)->u16[1] == 0) && \
58  ((addr)->u16[2] == 0) && \
59  ((addr)->u16[3] == 0) && \
60  ((addr)->u16[4] == 0) && \
61  ((addr)->u16[5] == 0) && \
62  ((addr)->u16[6] == 0) && \
63  ((addr)->u8[14] == 0) && \
64  ((addr)->u8[15] == 0x1a))
65 
66 /** \brief Set IP address addr to the link-local, all-rpl-nodes
67  multicast address. */
68 #define uip_create_linklocal_rplnodes_mcast(addr) \
69  uip_ip6addr((addr), 0xff02, 0, 0, 0, 0, 0, 0, 0x001a)
70 /*---------------------------------------------------------------------------*/
71 /** RPL message types.
72  * @{ */
73 #define RPL_CODE_DIS 0x00 /* DAG Information Solicitation */
74 #define RPL_CODE_DIO 0x01 /* DAG Information Option */
75 #define RPL_CODE_DAO 0x02 /* Destination Advertisement Option */
76 #define RPL_CODE_DAO_ACK 0x03 /* DAO acknowledgment */
77 #define RPL_CODE_SEC_DIS 0x80 /* Secure DIS */
78 #define RPL_CODE_SEC_DIO 0x81 /* Secure DIO */
79 #define RPL_CODE_SEC_DAO 0x82 /* Secure DAO */
80 #define RPL_CODE_SEC_DAO_ACK 0x83 /* Secure DAO ACK */
81 /** @} */
82 
83 /** @name RPL control message options.
84  * @{ */
85 #define RPL_OPTION_PAD1 0
86 #define RPL_OPTION_PADN 1
87 #define RPL_OPTION_DAG_METRIC_CONTAINER 2
88 #define RPL_OPTION_ROUTE_INFO 3
89 #define RPL_OPTION_DAG_CONF 4
90 #define RPL_OPTION_TARGET 5
91 #define RPL_OPTION_TRANSIT 6
92 #define RPL_OPTION_SOLICITED_INFO 7
93 #define RPL_OPTION_PREFIX_INFO 8
94 #define RPL_OPTION_TARGET_DESC 9
95 /** @} */
96 
97 #define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */
98 #define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */
99 /*---------------------------------------------------------------------------*/
100 /* RPL IPv6 extension header option. */
101 #define RPL_HDR_OPT_LEN 4
102 #define RPL_HOP_BY_HOP_LEN (RPL_HDR_OPT_LEN + 2 + 2)
103 #define RPL_HDR_OPT_DOWN 0x80
104 #define RPL_HDR_OPT_DOWN_SHIFT 7
105 #define RPL_HDR_OPT_RANK_ERR 0x40
106 #define RPL_HDR_OPT_RANK_ERR_SHIFT 6
107 #define RPL_HDR_OPT_FWD_ERR 0x20
108 #define RPL_HDR_OPT_FWD_ERR_SHIFT 5
109 /*---------------------------------------------------------------------------*/
110 /* Default values for RPL constants and variables. */
111 
112 /* The default value for the DAO timer. */
113 #ifdef RPL_CONF_DAO_LATENCY
114 #define RPL_DAO_LATENCY RPL_CONF_DAO_LATENCY
115 #else /* RPL_CONF_DAO_LATENCY */
116 #define RPL_DAO_LATENCY (CLOCK_SECOND * 4)
117 #endif /* RPL_DAO_LATENCY */
118 
119 /* Special value indicating immediate removal. */
120 #define RPL_ZERO_LIFETIME 0
121 
122 #define RPL_LIFETIME(instance, lifetime) \
123  ((unsigned long)(instance)->lifetime_unit * (lifetime))
124 
125 #ifndef RPL_CONF_MIN_HOPRANKINC
126 #define RPL_MIN_HOPRANKINC 256
127 #else
128 #define RPL_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC
129 #endif
130 #define RPL_MAX_RANKINC (7 * RPL_MIN_HOPRANKINC)
131 
132 #define DAG_RANK(fixpt_rank, instance) \
133  ((fixpt_rank) / (instance)->min_hoprankinc)
134 
135 /* Rank of a virtual root node that coordinates DAG root nodes. */
136 #define BASE_RANK 0
137 
138 /* Rank of a root node. */
139 #define ROOT_RANK(instance) (instance)->min_hoprankinc
140 
141 #define INFINITE_RANK 0xffff
142 
143 /* Represents 2^n ms. */
144 /* Default value according to the specification is 3 which
145  means 8 milliseconds, but that is an unreasonable value if
146  using power-saving / duty-cycling */
147 #ifdef RPL_CONF_DIO_INTERVAL_MIN
148 #define RPL_DIO_INTERVAL_MIN RPL_CONF_DIO_INTERVAL_MIN
149 #else
150 #define RPL_DIO_INTERVAL_MIN 12
151 #endif
152 
153 /* Maximum amount of timer doublings. */
154 #ifdef RPL_CONF_DIO_INTERVAL_DOUBLINGS
155 #define RPL_DIO_INTERVAL_DOUBLINGS RPL_CONF_DIO_INTERVAL_DOUBLINGS
156 #else
157 #define RPL_DIO_INTERVAL_DOUBLINGS 8
158 #endif
159 
160 /* Default DIO redundancy. */
161 #ifdef RPL_CONF_DIO_REDUNDANCY
162 #define RPL_DIO_REDUNDANCY RPL_CONF_DIO_REDUNDANCY
163 #else
164 #define RPL_DIO_REDUNDANCY 10
165 #endif
166 
167 /* Expire DAOs from neighbors that do not respond in this time. (seconds) */
168 #define DAO_EXPIRATION_TIMEOUT 60
169 /*---------------------------------------------------------------------------*/
170 #define RPL_INSTANCE_LOCAL_FLAG 0x80
171 #define RPL_INSTANCE_D_FLAG 0x40
172 
173 /* Values that tell where a route came from. */
174 #define RPL_ROUTE_FROM_INTERNAL 0
175 #define RPL_ROUTE_FROM_UNICAST_DAO 1
176 #define RPL_ROUTE_FROM_MULTICAST_DAO 2
177 #define RPL_ROUTE_FROM_DIO 3
178 
179 /* DAG Mode of Operation */
180 #define RPL_MOP_NO_DOWNWARD_ROUTES 0
181 #define RPL_MOP_NON_STORING 1
182 #define RPL_MOP_STORING_NO_MULTICAST 2
183 #define RPL_MOP_STORING_MULTICAST 3
184 
185 #ifdef RPL_CONF_MOP
186 #define RPL_MOP_DEFAULT RPL_CONF_MOP
187 #else /* RPL_CONF_MOP */
188 #if RPL_CONF_MULTICAST
189 #define RPL_MOP_DEFAULT RPL_MOP_STORING_MULTICAST
190 #else
191 #define RPL_MOP_DEFAULT RPL_MOP_STORING_NO_MULTICAST
192 #endif /* UIP_IPV6_MULTICAST_RPL */
193 #endif /* RPL_CONF_MOP */
194 
195 /* Emit a pre-processor error if the user configured multicast with bad MOP */
196 #if RPL_CONF_MULTICAST && (RPL_MOP_DEFAULT != RPL_MOP_STORING_MULTICAST)
197 #error "RPL Multicast requires RPL_MOP_DEFAULT==3. Check contiki-conf.h"
198 #endif
199 
200 /* Multicast Route Lifetime as a multiple of the lifetime unit */
201 #ifdef RPL_CONF_MCAST_LIFETIME
202 #define RPL_MCAST_LIFETIME RPL_CONF_MCAST_LIFETIME
203 #else
204 #define RPL_MCAST_LIFETIME 3
205 #endif
206 
207 /*
208  * The ETX in the metric container is expressed as a fixed-point value
209  * whose integer part can be obtained by dividing the value by
210  * RPL_DAG_MC_ETX_DIVISOR.
211  */
212 #define RPL_DAG_MC_ETX_DIVISOR 256
213 
214 /* DIS related */
215 #define RPL_DIS_SEND 1
216 #ifdef RPL_DIS_INTERVAL_CONF
217 #define RPL_DIS_INTERVAL RPL_DIS_INTERVAL_CONF
218 #else
219 #define RPL_DIS_INTERVAL 60
220 #endif
221 #define RPL_DIS_START_DELAY 5
222 /*---------------------------------------------------------------------------*/
223 /* Lollipop counters */
224 
225 #define RPL_LOLLIPOP_MAX_VALUE 255
226 #define RPL_LOLLIPOP_CIRCULAR_REGION 127
227 #define RPL_LOLLIPOP_SEQUENCE_WINDOWS 16
228 #define RPL_LOLLIPOP_INIT (RPL_LOLLIPOP_MAX_VALUE - RPL_LOLLIPOP_SEQUENCE_WINDOWS + 1)
229 #define RPL_LOLLIPOP_INCREMENT(counter) \
230  do { \
231  if((counter) > RPL_LOLLIPOP_CIRCULAR_REGION) { \
232  (counter) = ((counter) + 1) & RPL_LOLLIPOP_MAX_VALUE; \
233  } else { \
234  (counter) = ((counter) + 1) & RPL_LOLLIPOP_CIRCULAR_REGION; \
235  } \
236  } while(0)
237 
238 #define RPL_LOLLIPOP_IS_INIT(counter) \
239  ((counter) > RPL_LOLLIPOP_CIRCULAR_REGION)
240 /*---------------------------------------------------------------------------*/
241 /** Logical representation of a DAG Information Object (DIO.) */
242 struct rpl_dio {
243  uip_ipaddr_t dag_id;
244  rpl_ocp_t ocp;
245  rpl_rank_t rank;
246  uint8_t grounded;
247  uint8_t mop;
248  uint8_t preference;
249  uint8_t version;
250  uint8_t instance_id;
251  uint8_t dtsn;
252  uint8_t dag_intdoubl;
253  uint8_t dag_intmin;
254  uint8_t dag_redund;
255  uint8_t default_lifetime;
256  uint16_t lifetime_unit;
257  rpl_rank_t dag_max_rankinc;
258  rpl_rank_t dag_min_hoprankinc;
259  rpl_prefix_t destination_prefix;
260  rpl_prefix_t prefix_info;
261  struct rpl_metric_container mc;
262 };
263 typedef struct rpl_dio rpl_dio_t;
264 
265 #if RPL_CONF_STATS
266 /** Statistics for fault management. */
267 struct rpl_stats {
268  uint16_t mem_overflows;
269  uint16_t local_repairs;
270  uint16_t global_repairs;
271  uint16_t malformed_msgs;
272  uint16_t resets;
273  uint16_t parent_switch;
274 };
275 typedef struct rpl_stats rpl_stats_t;
276 
277 extern rpl_stats_t rpl_stats;
278 #endif
279 /*---------------------------------------------------------------------------*/
280 /* RPL macros. */
281 
282 #if RPL_CONF_STATS
283 #define RPL_STAT(code) (code)
284 #else
285 #define RPL_STAT(code)
286 #endif /* RPL_CONF_STATS */
287 /*---------------------------------------------------------------------------*/
288 /* Instances */
289 extern rpl_instance_t instance_table[];
290 extern rpl_instance_t *default_instance;
291 
292 /** @name ICMPv6 functions for RPL.
293  * @{ */
294 void dis_output(uip_ipaddr_t *addr);
295 void dio_output(rpl_instance_t *, uip_ipaddr_t *uc_addr);
296 void dao_output(rpl_parent_t *, uint8_t lifetime);
297 void dao_output_target(rpl_parent_t *, uip_ipaddr_t *, uint8_t lifetime);
298 void dao_ack_output(rpl_instance_t *, uip_ipaddr_t *, uint8_t);
299 /** @} */
300 
301 /** @name RPL logic functions.
302  * @{ */
303 void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
304 void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio);
305 void rpl_local_repair(rpl_instance_t *instance);
306 void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *);
307 int rpl_process_parent_event(rpl_instance_t *, rpl_parent_t *);
308 /** @} */
309 
310 /** @name DAG object management.
311  * @{ */
312 rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *);
313 rpl_instance_t *rpl_alloc_instance(uint8_t);
314 void rpl_free_dag(rpl_dag_t *);
315 void rpl_free_instance(rpl_instance_t *);
316 /** @} */
317 
318 /** @name DAG parent management function.
319  * @{ */
320 rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);
321 rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *);
322 rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
323 void rpl_nullify_parent(rpl_parent_t *);
324 void rpl_remove_parent(rpl_parent_t *);
325 void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent);
326 rpl_parent_t *rpl_select_parent(rpl_dag_t *dag);
327 rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent);
328 void rpl_recalculate_ranks(void);
329 /** @} */
330 
331 /** @name RPL routing table functions.
332  * @{ */
333 void rpl_remove_routes(rpl_dag_t *dag);
334 void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag);
335 uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix,
336  int prefix_len, uip_ipaddr_t *next_hop);
337 void rpl_purge_routes(void);
338 /** @} */
339 
340 /* Lock a parent in the neighbor cache. */
341 void rpl_lock_parent(rpl_parent_t *p);
342 
343 /* Objective function. */
344 rpl_of_t *rpl_find_of(rpl_ocp_t);
345 
346 /* Timer functions. */
347 void rpl_schedule_dao(rpl_instance_t *);
348 void rpl_schedule_dao_immediately(rpl_instance_t *);
349 void rpl_cancel_dao(rpl_instance_t *instance);
350 
351 void rpl_reset_dio_timer(rpl_instance_t *);
352 void rpl_reset_periodic_timer(void);
353 
354 /* Route poisoning. */
355 void rpl_poison_routes(rpl_dag_t *, rpl_parent_t *);
356 
357 #endif /* RPL_PRIVATE_H */