Contiki-NG
rpl-nbr-policy.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Yanzi Networks AB.
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 are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holders nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  */
30 
31 /**
32  * \addtogroup rpl-lite
33  * @{
34  *
35  * \file
36  *
37  * Default RPL NBR policy
38  * decides when to add a new discovered node to the nbr table from RPL.
39  *
40  * \author Joakim Eriksson <joakime@sics.se>
41  * Contributors: Niclas Finne <nfi@sics.se>, Oriol PiƱol <oriol@yanzi.se>,
42  *
43  */
44 
45 #include "net/routing/rpl-lite/rpl.h"
46 #include "net/nbr-table.h"
47 
48 /* Log configuration */
49 #include "sys/log.h"
50 #define LOG_MODULE "RPL"
51 #define LOG_LEVEL LOG_LEVEL_RPL
52 
53 /*
54  * Policy for neighbor addition
55  * - one node is locked (default route)
56  * - max X "best parents"
57  * => at least MAX_NBRS - (X + 1) free slots for other.
58  *
59  * NOTE: this policy assumes that all neighbors end up being IPv6
60  * neighbors and are not only MAC neighbors.
61  */
62 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
63 
64 static int num_parents; /* all nodes that are possible parents */
65 static int num_free;
66 static linkaddr_t *worst_rank_nbr_lladdr; /* lladdr of the the neighbor with the worst rank */
67 static rpl_rank_t worst_rank;
68 
69 /*---------------------------------------------------------------------------*/
70 static void
71 update_state(void)
72 {
73  uip_ds6_nbr_t *ds6_nbr;
75  rpl_rank_t nbr_rank;
76  int num_used = 0;
77 
78  worst_rank = 0;
79  worst_rank_nbr_lladdr = NULL;
80  num_parents = 0;
81 
82  ds6_nbr = nbr_table_head(ds6_neighbors);
83  while(ds6_nbr != NULL) {
84 
85  linkaddr_t *nbr_lladdr = nbr_table_get_lladdr(ds6_neighbors, ds6_nbr);
86  rpl_nbr = rpl_neighbor_get_from_lladdr((uip_lladdr_t *)nbr_lladdr);
87 
88  if(rpl_nbr != NULL && rpl_neighbor_is_parent(rpl_nbr)) {
89  num_parents++;
90  }
91 
92  nbr_rank = rpl_neighbor_rank_via_nbr(rpl_nbr);
93  /* Select worst-rank neighbor */
94  if(rpl_nbr != curr_instance.dag.preferred_parent
95  && nbr_rank > worst_rank) {
96  /* This is the worst-rank neighbor - this is a good candidate for removal */
97  worst_rank = nbr_rank;
98  worst_rank_nbr_lladdr = nbr_lladdr;
99  }
100 
101  ds6_nbr = nbr_table_next(ds6_neighbors, ds6_nbr);
102  num_used++;
103  }
104  /* how many more IP neighbors can be have? */
105  num_free = NBR_TABLE_MAX_NEIGHBORS - num_used;
106 
107  LOG_DBG("nbr-policy: free: %d, parents: %d\n", num_free, num_parents);
108 }
109 /*---------------------------------------------------------------------------*/
110 static const linkaddr_t *
111 find_worst_rank_nbr_lladdr(void)
112 {
113  update_state();
114  return worst_rank_nbr_lladdr;
115 }
116 /*---------------------------------------------------------------------------*/
117 static const linkaddr_t *
118 find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
119 {
120  update_state();
121 
122  if(!curr_instance.used || curr_instance.instance_id != dio->instance_id) {
123  LOG_WARN("nbr-policy: did not find instance id: %d\n", dio->instance_id);
124  return NULL;
125  }
126 
127  /* Add the new neighbor only if it is better than the current worst. */
128  if(dio->rank + curr_instance.min_hoprankinc < worst_rank - curr_instance.min_hoprankinc / 2) {
129  /* Found *great* neighbor - add! */
130  LOG_DBG("nbr-policy: DIO rank %u, worst_rank %u -- add to cache\n",
131  dio->rank, worst_rank);
132  return worst_rank_nbr_lladdr;
133  }
134 
135  LOG_DBG("nbr-policy: DIO rank %u, worst_rank %u -- do not add to cache\n",
136  dio->rank, worst_rank);
137  return NULL;
138 }
139 /*---------------------------------------------------------------------------*/
140 const linkaddr_t *
141 rpl_nbr_policy_find_removable(nbr_table_reason_t reason, void *data)
142 {
143  /* When we get the DIO/DAO/DIS we know that UIP contains the
144  incoming packet */
145  switch(reason) {
146  case NBR_TABLE_REASON_RPL_DIO:
147  return find_removable_dio(&UIP_IP_BUF->srcipaddr, data);
148  case NBR_TABLE_REASON_RPL_DIS:
149  return find_worst_rank_nbr_lladdr();
150  case NBR_TABLE_REASON_IPV6_ND_AUTOFILL:
151  return find_worst_rank_nbr_lladdr();
152  default:
153  return NULL;
154  }
155 }
156 /*---------------------------------------------------------------------------*/
157 /** @}*/
#define UIP_IP_BUF
Pointer to IP header.
Definition: uip-nd6.c:97
int rpl_neighbor_is_parent(rpl_nbr_t *nbr)
Tells whether a neighbor is in the parent set.
Definition: rpl-neighbor.c:287
All information related to a RPL neighbor.
Definition: rpl-types.h:136
rpl_rank_t rpl_neighbor_rank_via_nbr(rpl_nbr_t *nbr)
Returns our rank if selecting a given parent as preferred parent.
Definition: rpl-neighbor.c:234
Header file for the logging system
rpl_nbr_t * rpl_neighbor_get_from_lladdr(uip_lladdr_t *addr)
Returns a neighbor from its link-layer address.
Definition: rpl-neighbor.c:210
An entry in the nbr cache.
Definition: uip-ds6-nbr.h:69