51 #include "net/routing/rpl-classic/rpl-private.h" 52 #include "net/routing/rpl-classic/rpl-dag-root.h" 55 #define DEBUG DEBUG_NONE 62 rpl_stats_t rpl_stats;
65 static enum rpl_mode mode = RPL_MODE_MESH;
76 enum rpl_mode oldmode = mode;
80 if(m == RPL_MODE_MESH) {
86 PRINTF(
"RPL: switching to mesh mode\n");
89 if(default_instance != NULL) {
90 rpl_schedule_dao_immediately(default_instance);
92 }
else if(m == RPL_MODE_FEATHER) {
94 PRINTF(
"RPL: switching to feather mode\n");
95 if(default_instance != NULL) {
96 PRINTF(
"rpl_set_mode: RPL sending DAO with zero lifetime\n");
97 if(default_instance->current_dag != NULL) {
98 dao_output(default_instance->current_dag->preferred_parent, RPL_ZERO_LIFETIME);
100 rpl_cancel_dao(default_instance);
102 PRINTF(
"rpl_set_mode: no default instance\n");
114 rpl_purge_routes(
void)
119 #if RPL_WITH_MULTICAST 124 r = uip_ds6_route_head();
127 if(r->state.lifetime >= 1 && r->state.lifetime != RPL_ROUTE_INFINITE_LIFETIME) {
135 r = uip_ds6_route_next(r);
139 r = uip_ds6_route_head();
142 if(r->state.lifetime < 1) {
147 r = uip_ds6_route_head();
148 PRINTF(
"No more routes to ");
150 dag = default_instance->current_dag;
152 if(dag->rank !=
ROOT_RANK(default_instance)) {
153 PRINTF(
" -> generate No-Path DAO\n");
154 dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME);
160 r = uip_ds6_route_next(r);
164 #if RPL_WITH_MULTICAST 167 while(mcast_route != NULL) {
183 #if RPL_WITH_MULTICAST 187 r = uip_ds6_route_head();
190 if(r->state.dag == dag) {
192 r = uip_ds6_route_head();
194 r = uip_ds6_route_next(r);
198 #if RPL_WITH_MULTICAST 201 while(mcast_route != NULL) {
202 if(mcast_route->
dag == dag) {
213 rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop,
rpl_dag_t *dag)
217 r = uip_ds6_route_head();
220 if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) &&
221 r->state.dag == dag) {
222 r->state.lifetime = 0;
224 r = uip_ds6_route_next(r);
226 ANNOTATE(
"#L %u 0\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
230 rpl_add_route(
rpl_dag_t *dag, uip_ipaddr_t *prefix,
int prefix_len,
231 uip_ipaddr_t *next_hop)
235 if((rep = uip_ds6_route_add(prefix, prefix_len, next_hop)) == NULL) {
236 PRINTF(
"RPL: No space for more route entries\n");
240 rep->state.dag = dag;
241 rep->state.lifetime =
RPL_LIFETIME(dag->instance, dag->instance->default_lifetime);
243 RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep);
245 PRINTF(
"RPL: Added a route to ");
247 PRINTF(
"/%d via ", prefix_len);
248 PRINT6ADDR(next_hop);
258 rpl_parent_t *parent;
265 for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
266 if(instance->used == 1 ) {
267 parent = rpl_find_parent_any_dag(instance, &ipaddr);
271 if(instance->urgent_probing_target == parent) {
272 instance->urgent_probing_target = NULL;
275 PRINTF(
"RPL: rpl_link_callback triggering update\n");
276 parent->flags |= RPL_PARENT_FLAG_UPDATED;
289 PRINTF(
"RPL: Neighbor state changed for ");
290 PRINT6ADDR(&nbr->ipaddr);
291 #if UIP_ND6_SEND_NS || UIP_ND6_SEND_RA 292 PRINTF(
", nscount=%u, state=%u\n", nbr->nscount, nbr->state);
294 PRINTF(
", state=%u\n", nbr->state);
296 for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
297 if(instance->used == 1 ) {
298 p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
300 p->rank = RPL_INFINITE_RANK;
302 PRINTF(
"RPL: rpl_ipv6_neighbor_callback infinite rank\n");
303 p->flags |= RPL_PARENT_FLAG_UPDATED;
316 for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
317 instance < end; ++instance) {
319 for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
320 if(instance->dag_table[i].used) {
321 if(instance->dag_table[i].lifetime == 0) {
322 if(!instance->dag_table[i].joined) {
323 PRINTF(
"Removing dag ");
324 PRINT6ADDR(&instance->dag_table[i].dag_id);
326 rpl_free_dag(&instance->dag_table[i]);
329 instance->dag_table[i].lifetime--;
340 uip_ipaddr_t rplmaddr;
341 PRINTF(
"RPL started\n");
342 default_instance = NULL;
345 rpl_reset_periodic_timer();
346 rpl_icmp6_register_handlers();
350 uip_ds6_maddr_add(&rplmaddr);
353 memset(&rpl_stats, 0,
sizeof(rpl_stats));
356 #if RPL_WITH_NON_STORING 364 if(
addr != NULL && node != NULL) {
366 memcpy(((
unsigned char *)
addr) + 8, &node->link_identifier, 8);
374 global_repair(
const char *str)
377 if(dag != NULL && dag->instance != NULL) {
378 rpl_repair_root(dag->instance->instance_id);
383 local_repair(
const char *str)
398 if(dag != NULL && dag->instance != NULL) {
399 rpl_repair_root(dag->instance->instance_id);
406 PRINTF(
"RPL: leave_network not supported in RPL Classic\n");
410 get_root_ipaddr(uip_ipaddr_t *
ipaddr)
415 if(dag != NULL && ipaddr != NULL) {
441 rpl_ipv6_neighbor_callback,
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
void rpl_ext_header_remove(void)
Removes all RPL extension headers.
void rpl_link_callback(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
Header for the Contiki/uIP interface.
Header file for ICMPv6 message and error handing (RFC 4443)
int rpl_dag_root_start(void)
Set the node as root and start a DAG.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
int rpl_ext_header_hbh_update(int uip_ext_opt_offset)
Process and update the RPL hop-by-hop extension headers of the current uIP packet.
#define ROOT_RANK
Rank of a root node.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
enum rpl_mode rpl_get_mode(void)
Get the RPL mode.
void(* drop_route)(uip_ds6_route_t *route)
Called by uIP if it has decided to drop a route because.
int rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
Look for next hop from SRH of current uIP packet.
void uip_sr_init(void)
Initialize this module.
A set of debugging macros for the IP stack
#define RPL_LIFETIME(lifetime)
Compute lifetime, accounting for the lifetime unit.
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
int rpl_ext_header_update(void)
Adds/updates all RPL extension headers to current uIP packet.
int rpl_dag_root_is_root(void)
Tells whether we are DAG root or not.
void(* global_repair)(const char *str)
Triggers a global topology repair.
Header file for IPv6-related data structures.
void(* init)(void)
Initialize the routing protocol.
An entry in the routing table.
This header file contains configuration directives for uIPv6 multicast support.
int rpl_has_downward_route(void)
Get the RPL's best guess on if we have downward route or not.
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.
void * dag
Pointer to an rpl_dag_t struct.
Routing driver header file
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
uint32_t lifetime
Entry lifetime seconds.
An entry in the multicast routing table.
void(* leave_network)(void)
Leave the network the node is part of.
void uip_mcast6_route_rm(uip_mcast6_route_t *route)
Remove a multicast route.
Header file for the uIP TCP/IP stack.
void(* local_repair)(const char *str)
Triggers a RPL local topology repair.
int(* get_sr_node_ipaddr)(uip_ipaddr_t *addr, const uip_sr_node_t *node)
Returns the global IPv6 address of a source routing node.
int(* get_root_ipaddr)(uip_ipaddr_t *ipaddr)
Returns the IPv6 address of the network root, if any.
#define uip_create_linklocal_rplnodes_mcast(addr)
Set IP address addr to the link-local, all-rpl-nodes multicast address.
void rpl_local_repair(const char *str)
Triggers a RPL local repair.
int rpl_has_joined(void)
Tells whether the node has joined a network or not.
The structure of a routing protocol driver.
void * list_item_next(void *item)
Get the next item following this item.
A node in a source routing graph, stored at the root and representing all child-parent relationship...
uip_mcast6_route_t * uip_mcast6_route_list_head(void)
Retrieve a pointer to the start of the multicast routes list.
enum rpl_mode rpl_set_mode(enum rpl_mode m)
Set the RPL mode.
void rpl_dag_init(void)
Initializes rpl-dag module.
int rpl_ext_header_srh_update(void)
Process and update SRH in-place, i.e.
An entry in the nbr cache.