Contiki-NG
Loading...
Searching...
No Matches
rpl.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, 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 * \addtogroup rpl-lite
34 * @{
35 *
36 * \file
37 * ContikiRPL, an implementation of RPL: IPv6 Routing Protocol
38 * for Low-Power and Lossy Networks (IETF RFC 6550)
39 *
40 * \author Joakim Eriksson <joakime@sics.se>, Nicolas Tsiftes <nvt@sics.se>
41 * Simon Duquennoy <simon.duquennoy@inria.fr>
42 */
43
44#include "net/routing/rpl-lite/rpl.h"
45#include "net/routing/routing.h"
46
47/* Log configuration */
48#include "sys/log.h"
49#define LOG_MODULE "RPL"
50#define LOG_LEVEL LOG_LEVEL_RPL
51
52uip_ipaddr_t rpl_multicast_addr;
53static uint8_t rpl_leaf_only = RPL_DEFAULT_LEAF_ONLY;
54
55/*---------------------------------------------------------------------------*/
56int
58{
59 /* Check if we are comparing an initial value with an old value */
60 if(a > RPL_LOLLIPOP_CIRCULAR_REGION && b <= RPL_LOLLIPOP_CIRCULAR_REGION) {
61 return (RPL_LOLLIPOP_MAX_VALUE + 1 + b - a) > RPL_LOLLIPOP_SEQUENCE_WINDOWS;
62 }
63 /* Otherwise check if a > b and comparable => ok, or
64 if they have wrapped and are still comparable */
65 return (a > b && (a - b) < RPL_LOLLIPOP_SEQUENCE_WINDOWS) ||
66 (a < b && (b - a) > (RPL_LOLLIPOP_CIRCULAR_REGION + 1-
67 RPL_LOLLIPOP_SEQUENCE_WINDOWS));
68}
69/*---------------------------------------------------------------------------*/
70const uip_ipaddr_t *
72{
73 int i;
74 uint8_t state;
75 uip_ipaddr_t *ipaddr = NULL;
76 uip_ipaddr_t *prefix = NULL;
77 uint8_t prefix_length = 0;
78
79 if(curr_instance.used && curr_instance.dag.prefix_info.length != 0) {
80 prefix = &curr_instance.dag.prefix_info.prefix;
81 prefix_length = curr_instance.dag.prefix_info.length;
82 }
83
84 for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
85 state = uip_ds6_if.addr_list[i].state;
86 if(uip_ds6_if.addr_list[i].isused &&
87 state == ADDR_PREFERRED &&
88 !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr) &&
89 (prefix == NULL || uip_ipaddr_prefixcmp(prefix, &uip_ds6_if.addr_list[i].ipaddr, prefix_length))) {
90 ipaddr = &uip_ds6_if.addr_list[i].ipaddr;
91 }
92 }
93 return ipaddr;
94}
95/*---------------------------------------------------------------------------*/
96void
97rpl_link_callback(const linkaddr_t *addr, int status, int numtx)
98{
99 if(curr_instance.used == 1 ) {
101 if(nbr != NULL) {
102 /* If this is the neighbor we were probing urgently, mark urgent
103 probing as done */
104#if RPL_WITH_PROBING
105 if(curr_instance.dag.urgent_probing_target == nbr) {
106 curr_instance.dag.urgent_probing_target = NULL;
107 }
108#endif
109 /* Link stats were updated, and we need to update our internal state.
110 Updating from here is unsafe; postpone */
111 LOG_INFO("packet sent to ");
112 LOG_INFO_LLADDR(addr);
113 LOG_INFO_(", status %u, tx %u, new link metric %u\n",
114 status, numtx, rpl_neighbor_get_link_metric(nbr));
116 }
117 }
118}
119/*---------------------------------------------------------------------------*/
120int
122{
123 return curr_instance.used && curr_instance.dag.state >= DAG_JOINED;
124}
125/*---------------------------------------------------------------------------*/
126int
128{
129 return curr_instance.used && curr_instance.dag.state == DAG_REACHABLE;
130}
131/*---------------------------------------------------------------------------*/
132static void
133set_ip_from_prefix(uip_ipaddr_t *ipaddr, rpl_prefix_t *prefix)
134{
135 memset(ipaddr, 0, sizeof(uip_ipaddr_t));
136 memcpy(ipaddr, &prefix->prefix, (prefix->length + 7) / 8);
138}
139/*---------------------------------------------------------------------------*/
140void
142{
143 uip_ipaddr_t ipaddr;
144 uip_ds6_addr_t *rep;
145 set_ip_from_prefix(&ipaddr, last_prefix);
146 rep = uip_ds6_addr_lookup(&ipaddr);
147 if(rep != NULL) {
148 LOG_INFO("removing global IP address ");
149 LOG_INFO_6ADDR(&ipaddr);
150 LOG_INFO_("\n");
151 uip_ds6_addr_rm(rep);
152 }
153 curr_instance.dag.prefix_info.length = 0;
154}
155/*---------------------------------------------------------------------------*/
156int
157rpl_set_prefix_from_addr(uip_ipaddr_t *addr, unsigned len, uint8_t flags)
158{
159 uip_ipaddr_t ipaddr;
160
161 if(addr == NULL || len == 0 || len > 128 || !(flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) {
162 LOG_WARN("prefix not included, not-supported or invalid\n");
163 return 0;
164 }
165
166 /* Try and initialize prefix */
167 memset(&curr_instance.dag.prefix_info.prefix, 0, sizeof(uip_ipaddr_t));
168 memcpy(&curr_instance.dag.prefix_info.prefix, addr, (len + 7) / 8);
169 curr_instance.dag.prefix_info.length = len;
170 curr_instance.dag.prefix_info.lifetime = RPL_ROUTE_INFINITE_LIFETIME;
171 curr_instance.dag.prefix_info.flags = flags;
172
173 /* Add global address if not already there */
174 set_ip_from_prefix(&ipaddr, &curr_instance.dag.prefix_info);
175 if(uip_ds6_addr_lookup(&ipaddr) == NULL) {
176 LOG_INFO("adding global IP address ");
177 LOG_INFO_6ADDR(&ipaddr);
178 LOG_INFO_("\n");
179 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
180 }
181 return 1;
182}
183/*---------------------------------------------------------------------------*/
184int
186{
187 if(prefix != NULL && rpl_set_prefix_from_addr(&prefix->prefix, prefix->length, prefix->flags)) {
188 curr_instance.dag.prefix_info.lifetime = prefix->lifetime;
189 return 1;
190 }
191 return 0;
192}
193/*---------------------------------------------------------------------------*/
194static void
195init(void)
196{
197 LOG_INFO("initializing\n");
198
199 /* Initialize multicast address and register it */
200 uip_create_linklocal_rplnodes_mcast(&rpl_multicast_addr);
201 uip_ds6_maddr_add(&rpl_multicast_addr);
202
203 rpl_dag_init();
207
208 uip_sr_init();
209}
210/*---------------------------------------------------------------------------*/
211static int
212get_sr_node_ipaddr(uip_ipaddr_t *addr, const uip_sr_node_t *node)
213{
214 if(addr != NULL && node != NULL) {
215 memcpy(addr, &curr_instance.dag.dag_id, 8);
216 memcpy(((unsigned char *)addr) + 8, &node->link_identifier, 8);
217 return 1;
218 } else {
219 return 0;
220 }
221}
222/*---------------------------------------------------------------------------*/
223static void
224neighbor_state_changed(uip_ds6_nbr_t *nbr)
225{
226 /* Nothing needs be done in non-storing mode */
227}
228/*---------------------------------------------------------------------------*/
229static void
230drop_route(uip_ds6_route_t *route)
231{
232 /* Do nothing. RPL-lite only supports non-storing mode, i.e. no routes */
233}
234/*---------------------------------------------------------------------------*/
235void
236rpl_set_leaf_only(uint8_t value)
237{
238 rpl_leaf_only = value;
239}
240/*---------------------------------------------------------------------------*/
241uint8_t
243{
244 return rpl_leaf_only;
245}
246/*---------------------------------------------------------------------------*/
247const struct routing_driver rpl_lite_driver = {
248 "RPL Lite",
249 init,
250 rpl_dag_root_set_prefix,
251 rpl_dag_root_start,
252 rpl_dag_root_is_root,
259 rpl_local_repair,
260 rpl_ext_header_remove,
261 rpl_ext_header_update,
262 rpl_ext_header_hbh_update,
263 rpl_ext_header_srh_update,
264 rpl_ext_header_srh_get_next_hop,
269};
270/*---------------------------------------------------------------------------*/
271
272/** @}*/
void rpl_neighbor_init(void)
Initialize rpl-dag-neighbor module.
rpl_nbr_t * rpl_neighbor_get_from_lladdr(uip_lladdr_t *addr)
Returns a neighbor from its link-layer address.
int rpl_dag_get_root_ipaddr(uip_ipaddr_t *ipaddr)
Returns the IPv6 address of the RPL DAG root, if any.
Definition rpl-dag.c:89
int rpl_set_prefix(rpl_prefix_t *prefix)
Set prefix from an prefix data structure (from DIO)
Definition rpl.c:185
int rpl_is_reachable(void)
Get the RPL's best guess on if we are reachable via have downward route or not.
Definition rpl.c:127
void rpl_set_leaf_only(uint8_t value)
Changes the value of the rpl_leaf_only flag, which determines if a node acts only as a leaf in the ne...
Definition rpl.c:236
uint8_t rpl_get_leaf_only(void)
Get the value of the rpl_leaf_only flag.
Definition rpl.c:242
int rpl_lollipop_greater_than(int a, int b)
Greater-than function for a lollipop counter.
Definition rpl.c:57
uint16_t rpl_neighbor_get_link_metric(rpl_nbr_t *nbr)
Returns a neighbor's link metric.
void rpl_reset_prefix(rpl_prefix_t *last_prefix)
Removes current prefx.
Definition rpl.c:141
int rpl_set_prefix_from_addr(uip_ipaddr_t *addr, unsigned len, uint8_t flags)
Set prefix from an IPv6 address.
Definition rpl.c:157
void rpl_dag_poison_and_leave(void)
Start poisoning and leave the DAG after a delay.
Definition rpl-dag.c:131
void rpl_timers_init(void)
Initialize rpl-timers module.
Definition rpl-timers.c:505
void rpl_icmp6_init()
Initializes rpl-icmp6 module, registers ICMPv6 handlers for all RPL ICMPv6 messages: DIO,...
Definition rpl-icmp6.c:728
const uip_ipaddr_t * rpl_get_global_address(void)
Get one of the node's global addresses.
Definition rpl.c:71
void rpl_global_repair(const char *str)
Triggers a RPL global repair.
Definition rpl-dag.c:204
void rpl_timers_schedule_state_update(void)
Schedule a state update ASAP.
Definition rpl-timers.c:555
int rpl_has_joined(void)
Tells whether the node has joined a network or not.
Definition rpl-dag.c:1049
uip_lladdr_t uip_lladdr
Host L2 address.
Definition uip6.c:107
void uip_sr_init(void)
Initialize this module.
Definition uip-sr.c:191
uip_ds6_addr_t * uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
Add a unicast address to the interface.
Definition uip-ds6.c:352
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition uip.h:1766
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
Definition uip-ds6.c:568
void rpl_link_callback(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
Definition rpl.c:265
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition uip-ds6.c:75
Header file for the logging system.
Routing driver header file.
The structure of a routing protocol driver.
Definition routing.h:60
void(* init)(void)
Initialize the routing protocol.
Definition routing.h:63
void(* neighbor_state_changed)(uip_ds6_nbr_t *nbr)
Called by uIP to notify addition/removal of IPv6 neighbor entries.
Definition routing.h:176
int(* get_sr_node_ipaddr)(uip_ipaddr_t *ipaddr, const uip_sr_node_t *node)
Returns the global IPv6 address of a source routing node.
Definition routing.h:97
void(* drop_route)(uip_ds6_route_t *route)
Called by uIP if it has decided to drop a route because.
Definition routing.h:182
All information related to a RPL neighbor.
Definition rpl-types.h:136
RPL prefix information.
Definition rpl.h:128
Unicast address structure.
Definition uip-ds6.h:205
The default nbr_table entry (when UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr cach...
An entry in the routing table.
A node in a source routing graph, stored at the root and representing all child-parent relationship.
Definition uip-sr.h:92
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
Definition uip-nd6.c:106
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition uip-nd6.c:116
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition uip-nd6.c:107