Contiki-NG
rpl.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  * Public API declarations for ContikiRPL.
33  * \author
34  * Joakim Eriksson <joakime@sics.se> & Nicolas Tsiftes <nvt@sics.se>
35  *
36  */
37 
38 #ifndef RPL_H
39 #define RPL_H
40 
41 #include "net/routing/rpl-classic/rpl-conf.h"
42 
43 #include "lib/list.h"
44 #include "net/ipv6/uip.h"
45 #include "net/ipv6/uip-ds6.h"
46 #include "sys/ctimer.h"
47 
48 /*---------------------------------------------------------------------------*/
49 typedef uint16_t rpl_rank_t;
50 typedef uint16_t rpl_ocp_t;
51 /*---------------------------------------------------------------------------*/
52 /* IANA Routing Metric/Constraint Type as defined in RFC6551 */
53 #define RPL_DAG_MC_NONE 0 /* Local identifier for empty MC */
54 #define RPL_DAG_MC_NSA 1 /* Node State and Attributes */
55 #define RPL_DAG_MC_ENERGY 2 /* Node Energy */
56 #define RPL_DAG_MC_HOPCOUNT 3 /* Hop Count */
57 #define RPL_DAG_MC_THROUGHPUT 4 /* Throughput */
58 #define RPL_DAG_MC_LATENCY 5 /* Latency */
59 #define RPL_DAG_MC_LQL 6 /* Link Quality Level */
60 #define RPL_DAG_MC_ETX 7 /* Expected Transmission Count */
61 #define RPL_DAG_MC_LC 8 /* Link Color */
62 
63 /* IANA Routing Metric/Constraint Common Header Flag field as defined in RFC6551 (bit indexes) */
64 #define RPL_DAG_MC_FLAG_P 5
65 #define RPL_DAG_MC_FLAG_C 6
66 #define RPL_DAG_MC_FLAG_O 7
67 #define RPL_DAG_MC_FLAG_R 8
68 
69 /* IANA Routing Metric/Constraint Common Header A Field as defined in RFC6551 */
70 #define RPL_DAG_MC_AGGR_ADDITIVE 0
71 #define RPL_DAG_MC_AGGR_MAXIMUM 1
72 #define RPL_DAG_MC_AGGR_MINIMUM 2
73 #define RPL_DAG_MC_AGGR_MULTIPLICATIVE 3
74 
75 /* The bit index within the flags field of the rpl_metric_object_energy structure. */
76 #define RPL_DAG_MC_ENERGY_INCLUDED 3
77 #define RPL_DAG_MC_ENERGY_TYPE 1
78 #define RPL_DAG_MC_ENERGY_ESTIMATION 0
79 
80 /* IANA Node Type Field as defined in RFC6551 */
81 #define RPL_DAG_MC_ENERGY_TYPE_MAINS 0
82 #define RPL_DAG_MC_ENERGY_TYPE_BATTERY 1
83 #define RPL_DAG_MC_ENERGY_TYPE_SCAVENGING 2
84 
85 /* IANA Objective Code Point as defined in RFC6550 */
86 #define RPL_OCP_OF0 0
87 #define RPL_OCP_MRHOF 1
88 
90  uint8_t flags;
91  uint8_t energy_est;
92 };
93 
94 /* Logical representation of a DAG Metric Container. */
96  uint8_t type;
97  uint8_t flags;
98  uint8_t aggr;
99  uint8_t prec;
100  uint8_t length;
101  union metric_object {
102  struct rpl_metric_object_energy energy;
103  uint16_t etx;
104  } obj;
105 };
106 typedef struct rpl_metric_container rpl_metric_container_t;
107 /*---------------------------------------------------------------------------*/
108 struct rpl_instance;
109 struct rpl_dag;
110 /*---------------------------------------------------------------------------*/
111 #define RPL_PARENT_FLAG_UPDATED 0x1
112 #define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2
113 
114 struct rpl_parent {
115  struct rpl_dag *dag;
116 #if RPL_WITH_MC
117  rpl_metric_container_t mc;
118 #endif /* RPL_WITH_MC */
119  rpl_rank_t rank;
120  uint8_t dtsn;
121  uint8_t flags;
122 };
123 typedef struct rpl_parent rpl_parent_t;
124 /*---------------------------------------------------------------------------*/
125 /* RPL DIO prefix suboption */
126 struct rpl_prefix {
127  uip_ipaddr_t prefix;
128  uint32_t lifetime;
129  uint8_t length;
130  uint8_t flags;
131 };
132 typedef struct rpl_prefix rpl_prefix_t;
133 /*---------------------------------------------------------------------------*/
134 /* Directed Acyclic Graph */
135 struct rpl_dag {
136  uip_ipaddr_t dag_id;
137  rpl_rank_t min_rank; /* should be reset per DAG iteration! */
138  uint8_t version;
139  uint8_t grounded;
140  uint8_t preference;
141  uint8_t used;
142  /* live data for the DAG */
143  uint8_t joined;
144  rpl_parent_t *preferred_parent;
145  rpl_rank_t rank;
146  struct rpl_instance *instance;
147  rpl_prefix_t prefix_info;
148  uint32_t lifetime;
149 };
150 typedef struct rpl_dag rpl_dag_t;
151 typedef struct rpl_instance rpl_instance_t;
152 /*---------------------------------------------------------------------------*/
153 /*
154  * API for RPL objective functions (OF)
155  *
156  * reset(dag)
157  *
158  * Resets the objective function state for a specific DAG. This function is
159  * called when doing a global repair on the DAG.
160  *
161  * parent_link_metric(parent)
162  *
163  * Returns the link metric of a parent
164  *
165  * parent_has_usable_link(parent)
166  *
167  * Returns 1 iff we have a usable link to this parent
168  *
169  * parent_path_cost(parent)
170  *
171  * Returns the path cost of a parent
172  *
173  * rank_via_parent(parent)
174  *
175  * Returns our rank if we select a given parent as preferred parent
176  *
177  * parent_is_acceptable
178  *
179  * Returns 1 if a parent is usable as preferred parent, 0 otherwise
180  *
181  * best_parent(parent1, parent2)
182  *
183  * Compares two parents and returns the best one, according to the OF.
184  *
185  * best_dag(dag1, dag2)
186  *
187  * Compares two DAGs and returns the best one, according to the OF.
188  *
189  * update_metric_container(dag)
190  *
191  * Updates the metric container for outgoing DIOs in a certain DAG.
192  * If the objective function of the DAG does not use metric containers,
193  * the function should set the object type to RPL_DAG_MC_NONE.
194  *
195  * dao_ack_callback(parent, status)
196  *
197  * A callback on the result of the DAO ACK. Similar to the neighbor link
198  * callback. A failed DAO_ACK (NACK) can be used for switching to another
199  * parent via changed link metric or other mechanisms.
200  */
201 struct rpl_of {
202  void (*reset)(struct rpl_dag *);
203 #if RPL_WITH_DAO_ACK
204  void (*dao_ack_callback)(rpl_parent_t *, int status);
205 #endif
206  uint16_t (*parent_link_metric)(rpl_parent_t *);
207  int (*parent_has_usable_link)(rpl_parent_t *);
208  uint16_t (*parent_path_cost)(rpl_parent_t *);
209  rpl_rank_t (*rank_via_parent)(rpl_parent_t *);
210  rpl_parent_t *(*best_parent)(rpl_parent_t *, rpl_parent_t *);
211  rpl_dag_t *(*best_dag)(rpl_dag_t *, rpl_dag_t *);
212  void (*update_metric_container)( rpl_instance_t *);
213  rpl_ocp_t ocp;
214 };
215 typedef struct rpl_of rpl_of_t;
216 
217 /*---------------------------------------------------------------------------*/
218 /* Instance */
219 struct rpl_instance {
220  /* DAG configuration */
221  rpl_metric_container_t mc;
222  rpl_of_t *of;
223  rpl_dag_t *current_dag;
224  rpl_dag_t dag_table[RPL_MAX_DAG_PER_INSTANCE];
225  /* The current default router - used for routing "upwards" */
226  uip_ds6_defrt_t *def_route;
227  uint8_t instance_id;
228  uint8_t used;
229  uint8_t dtsn_out;
230  uint8_t mop;
231  uint8_t dio_intdoubl;
232  uint8_t dio_intmin;
233  uint8_t dio_redundancy;
234  uint8_t default_lifetime;
235  uint8_t dio_intcurrent;
236  uint8_t dio_send; /* for keeping track of which mode the timer is in */
237  uint8_t dio_counter;
238  /* my last registered DAO that I might be waiting for ACK on */
239  uint8_t my_dao_seqno;
240  uint8_t my_dao_transmissions;
241  /* this is intended to keep track if this instance have a route downward */
242  uint8_t has_downward_route;
243  rpl_rank_t max_rankinc;
244  rpl_rank_t min_hoprankinc;
245  uint16_t lifetime_unit; /* lifetime in seconds = l_u * d_l */
246 #if RPL_CONF_STATS
247  uint16_t dio_totint;
248  uint16_t dio_totsend;
249  uint16_t dio_totrecv;
250 #endif /* RPL_CONF_STATS */
251  clock_time_t dio_next_delay; /* delay for completion of dio interval */
252 #if RPL_WITH_PROBING
253  struct ctimer probing_timer;
254  rpl_parent_t *urgent_probing_target;
255  int last_dag;
256 #endif /* RPL_WITH_PROBING */
257  struct ctimer dio_timer;
258  struct ctimer dao_timer;
259  struct ctimer dao_lifetime_timer;
260  struct ctimer unicast_dio_timer;
261  rpl_parent_t *unicast_dio_target;
262 #if RPL_WITH_DAO_ACK
263  struct ctimer dao_retransmit_timer;
264 #endif /* RPL_WITH_DAO_ACK */
265 };
266 
267 /*---------------------------------------------------------------------------*/
268 /* Public RPL functions. */
269 void uip_rpl_input(void);
270 rpl_dag_t *rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id);
271 int rpl_set_prefix(rpl_dag_t *dag, uip_ipaddr_t *prefix, unsigned len);
272 int rpl_repair_root(uint8_t instance_id);
273 int rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from);
274 rpl_dag_t *rpl_get_dag(const uip_ipaddr_t *addr);
275 rpl_dag_t *rpl_get_any_dag(void);
276 rpl_instance_t *rpl_get_instance(uint8_t instance_id);
277 int rpl_ext_header_update(void);
278 int rpl_ext_header_hbh_update(uint8_t *, int);
279 void rpl_insert_header(void);
280 bool rpl_ext_header_remove(void);
281 const struct link_stats *rpl_get_parent_link_stats(rpl_parent_t *p);
282 int rpl_parent_is_fresh(rpl_parent_t *p);
283 int rpl_parent_is_reachable(rpl_parent_t *p);
284 uint16_t rpl_get_parent_link_metric(rpl_parent_t *p);
285 rpl_rank_t rpl_rank_via_parent(rpl_parent_t *p);
286 const linkaddr_t *rpl_get_parent_lladdr(rpl_parent_t *p);
287 uip_ipaddr_t *rpl_parent_get_ipaddr(rpl_parent_t *nbr);
288 rpl_parent_t *rpl_get_parent(const uip_lladdr_t *addr);
289 rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
290 void rpl_dag_init(void);
291 uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
292 void rpl_print_neighbor_list(void);
293 int rpl_ext_header_srh_update(void);
294 int rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr);
295 void rpl_link_callback(const linkaddr_t *addr, int status, int numtx);
296 /* Per-parent RPL information */
297 NBR_TABLE_DECLARE(rpl_parents);
298 
299 /**
300  * RPL modes
301  *
302  * The RPL module can be in either of three modes: mesh mode
303  * (RPL_MODE_MESH), feater mode (RPL_MODE_FEATHER), and leaf mode
304  * (RPL_MODE_LEAF). In mesh mode, nodes forward data for other nodes,
305  * and are reachable by others. In feather mode, nodes can forward
306  * data for other nodes, but are not reachable themselves. In leaf
307  * mode, nodes do not forward data for others, but are reachable by
308  * others. */
309 enum rpl_mode {
310  RPL_MODE_MESH = 0,
311  RPL_MODE_FEATHER = 1,
312  RPL_MODE_LEAF = 2,
313 };
314 
315 /**
316  * Set the RPL mode
317  *
318  * \param mode The new RPL mode
319  * \retval The previous RPL mode
320  */
321 enum rpl_mode rpl_set_mode(enum rpl_mode mode);
322 
323 /**
324  * Get the RPL mode
325  *
326  * \retval The RPL mode
327  */
328 enum rpl_mode rpl_get_mode(void);
329 
330 /**
331  * Tells whether the node has joined a network or not
332  *
333  * \retval 1 if we have joined a network, 0 if not.
334  */
335 int rpl_has_joined(void);
336 
337 /**
338  * Get the RPL's best guess on if we have downward route or not.
339  *
340  * \retval 1 if we have a downward route from RPL Root, 0 if not.
341  */
342 int rpl_has_downward_route(void);
343 
344 /**
345  * Tells whether the protocol is in leaf mode
346  *
347  * \retval 1 if the protocol is in leaf mode, 0 if not.
348  */
349 uint8_t rpl_is_in_leaf_mode(void);
350 
351 /*---------------------------------------------------------------------------*/
352 #endif /* RPL_H */
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:116
An entry in the default router list.
void rpl_link_callback(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
Definition: rpl.c:257
RPL DAG structure.
Definition: rpl.h:135
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
Definition: uip-nd6.c:106
RPL instance structure.
Definition: rpl.h:219
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
Structure for RPL energy metric.
Definition: rpl.h:89
enum rpl_mode rpl_get_mode(void)
Get the RPL mode.
Definition: rpl.c:70
int rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
Look for next hop from SRH of current uIP packet.
uint8_t rpl_is_in_leaf_mode(void)
Tells whether the protocol is in leaf mode.
Definition: rpl.c:427
RPL prefix information.
Definition: rpl.h:126
int rpl_ext_header_update(void)
Adds/updates all RPL extension headers to current uIP packet.
int rpl_ext_header_hbh_update(uint8_t *, int)
Process and update the RPL hop-by-hop extension headers of the current uIP packet.
Header file for IPv6-related data structures.
API for RPL objective functions (OF)
Definition: rpl.h:201
int rpl_set_prefix(rpl_prefix_t *prefix)
Set prefix from an prefix data structure (from DIO)
Definition: rpl.c:184
int rpl_has_downward_route(void)
Get the RPL&#39;s best guess on if we have downward route or not.
Definition: rpl-dag.c:1036
Header file for the callback timer
Linked list manipulation routines.
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
Definition: rpl-dag.c:1070
Logical representation of a DAG Metric Container.
Definition: rpl.h:95
bool rpl_ext_header_remove(void)
Removes all RPL extension headers.
Header file for the uIP TCP/IP stack.
int rpl_has_joined(void)
Tells whether the node has joined a network or not.
Definition: rpl-dag.c:1030
enum rpl_mode rpl_set_mode(enum rpl_mode mode)
Set the RPL mode.
Definition: rpl.c:76
void rpl_dag_init(void)
Initializes rpl-dag module.
Definition: rpl-dag.c:143
int rpl_ext_header_srh_update(void)
Process and update SRH in-place, i.e.
The default nbr_table entry (when UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr cach...
Definition: uip-ds6-nbr.h:105