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 <string.h>
40 
41 #define DEBUG DEBUG_NONE
42 #include "net/ipv6/uip-debug.h"
43 
44 /*---------------------------------------------------------------------------*/
45 static void
46 set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
47 {
48  static uip_ipaddr_t root_ipaddr;
49  int i;
50  uint8_t state;
51 
52  /* Assign a unique local address (RFC4193,
53  http://tools.ietf.org/html/rfc4193). */
54  if(prefix == NULL) {
55  uip_ip6addr(&root_ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
56  } else {
57  memcpy(&root_ipaddr, prefix, 8);
58  }
59  if(iid == NULL) {
60  uip_ds6_set_addr_iid(&root_ipaddr, &uip_lladdr);
61  } else {
62  memcpy(((uint8_t*)&root_ipaddr) + 8, ((uint8_t*)iid) + 8, 8);
63  }
64 
65  uip_ds6_addr_add(&root_ipaddr, 0, ADDR_AUTOCONF);
66 
67  printf("IPv6 addresses: ");
68  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
69  state = uip_ds6_if.addr_list[i].state;
70  if(uip_ds6_if.addr_list[i].isused &&
71  (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
72  uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
73  printf("\n");
74  }
75  }
76 }
77 /*---------------------------------------------------------------------------*/
78 void
79 rpl_dag_root_set_prefix(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
80 {
81  static uint8_t initialized = 0;
82 
83  if(!initialized) {
84  set_global_address(prefix, iid);
85  initialized = 1;
86  }
87 }
88 /*---------------------------------------------------------------------------*/
89 int
91 {
92  struct uip_ds6_addr *root_if;
93  int i;
94  uint8_t state;
95  uip_ipaddr_t *ipaddr = NULL;
96 
97  rpl_dag_root_set_prefix(NULL, NULL);
98 
99  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
100  state = uip_ds6_if.addr_list[i].state;
101  if(uip_ds6_if.addr_list[i].isused &&
102  state == ADDR_PREFERRED &&
103  !uip_is_addr_linklocal(&uip_ds6_if.addr_list[i].ipaddr)) {
104  ipaddr = &uip_ds6_if.addr_list[i].ipaddr;
105  }
106  }
107 
108  if(ipaddr != NULL) {
109  root_if = uip_ds6_addr_lookup(ipaddr);
110  if(root_if != NULL) {
111  rpl_dag_t *dag;
112  uip_ipaddr_t prefix;
113 
114  rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr);
115  dag = rpl_get_any_dag();
116 
117  /* If there are routes in this dag, we remove them all as we are
118  from now on the new dag root and the old routes are wrong */
119  if(RPL_IS_STORING(dag->instance)) {
120  rpl_remove_routes(dag);
121  }
122  if(dag->instance != NULL && dag->instance->def_route != NULL) {
123  uip_ds6_defrt_rm(dag->instance->def_route);
124  dag->instance->def_route = NULL;
125  }
126 
127  uip_ip6addr(&prefix, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
128  rpl_set_prefix(dag, &prefix, 64);
129  PRINTF("rpl_dag_root_set_prefix_dag: created a new RPL dag\n");
130  return 0;
131  } else {
132  PRINTF("rpl_dag_root_set_prefix_dag: failed to create a new RPL DAG\n");
133  return -1;
134  }
135  } else {
136  PRINTF("rpl_dag_root_set_prefix_dag: failed to create a new RPL DAG, no preferred IP address found\n");
137  return -2;
138  }
139 }
140 /*---------------------------------------------------------------------------*/
141 int
143 {
144  rpl_instance_t *instance;
145 
146  instance = rpl_get_default_instance();
147 
148  if(instance == NULL) {
149  return 0;
150  }
151 
152  if(instance->current_dag &&
153  instance->current_dag->rank == ROOT_RANK(instance)) {
154  return 1;
155  }
156 
157  return 0;
158 }
159 /*---------------------------------------------------------------------------*/
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:124
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
Definition: uip.h:961
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:121
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
A set of debugging macros for the IP stack
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:557
int rpl_dag_root_is_root(void)
Tells whether we are DAG root or not.
Definition: rpl-dag-root.c:155
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:110
Unicast address structure.
Definition: uip-ds6.h:204
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
Definition: rpl-dag.c:1051
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
Definition: uip-ds6.h:155
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:341
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:2023
rpl_instance_t * rpl_get_default_instance(void)
Returns pointer to the default instance (for compatibility with legagy RPL code)
Definition: rpl-dag.c:624