Contiki-NG
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  * \file
32  * Private declarations for ContikiRPL.
33  * \author
34  * Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
35  */
36 
37 #ifndef RPL_PRIVATE_H
38 #define RPL_PRIVATE_H
39 
40 #include "net/routing/rpl-classic/rpl.h"
41 
42 #include "lib/list.h"
43 #include "net/ipv6/uip.h"
44 #include "sys/clock.h"
45 #include "sys/ctimer.h"
46 #include "net/ipv6/uip-ds6.h"
47 #include "net/ipv6/uip-ds6-route.h"
49 
50 /*---------------------------------------------------------------------------*/
51 /** \brief Is IPv6 address addr the link-local, all-RPL-nodes
52  multicast address? */
53 #define uip_is_addr_linklocal_rplnodes_mcast(addr) \
54  ((addr)->u8[0] == 0xff) && \
55  ((addr)->u8[1] == 0x02) && \
56  ((addr)->u16[1] == 0) && \
57  ((addr)->u16[2] == 0) && \
58  ((addr)->u16[3] == 0) && \
59  ((addr)->u16[4] == 0) && \
60  ((addr)->u16[5] == 0) && \
61  ((addr)->u16[6] == 0) && \
62  ((addr)->u8[14] == 0) && \
63  ((addr)->u8[15] == 0x1a))
64 
65 /** \brief Set IP address addr to the link-local, all-rpl-nodes
66  multicast address. */
67 #define uip_create_linklocal_rplnodes_mcast(addr) \
68  uip_ip6addr((addr), 0xff02, 0, 0, 0, 0, 0, 0, 0x001a)
69 /*---------------------------------------------------------------------------*/
70 /* RPL message types */
71 #define RPL_CODE_DIS 0x00 /* DAG Information Solicitation */
72 #define RPL_CODE_DIO 0x01 /* DAG Information Option */
73 #define RPL_CODE_DAO 0x02 /* Destination Advertisement Option */
74 #define RPL_CODE_DAO_ACK 0x03 /* DAO acknowledgment */
75 #define RPL_CODE_SEC_DIS 0x80 /* Secure DIS */
76 #define RPL_CODE_SEC_DIO 0x81 /* Secure DIO */
77 #define RPL_CODE_SEC_DAO 0x82 /* Secure DAO */
78 #define RPL_CODE_SEC_DAO_ACK 0x83 /* Secure DAO ACK */
79 
80 /* RPL control message options. */
81 #define RPL_OPTION_PAD1 0
82 #define RPL_OPTION_PADN 1
83 #define RPL_OPTION_DAG_METRIC_CONTAINER 2
84 #define RPL_OPTION_ROUTE_INFO 3
85 #define RPL_OPTION_DAG_CONF 4
86 #define RPL_OPTION_TARGET 5
87 #define RPL_OPTION_TRANSIT 6
88 #define RPL_OPTION_SOLICITED_INFO 7
89 #define RPL_OPTION_PREFIX_INFO 8
90 #define RPL_OPTION_TARGET_DESC 9
91 
92 #define RPL_DAO_K_FLAG 0x80 /* DAO ACK requested */
93 #define RPL_DAO_D_FLAG 0x40 /* DODAG ID present */
94 
95 #define RPL_DAO_ACK_UNCONDITIONAL_ACCEPT 0
96 #define RPL_DAO_ACK_ACCEPT 1 /* 1 - 127 is OK but not good */
97 #define RPL_DAO_ACK_UNABLE_TO_ACCEPT 128 /* >127 is fail */
98 #define RPL_DAO_ACK_UNABLE_TO_ADD_ROUTE_AT_ROOT 255 /* root can not accept */
99 
100 #define RPL_DAO_ACK_TIMEOUT -1
101 
102 /*---------------------------------------------------------------------------*/
103 /* RPL IPv6 extension header option. */
104 #define RPL_HDR_OPT_LEN 4
105 #define RPL_HOP_BY_HOP_LEN (RPL_HDR_OPT_LEN + 2 + 2)
106 #define RPL_RH_LEN 4
107 #define RPL_SRH_LEN 4
108 #define RPL_RH_TYPE_SRH 3
109 #define RPL_HDR_OPT_DOWN 0x80
110 #define RPL_HDR_OPT_DOWN_SHIFT 7
111 #define RPL_HDR_OPT_RANK_ERR 0x40
112 #define RPL_HDR_OPT_RANK_ERR_SHIFT 6
113 #define RPL_HDR_OPT_FWD_ERR 0x20
114 #define RPL_HDR_OPT_FWD_ERR_SHIFT 5
115 /*---------------------------------------------------------------------------*/
116 /* Default values for RPL constants and variables. */
117 
118 /* DAO transmissions are always delayed by RPL_DAO_DELAY +/- RPL_DAO_DELAY/2 */
119 #ifdef RPL_CONF_DAO_DELAY
120 #define RPL_DAO_DELAY RPL_CONF_DAO_DELAY
121 #else /* RPL_CONF_DAO_DELAY */
122 #define RPL_DAO_DELAY (CLOCK_SECOND * 4)
123 #endif /* RPL_CONF_DAO_DELAY */
124 
125 /* Delay between reception of a no-path DAO and actual route removal */
126 #ifdef RPL_CONF_NOPATH_REMOVAL_DELAY
127 #define RPL_NOPATH_REMOVAL_DELAY RPL_CONF_NOPATH_REMOVAL_DELAY
128 #else /* RPL_CONF_NOPATH_REMOVAL_DELAY */
129 #define RPL_NOPATH_REMOVAL_DELAY 60
130 #endif /* RPL_CONF_NOPATH_REMOVAL_DELAY */
131 
132 #ifdef RPL_CONF_DAO_MAX_RETRANSMISSIONS
133 #define RPL_DAO_MAX_RETRANSMISSIONS RPL_CONF_DAO_MAX_RETRANSMISSIONS
134 #else
135 #define RPL_DAO_MAX_RETRANSMISSIONS 5
136 #endif /* RPL_CONF_DAO_MAX_RETRANSMISSIONS */
137 
138 #ifdef RPL_CONF_DAO_RETRANSMISSION_TIMEOUT
139 #define RPL_DAO_RETRANSMISSION_TIMEOUT RPL_CONF_DAO_RETRANSMISSION_TIMEOUT
140 #else
141 #define RPL_DAO_RETRANSMISSION_TIMEOUT (5 * CLOCK_SECOND)
142 #endif /* RPL_CONF_DAO_RETRANSMISSION_TIMEOUT */
143 
144 /* Special value indicating immediate removal. */
145 #define RPL_ZERO_LIFETIME 0
146 
147 /* Special value indicating infinite lifetime. */
148 #define RPL_INFINITE_LIFETIME 0xFF
149 
150 #define RPL_ROUTE_INFINITE_LIFETIME 0xFFFFFFFF
151 
152 #define RPL_LIFETIME(instance, lifetime) \
153  (((lifetime) == RPL_INFINITE_LIFETIME) ? RPL_ROUTE_INFINITE_LIFETIME : (unsigned long)(instance)->lifetime_unit * (lifetime))
154 
155 
156 #ifndef RPL_CONF_MIN_HOPRANKINC
157 /* RFC6550 defines the default MIN_HOPRANKINC as 256.
158  * However, we use MRHOF as a default Objective Function (RFC6719),
159  * which recommends setting MIN_HOPRANKINC with care, in particular
160  * when used with ETX as a metric. ETX is computed as a fixed point
161  * real with a divisor of 128 (RFC6719, RFC6551). We choose to also
162  * use 128 for RPL_MIN_HOPRANKINC, resulting in a rank equal to the
163  * ETX path cost. Larger values may also be desirable, as discussed
164  * in section 6.1 of RFC6719. */
165 #if RPL_OF_OCP == RPL_OCP_MRHOF
166 #define RPL_MIN_HOPRANKINC 128
167 #else /* RPL_OF_OCP == RPL_OCP_MRHOF */
168 #define RPL_MIN_HOPRANKINC 256
169 #endif /* RPL_OF_OCP == RPL_OCP_MRHOF */
170 #else /* RPL_CONF_MIN_HOPRANKINC */
171 #define RPL_MIN_HOPRANKINC RPL_CONF_MIN_HOPRANKINC
172 #endif /* RPL_CONF_MIN_HOPRANKINC */
173 
174 #ifndef RPL_CONF_MAX_RANKINC
175 #define RPL_MAX_RANKINC (7 * RPL_MIN_HOPRANKINC)
176 #else /* RPL_CONF_MAX_RANKINC */
177 #define RPL_MAX_RANKINC RPL_CONF_MAX_RANKINC
178 #endif /* RPL_CONF_MAX_RANKINC */
179 
180 #define DAG_RANK(fixpt_rank, instance) \
181  ((fixpt_rank) / (instance)->min_hoprankinc)
182 
183 /* Rank of a virtual root node that coordinates DAG root nodes. */
184 #define BASE_RANK 0
185 
186 /* Rank of a root node. */
187 #define ROOT_RANK(instance) (instance)->min_hoprankinc
188 
189 #define RPL_INFINITE_RANK 0xffff
190 
191 /*---------------------------------------------------------------------------*/
192 #define RPL_INSTANCE_LOCAL_FLAG 0x80
193 #define RPL_INSTANCE_D_FLAG 0x40
194 
195 /* Values that tell where a route came from. */
196 #define RPL_ROUTE_FROM_INTERNAL 0
197 #define RPL_ROUTE_FROM_UNICAST_DAO 1
198 #define RPL_ROUTE_FROM_MULTICAST_DAO 2
199 #define RPL_ROUTE_FROM_DIO 3
200 
201 /* DIS related */
202 #define RPL_DIS_SEND 1
203 
204 /*---------------------------------------------------------------------------*/
205 /* Lollipop counters */
206 
207 #define RPL_LOLLIPOP_MAX_VALUE 255
208 #define RPL_LOLLIPOP_CIRCULAR_REGION 127
209 #define RPL_LOLLIPOP_SEQUENCE_WINDOWS 16
210 #define RPL_LOLLIPOP_INIT (RPL_LOLLIPOP_MAX_VALUE - RPL_LOLLIPOP_SEQUENCE_WINDOWS + 1)
211 #define RPL_LOLLIPOP_INCREMENT(counter) \
212  do { \
213  if((counter) > RPL_LOLLIPOP_CIRCULAR_REGION) { \
214  (counter) = ((counter) + 1) & RPL_LOLLIPOP_MAX_VALUE; \
215  } else { \
216  (counter) = ((counter) + 1) & RPL_LOLLIPOP_CIRCULAR_REGION; \
217  } \
218  } while(0)
219 
220 #define RPL_LOLLIPOP_IS_INIT(counter) \
221  ((counter) > RPL_LOLLIPOP_CIRCULAR_REGION)
222 /*---------------------------------------------------------------------------*/
223 /* Logical representation of a DAG Information Object (DIO.) */
224 struct rpl_dio {
225  uip_ipaddr_t dag_id;
226  rpl_ocp_t ocp;
227  rpl_rank_t rank;
228  uint8_t grounded;
229  uint8_t mop;
230  uint8_t preference;
231  uint8_t version;
232  uint8_t instance_id;
233  uint8_t dtsn;
234  uint8_t dag_intdoubl;
235  uint8_t dag_intmin;
236  uint8_t dag_redund;
237  uint8_t default_lifetime;
238  uint16_t lifetime_unit;
239  rpl_rank_t dag_max_rankinc;
240  rpl_rank_t dag_min_hoprankinc;
241  rpl_prefix_t destination_prefix;
242  rpl_prefix_t prefix_info;
243  struct rpl_metric_container mc;
244 };
245 typedef struct rpl_dio rpl_dio_t;
246 
247 #if RPL_CONF_STATS
248 /* Statistics for fault management. */
249 struct rpl_stats {
250  uint16_t mem_overflows;
251  uint16_t local_repairs;
252  uint16_t global_repairs;
253  uint16_t malformed_msgs;
254  uint16_t resets;
255  uint16_t parent_switch;
256  uint16_t forward_errors;
257  uint16_t loop_errors;
258  uint16_t loop_warnings;
259  uint16_t root_repairs;
260 };
261 typedef struct rpl_stats rpl_stats_t;
262 
263 extern rpl_stats_t rpl_stats;
264 #endif
265 
266 /* RPL callbacks when TSCH is enabled */
267 #if MAC_CONF_WITH_TSCH
268 
269 #ifndef RPL_CALLBACK_PARENT_SWITCH
270 #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch
271 #endif /* RPL_CALLBACK_PARENT_SWITCH */
272 
273 #ifndef RPL_CALLBACK_NEW_DIO_INTERVAL
274 #define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval
275 #endif /* RPL_CALLBACK_NEW_DIO_INTERVAL */
276 
277 #endif /* MAC_CONF_WITH_TSCH */
278 
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 /*---------------------------------------------------------------------------*/
289 /* Instances */
290 extern rpl_instance_t instance_table[];
291 extern rpl_instance_t *default_instance;
292 
293 /* ICMPv6 functions for RPL. */
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, uint8_t);
299 void rpl_icmp6_register_handlers(void);
300 uip_ds6_nbr_t *rpl_icmp6_update_nbr_table(uip_ipaddr_t *from,
301  nbr_table_reason_t r, void *data);
302 
303 /* RPL logic functions. */
304 void rpl_join_dag(uip_ipaddr_t *from, rpl_dio_t *dio);
305 void rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio);
306 void rpl_local_repair(rpl_instance_t *instance);
307 void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *);
308 int rpl_process_parent_event(rpl_instance_t *, rpl_parent_t *);
309 
310 /* DAG object management. */
311 rpl_dag_t *rpl_alloc_dag(uint8_t, uip_ipaddr_t *);
312 rpl_instance_t *rpl_alloc_instance(uint8_t);
313 void rpl_free_dag(rpl_dag_t *);
314 void rpl_free_instance(rpl_instance_t *);
315 void rpl_purge_dags(void);
316 
317 /* DAG parent management function. */
318 rpl_parent_t *rpl_add_parent(rpl_dag_t *, rpl_dio_t *dio, uip_ipaddr_t *);
319 rpl_parent_t *rpl_find_parent(rpl_dag_t *, uip_ipaddr_t *);
320 rpl_parent_t *rpl_find_parent_any_dag(rpl_instance_t *instance, uip_ipaddr_t *addr);
321 void rpl_nullify_parent(rpl_parent_t *);
322 void rpl_remove_parent(rpl_parent_t *);
323 void rpl_move_parent(rpl_dag_t *dag_src, rpl_dag_t *dag_dst, rpl_parent_t *parent);
324 rpl_parent_t *rpl_select_parent(rpl_dag_t *dag);
325 rpl_dag_t *rpl_select_dag(rpl_instance_t *instance,rpl_parent_t *parent);
326 void rpl_recalculate_ranks(void);
327 
328 /* RPL routing table functions. */
329 void rpl_remove_routes(rpl_dag_t *dag);
330 void rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop, rpl_dag_t *dag);
331 uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix,
332  int prefix_len, uip_ipaddr_t *next_hop);
333 void rpl_purge_routes(void);
334 
335 /* Objective function. */
336 rpl_of_t *rpl_find_of(rpl_ocp_t);
337 
338 /* Timer functions. */
339 void rpl_schedule_dao(rpl_instance_t *);
340 void rpl_schedule_dao_immediately(rpl_instance_t *);
341 void rpl_schedule_unicast_dio_immediately(rpl_instance_t *instance);
342 void rpl_cancel_dao(rpl_instance_t *instance);
343 void rpl_schedule_probing(rpl_instance_t *instance);
345 
346 void rpl_reset_dio_timer(rpl_instance_t *);
347 void rpl_reset_periodic_timer(void);
348 
349 /* Route poisoning. */
350 void rpl_poison_routes(rpl_dag_t *, rpl_parent_t *);
351 
352 
354 
355 #endif /* RPL_PRIVATE_H */
RPL DAG structure.
Definition: rpl.h:135
RPL instance structure.
Definition: rpl.h:219
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
void rpl_schedule_probing_now(void)
Schedule probing within a few seconds.
RPL prefix information.
Definition: rpl.h:126
Header file for IPv6-related data structures.
API for RPL objective functions (OF)
Definition: rpl.h:201
An entry in the routing table.
This header file contains configuration directives for uIPv6 multicast support.
Header file for the callback timer
Linked list manipulation routines.
uip_ds6_nbr_t * rpl_icmp6_update_nbr_table(uip_ipaddr_t *from, nbr_table_reason_t r, void *data)
Updates IPv6 neighbor cache on incoming link-local RPL ICMPv6 messages.
Definition: rpl-icmp6.c:194
Logical representation of a DAG Metric Container.
Definition: rpl.h:95
Header file for the uIP TCP/IP stack.
Header file for routing table manipulation.
void rpl_process_dio(uip_ipaddr_t *, rpl_dio_t *)
Processes incoming DIO.
Definition: rpl-dag.c:1470
void rpl_local_repair(const char *str)
Triggers a RPL local repair.
Definition: rpl-dag.c:240
rpl_instance_t * rpl_get_default_instance(void)
Returns pointer to the default instance (for compatibility with legagy RPL code)
Definition: rpl-dag.c:628
The default nbr_table entry (when UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr cach...
Definition: uip-ds6-nbr.h:105
void rpl_schedule_probing(void)
Schedule probing with delay RPL_PROBING_DELAY_FUNC()