Contiki-NG
rpl-dag-root.c
1/*
2 * Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
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 copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 */
31
32#include "contiki.h"
33#include "contiki-net.h"
34
35#include "net/routing/rpl-classic/rpl.h"
36#include "net/routing/rpl-classic/rpl-private.h"
38
39#include "sys/log.h"
40
41#include <string.h>
42
43#define LOG_MODULE "RPL"
44#define LOG_LEVEL LOG_LEVEL_RPL
45
46/*---------------------------------------------------------------------------*/
47static void
48set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
49{
50 static uip_ipaddr_t root_ipaddr;
51 const uip_ipaddr_t *default_prefix;
52 int i;
53
54 default_prefix = uip_ds6_default_prefix();
55
56 /* Assign a unique local address (RFC4193,
57 http://tools.ietf.org/html/rfc4193). */
58 if(prefix == NULL) {
59 uip_ip6addr_copy(&root_ipaddr, default_prefix);
60 } else {
61 memcpy(&root_ipaddr, prefix, 8);
62 }
63 if(iid == NULL) {
64 uip_ds6_set_addr_iid(&root_ipaddr, &uip_lladdr);
65 } else {
66 memcpy(((uint8_t*)&root_ipaddr) + 8, ((uint8_t*)iid) + 8, 8);
67 }
68
69 uip_ds6_addr_add(&root_ipaddr, 0, ADDR_AUTOCONF);
70
71 if(LOG_DBG_ENABLED) {
72 uint8_t state;
73
74 LOG_DBG("IPv6 addresses: \n");
75 for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
76 state = uip_ds6_if.addr_list[i].state;
77 if(uip_ds6_if.addr_list[i].isused &&
78 (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
79 LOG_DBG(" - ");
80 LOG_DBG_6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
81 LOG_DBG_("\n");
82 }
83 }
84 }
85}
86/*---------------------------------------------------------------------------*/
87void
88rpl_dag_root_set_prefix(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
89{
90 static uint8_t initialized = 0;
91
92 if(!initialized) {
93 set_global_address(prefix, iid);
94 initialized = 1;
95 }
96}
97/*---------------------------------------------------------------------------*/
98int
100{
101 struct uip_ds6_addr *root_if;
102 int i;
103 uint8_t state;
104 uip_ipaddr_t *ipaddr = NULL;
105
106 rpl_dag_root_set_prefix(NULL, NULL);
107
108 for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
109 state = uip_ds6_if.addr_list[i].state;
110 if(uip_ds6_if.addr_list[i].isused &&
111 state == ADDR_PREFERRED &&
112 !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) {
113 ipaddr = &uip_ds6_if.addr_list[i].ipaddr;
114 }
115 }
116
117 if(ipaddr != NULL) {
118 root_if = uip_ds6_addr_lookup(ipaddr);
119 if(root_if != NULL) {
120 rpl_dag_t *dag;
121 uip_ipaddr_t prefix;
122
123 rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr);
124 dag = rpl_get_any_dag();
125
126 /* If there are routes in this dag, we remove them all as we are
127 from now on the new dag root and the old routes are wrong */
128 if(RPL_IS_STORING(dag->instance)) {
129 rpl_remove_routes(dag);
130 }
131 if(dag->instance != NULL && dag->instance->def_route != NULL) {
132 uip_ds6_defrt_rm(dag->instance->def_route);
133 dag->instance->def_route = NULL;
134 }
135
136 uip_ip6addr_copy(&prefix, ipaddr);
137 rpl_set_prefix(dag, &prefix, 64);
138 LOG_INFO("root_set_prefix: created a new RPL dag\n");
139 return 0;
140 } else {
141 LOG_ERR("root_set_prefix: failed to create a new RPL DAG\n");
142 return -1;
143 }
144 } else {
145 LOG_ERR("root_set_prefix_dag: failed to create a new RPL DAG, no preferred IP address found\n");
146 return -2;
147 }
148}
149/*---------------------------------------------------------------------------*/
150int
152{
153 rpl_instance_t *instance;
154
155 instance = rpl_get_default_instance();
156
157 if(instance == NULL) {
158 return 0;
159 }
160
161 if(instance->current_dag &&
162 instance->current_dag->rank == ROOT_RANK(instance)) {
163 return 1;
164 }
165
166 return 0;
167}
168/*---------------------------------------------------------------------------*/
int rpl_dag_root_start(void)
Set the node as root and start a DAG.
Definition: rpl-dag-root.c:124
int rpl_dag_root_is_root(void)
Tells whether we are DAG root or not.
Definition: rpl-dag-root.c:158
void rpl_dag_root_set_prefix(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
Set a prefix in case the node is later set as dag root.
Definition: rpl-dag-root.c:113
#define ROOT_RANK
Rank of a root node.
Definition: rpl-types.h:78
const uip_ip6addr_t * uip_ds6_default_prefix()
Retrieve the Default IPv6 prefix.
Definition: uip-ds6.c:104
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
Definition: rpl-dag.c:1069
uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:107
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:360
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition: uip.h:1775
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
Definition: uip-ds6.c:576
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
Definition: uip-ds6.h:156
rpl_instance_t * rpl_get_default_instance(void)
Returns pointer to the default instance (for compatibility with legagy RPL code)
Definition: rpl-dag.c:627
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition: uip-ds6.c:75
Header file for the logging system.
RPL DAG structure.
Definition: rpl.h:135
RPL instance structure.
Definition: rpl.h:219
Unicast address structure.
Definition: uip-ds6.h:205
Header file for routing table manipulation.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:116