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"
37 #include "net/ipv6/uip-ds6-route.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 /*---------------------------------------------------------------------------*/
47 static void
48 set_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 /*---------------------------------------------------------------------------*/
87 void
88 rpl_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 /*---------------------------------------------------------------------------*/
98 int
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  const uip_ipaddr_t *default_prefix;
123 
124  rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr);
125  dag = rpl_get_any_dag();
126  default_prefix = uip_ds6_default_prefix();
127 
128  /* If there are routes in this dag, we remove them all as we are
129  from now on the new dag root and the old routes are wrong */
130  if(RPL_IS_STORING(dag->instance)) {
131  rpl_remove_routes(dag);
132  }
133  if(dag->instance != NULL && dag->instance->def_route != NULL) {
134  uip_ds6_defrt_rm(dag->instance->def_route);
135  dag->instance->def_route = NULL;
136  }
137 
138  uip_ip6addr_copy(&prefix, default_prefix);
139  rpl_set_prefix(dag, &prefix, 64);
140  LOG_INFO("root_set_prefix: created a new RPL dag\n");
141  return 0;
142  } else {
143  LOG_ERR("root_set_prefix: failed to create a new RPL DAG\n");
144  return -1;
145  }
146  } else {
147  LOG_ERR("root_set_prefix_dag: failed to create a new RPL DAG, no preferred IP address found\n");
148  return -2;
149  }
150 }
151 /*---------------------------------------------------------------------------*/
152 int
154 {
155  rpl_instance_t *instance;
156 
157  instance = rpl_get_default_instance();
158 
159  if(instance == NULL) {
160  return 0;
161  }
162 
163  if(instance->current_dag &&
164  instance->current_dag->rank == ROOT_RANK(instance)) {
165  return 1;
166  }
167 
168  return 0;
169 }
170 /*---------------------------------------------------------------------------*/
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:116
uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:107
int rpl_dag_root_start(void)
Set the node as root and start a DAG.
Definition: rpl-dag-root.c:124
RPL DAG structure.
Definition: rpl.h:135
RPL instance structure.
Definition: rpl.h:219
#define ROOT_RANK
Rank of a root node.
Definition: rpl-types.h:78
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
int rpl_dag_root_is_root(void)
Tells whether we are DAG root or not.
Definition: rpl-dag-root.c:158
const uip_ip6addr_t * uip_ds6_default_prefix()
Retrieve the Default IPv6 prefix.
Definition: uip-ds6.c:104
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
Unicast address structure.
Definition: uip-ds6.h:205
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
Definition: rpl-dag.c:1073
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
Definition: uip-ds6.h:156
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
uip_ds6_netif_t uip_ds6_if
The single interface.
Definition: uip-ds6.c:75
Header file for routing table manipulation.
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition: uip.h:1877
Header file for the logging system
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