51 #include "net/routing/rpl-classic/rpl-private.h" 52 #include "net/routing/rpl-classic/rpl-dag-root.h" 60 #define LOG_MODULE "RPL" 61 #define LOG_LEVEL LOG_LEVEL_RPL 64 rpl_stats_t rpl_stats;
67 static enum rpl_mode mode = RPL_MODE_MESH;
78 enum rpl_mode oldmode = mode;
82 if(m == RPL_MODE_MESH) {
88 LOG_DBG(
"rpl_set_mode: switching to mesh mode\n");
91 if(default_instance != NULL) {
92 rpl_schedule_dao_immediately(default_instance);
94 }
else if(m == RPL_MODE_FEATHER) {
96 LOG_INFO(
"rpl_set_mode: switching to feather mode\n");
97 if(default_instance != NULL) {
98 LOG_INFO(
"rpl_set_mode: RPL sending DAO with zero lifetime\n");
99 if(default_instance->current_dag != NULL) {
100 dao_output(default_instance->current_dag->preferred_parent, RPL_ZERO_LIFETIME);
102 rpl_cancel_dao(default_instance);
104 LOG_INFO(
"rpl_set_mode: no default instance\n");
116 rpl_purge_routes(
void)
121 #if RPL_WITH_MULTICAST 126 r = uip_ds6_route_head();
129 if(r->state.lifetime >= 1 && r->state.lifetime != RPL_ROUTE_INFINITE_LIFETIME) {
137 r = uip_ds6_route_next(r);
141 r = uip_ds6_route_head();
144 if(r->state.lifetime < 1) {
149 r = uip_ds6_route_head();
150 LOG_INFO(
"No more routes to ");
151 LOG_INFO_6ADDR(&prefix);
152 dag = default_instance->current_dag;
154 if(dag->rank !=
ROOT_RANK(default_instance)) {
155 LOG_INFO_(
" -> generate No-Path DAO\n");
156 dao_output_target(dag->preferred_parent, &prefix, RPL_ZERO_LIFETIME);
162 r = uip_ds6_route_next(r);
166 #if RPL_WITH_MULTICAST 169 while(mcast_route != NULL) {
185 #if RPL_WITH_MULTICAST 189 r = uip_ds6_route_head();
192 if(r->state.dag == dag) {
194 r = uip_ds6_route_head();
196 r = uip_ds6_route_next(r);
200 #if RPL_WITH_MULTICAST 203 while(mcast_route != NULL) {
204 if(mcast_route->
dag == dag) {
215 rpl_remove_routes_by_nexthop(uip_ipaddr_t *nexthop,
rpl_dag_t *dag)
219 r = uip_ds6_route_head();
222 if(uip_ipaddr_cmp(uip_ds6_route_nexthop(r), nexthop) &&
223 r->state.dag == dag) {
224 r->state.lifetime = 0;
226 r = uip_ds6_route_next(r);
228 LOG_ANNOTATE(
"#L %u 0\n", nexthop->u8[
sizeof(uip_ipaddr_t) - 1]);
232 rpl_add_route(
rpl_dag_t *dag, uip_ipaddr_t *prefix,
int prefix_len,
233 uip_ipaddr_t *next_hop)
237 if((rep = uip_ds6_route_add(prefix, prefix_len, next_hop)) == NULL) {
238 LOG_ERR(
"No space for more route entries\n");
242 rep->state.dag = dag;
243 rep->state.lifetime =
RPL_LIFETIME(dag->instance, dag->instance->default_lifetime);
245 RPL_ROUTE_CLEAR_NOPATH_RECEIVED(rep);
247 LOG_INFO(
"Added a route to ");
248 LOG_INFO_6ADDR(prefix);
249 LOG_INFO_(
"/%d via ", prefix_len);
250 LOG_INFO_6ADDR(next_hop);
260 rpl_parent_t *parent;
267 for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
268 if(instance->used == 1 ) {
269 parent = rpl_find_parent_any_dag(instance, &ipaddr);
274 if(instance->urgent_probing_target == parent) {
275 instance->urgent_probing_target = NULL;
279 LOG_DBG(
"rpl_link_callback triggering update\n");
280 parent->flags |= RPL_PARENT_FLAG_UPDATED;
293 LOG_DBG(
"Neighbor state changed for ");
294 LOG_DBG_6ADDR(&nbr->ipaddr);
295 #if UIP_ND6_SEND_NS || UIP_ND6_SEND_RA 296 LOG_DBG_(
", nscount=%u, state=%u\n", nbr->nscount, nbr->state);
298 LOG_DBG_(
", state=%u\n", nbr->state);
300 for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
301 if(instance->used == 1 ) {
302 p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
304 p->rank = RPL_INFINITE_RANK;
306 LOG_DBG(
"rpl_ipv6_neighbor_callback infinite rank\n");
307 p->flags |= RPL_PARENT_FLAG_UPDATED;
320 for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES;
321 instance < end; ++instance) {
323 for(i = 0; i < RPL_MAX_DAG_PER_INSTANCE; i++) {
324 if(instance->dag_table[i].used) {
325 if(instance->dag_table[i].lifetime == 0) {
326 if(!instance->dag_table[i].joined) {
327 LOG_INFO(
"Removing dag ");
328 LOG_INFO_6ADDR(&instance->dag_table[i].dag_id);
330 rpl_free_dag(&instance->dag_table[i]);
333 instance->dag_table[i].lifetime--;
344 uip_ipaddr_t rplmaddr;
345 LOG_INFO(
"rpl-classic started\n");
346 default_instance = NULL;
349 rpl_reset_periodic_timer();
350 rpl_icmp6_register_handlers();
354 uip_ds6_maddr_add(&rplmaddr);
357 memset(&rpl_stats, 0,
sizeof(rpl_stats));
360 #if RPL_WITH_NON_STORING 368 if(
addr != NULL && node != NULL) {
370 memcpy(((
unsigned char *)
addr) + 8, &node->link_identifier, 8);
378 global_repair(
const char *str)
381 if(dag != NULL && dag->instance != NULL) {
382 rpl_repair_root(dag->instance->instance_id);
387 local_repair(
const char *str)
402 if(dag != NULL && dag->instance != NULL) {
403 rpl_repair_root(dag->instance->instance_id);
410 LOG_ERR(
"leave_network not supported in RPL Classic\n");
414 get_root_ipaddr(uip_ipaddr_t *
ipaddr)
419 if(dag != NULL && ipaddr != NULL) {
445 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.
#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.
Header file for the logging system
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.