Skip to content

Commit 3441594

Browse files
author
Juha Heiskanen
committed
RPL parent candidate list update
Added new API for RPL to ask instance candidate list sizeand size. Added API for remove worst parent candidate from list if user detect too much usage for replace. Replaced candidate must be proped or otherwise new candidate is dropped. Extend Objection function point for validate is new candidate enough good for add. WS_RPL_MIN_HOP_RANK_INCREASE from 196 to 160. This will reduce a case that device is not switching too aggressive to 1 hop shorter parent. Update Worts candidate select function for compare path cost and smarter dio age definition. Change-Id: I67150ab4eae96c90fbded9ff1a9c9084bdf97eae
1 parent 96ffe92 commit 3441594

12 files changed

+272
-64
lines changed

source/6LoWPAN/ws/ws_bootstrap.c

+61-36
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *
9797
static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry_t *cur, void *neighbor);
9898
static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr);
9999
static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
100-
static bool ws_rpl_dio_new_parent_accept(struct protocol_interface_info_entry *interface);
101100

102101

103102
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
@@ -321,12 +320,16 @@ static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighb
321320
}
322321
}
323322

324-
static bool ws_nud_message_build(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbor)
323+
static bool ws_nud_message_build(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbor, bool nud_process)
325324
{
326325
//Send NS
327326
uint8_t ll_target[16];
328327
ws_bootsrap_create_ll_address(ll_target, neighbor->mac64);
329-
tr_info("NUD generate NS %u", neighbor->index);
328+
if (nud_process) {
329+
tr_info("NUD generate NS %u", neighbor->index);
330+
} else {
331+
tr_info("Probe generate NS %u", neighbor->index);
332+
}
330333
buffer_t *buffer = icmpv6_build_ns(cur, ll_target, NULL, true, false, NULL);
331334
if (buffer) {
332335
protocol_push(buffer);
@@ -368,7 +371,7 @@ void ws_nud_active_timer(protocol_interface_info_entry_t *cur, uint16_t ticks)
368371

369372
} else {
370373
//Random TX wait period is over
371-
entry->wait_response = ws_nud_message_build(cur, entry->neighbor_info);
374+
entry->wait_response = ws_nud_message_build(cur, entry->neighbor_info, entry->nud_process);
372375
if (!entry->wait_response) {
373376
if (entry->nud_process && entry->retry_count < 2) {
374377
entry->timer = randLIB_get_random_in_range(1, 900);
@@ -1591,25 +1594,6 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
15911594
return true;
15921595
}
15931596

1594-
static bool ws_rpl_dio_new_parent_accept(struct protocol_interface_info_entry *interface)
1595-
{
1596-
uint16_t parent_candidate_size = rpl_control_parent_candidate_list_size(interface, false);
1597-
//TODO check bootstarap state for review
1598-
//if we have enough candidates at list do not accept new multicast neighbours
1599-
if (parent_candidate_size > interface->ws_info->rpl_parent_candidate_max) {
1600-
return false;
1601-
}
1602-
1603-
parent_candidate_size = rpl_control_parent_candidate_list_size(interface, true);
1604-
//If we have already enough parent selected Candidates count is bigger than configured
1605-
if (parent_candidate_size >= interface->ws_info->rpl_selected_parent_max) {
1606-
return false;
1607-
}
1608-
1609-
return true;
1610-
}
1611-
1612-
16131597
static void ws_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
16141598
{
16151599

@@ -1647,7 +1631,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
16471631
}
16481632

16491633
uint8_t ll_address[16];
1650-
1634+
bool nud_proces = false;
16511635
if (time_from_start > WS_NEIGHBOR_NUD_TIMEOUT) {
16521636

16531637
ws_bootsrap_create_ll_address(ll_address, entry_ptr->mac64);
@@ -1668,6 +1652,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
16681652
activate_nud = true;
16691653
}
16701654
}
1655+
nud_proces = activate_nud;
16711656
} else if (etx_entry->etx_samples < WS_NEIGBOR_ETX_SAMPLE_MAX) {
16721657
//Take Random number for trig a prope.
16731658
//ETX Sample 0: random 1-8
@@ -1679,7 +1664,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
16791664
} else {
16801665

16811666
ws_bootsrap_create_ll_address(ll_address, entry_ptr->mac64);
1682-
if (!rpl_control_is_dodag_parent_candidate(cur, ll_address, WS_NEIGHBOUR_MAX_CANDIDATE_PROBE)) {
1667+
if (!rpl_control_probe_parent_candidate(cur, ll_address)) {
16831668
return false;
16841669
}
16851670

@@ -1712,10 +1697,8 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
17121697
ws_neighbor->accelerated_etx_probe = false;
17131698
entry->timer = 1;
17141699
}
1700+
entry->nud_process = nud_proces;
17151701

1716-
if (etx_entry->etx_samples >= WS_NEIGBOR_ETX_SAMPLE_MAX) {
1717-
entry->nud_process = true;
1718-
}
17191702
return true;
17201703
}
17211704

@@ -2150,34 +2133,70 @@ static void ws_rpl_prefix_callback(prefix_entry_t *prefix, void *handle, uint8_t
21502133
}
21512134
}
21522135

2153-
static bool ws_rpl_new_parent_callback_t(uint8_t *ll_parent_address, void *handle)
2136+
static bool ws_rpl_new_parent_callback(uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance, uint16_t candidate_rank)
21542137
{
21552138

21562139
protocol_interface_info_entry_t *cur = handle;
21572140
if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) {
21582141
return false;
21592142
}
21602143

2144+
if (blacklist_reject(ll_parent_address)) {
2145+
// Rejected by blacklist
2146+
return false;
2147+
}
2148+
2149+
uint8_t replacing[16];
21612150
uint8_t mac64[8];
2162-
memcpy(mac64, ll_parent_address + 8, 8);
2163-
mac64[0] ^= 2;
2151+
bool replace_ok = false;
2152+
bool create_ok = false;
21642153
llc_neighbour_req_t neigh_buffer;
2154+
if (rpl_control_candidate_list_size(cur, instance) < cur->ws_info->rpl_parent_candidate_max) {
2155+
//Not reach max value yet accept then all go to create neigh table
2156+
goto neigh_create;
2157+
}
2158+
2159+
2160+
if (!rpl_control_find_worst_neighbor(cur, instance, replacing)) {
2161+
return false;
2162+
}
2163+
2164+
// if not yet probed, return false
2165+
memcpy(mac64, replacing + 8, 8);
2166+
mac64[0] ^= 2;
2167+
21652168
if (ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, false)) {
2166-
return true;
2169+
//Verify that we have proped min 1 time
2170+
etx_storage_t *etx_entry = etx_storage_entry_get(cur->id, neigh_buffer.neighbor->index);
2171+
if (etx_entry && etx_entry->etx_samples == 0) {
2172+
return false;
2173+
}
21672174
}
21682175

2169-
if (!ws_rpl_dio_new_parent_accept(cur)) {
2176+
// Accept now only better one's when max candidates slected and max candidate list size is reached
2177+
if (!rpl_possible_better_candidate(cur, instance, replacing, candidate_rank)) {
21702178
return false;
21712179
}
2180+
//TODO if replacing has poor ETX, put it in blacklist as "poor ETX" to prevent reselection
2181+
//Mark That We can try remove replaced link
2182+
replace_ok = true;
21722183

2173-
//Discover Multicast temporary entry
2184+
neigh_create:
2185+
2186+
memcpy(mac64, ll_parent_address + 8, 8);
2187+
mac64[0] ^= 2;
2188+
if (ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, false)) {
2189+
create_ok = true;
2190+
goto neigh_create_ok;
2191+
}
21742192

2193+
//Discover Multicast temporary entry
21752194
ws_neighbor_temp_class_t *entry = ws_llc_get_multicast_temp_entry(cur, mac64);
21762195
if (!entry) {
21772196
return false;
21782197
}
21792198
//Create entry
2180-
bool create_ok = ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, true);
2199+
create_ok = ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, true);
21812200
if (create_ok) {
21822201
ws_neighbor_class_entry_t *ws_neigh = neigh_buffer.ws_neighbor;
21832202
//Copy fhss temporary data
@@ -2188,7 +2207,13 @@ static bool ws_rpl_new_parent_callback_t(uint8_t *ll_parent_address, void *handl
21882207
}
21892208
ws_llc_free_multicast_temp_entry(cur, entry);
21902209

2210+
neigh_create_ok:
21912211

2212+
if (create_ok && replace_ok) {
2213+
//Try remove here when accepted new better one possible
2214+
tr_debug("Remove %s by %s", trace_ipv6(replacing), trace_ipv6(ll_parent_address));
2215+
rpl_control_neighbor_delete_from_instance(cur, instance, replacing);
2216+
}
21922217
return create_ok;
21932218
}
21942219

@@ -2200,7 +2225,7 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
22002225

22012226
addr_add_router_groups(cur);
22022227
rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, downstream);
2203-
rpl_control_set_callback(protocol_6lowpan_rpl_domain, ws_bootstrap_rpl_callback, ws_rpl_prefix_callback, ws_rpl_new_parent_callback_t, cur);
2228+
rpl_control_set_callback(protocol_6lowpan_rpl_domain, ws_bootstrap_rpl_callback, ws_rpl_prefix_callback, ws_rpl_new_parent_callback, cur);
22042229
// If i am router I Do this
22052230
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, leaf);
22062231
rpl_control_request_parent_link_confirmation(true);

source/6LoWPAN/ws/ws_config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#define WS_RPL_DIO_DOUBLING 2
3232
#define WS_RPL_DIO_REDUNDANCY 0
3333

34-
#define WS_RPL_MIN_HOP_RANK_INCREASE 196
34+
#define WS_RPL_MIN_HOP_RANK_INCREASE 160
3535
#define WS_RPL_MAX_HOP_RANK_INCREASE 2048
3636

3737
#define WS_CERTIFICATE_RPL_MIN_HOP_RANK_INCREASE 128

source/RPL/rpl_control.c

+87-9
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,46 @@ bool rpl_control_is_dodag_parent_candidate(protocol_interface_info_entry_t *inte
247247
return false;
248248
}
249249

250+
uint16_t rpl_control_candidate_list_size(protocol_interface_info_entry_t *interface, rpl_instance_t *rpl_instance)
251+
{
252+
if (!interface->rpl_domain) {
253+
return 0;
254+
}
255+
256+
return rpl_instance_address_candidate_count(rpl_instance, false);
257+
258+
}
259+
260+
261+
bool rpl_control_probe_parent_candidate(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16])
262+
{
263+
if (!interface->rpl_domain) {
264+
return false;
265+
}
266+
// go through instances and parents and check if they match the address.
267+
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
268+
if (rpl_lookup_neighbour_by_ll_address(instance, ll_addr, interface->id)) {
269+
return true;
270+
}
271+
}
272+
return false;
273+
}
274+
275+
bool rpl_possible_better_candidate(struct protocol_interface_info_entry *interface, rpl_instance_t *rpl_instance, const uint8_t ll_addr[16], uint16_t candidate_rank)
276+
{
277+
if (!interface->rpl_domain) {
278+
return false;
279+
}
280+
281+
rpl_neighbour_t *neighbour = rpl_lookup_neighbour_by_ll_address(rpl_instance, ll_addr, interface->id);
282+
if (!neighbour) {
283+
return false;
284+
}
285+
286+
return rpl_instance_possible_better_candidate(rpl_instance, neighbour, candidate_rank);
287+
288+
}
289+
250290

251291
uint16_t rpl_control_parent_candidate_list_size(protocol_interface_info_entry_t *interface, bool parent_list)
252292
{
@@ -266,6 +306,13 @@ uint16_t rpl_control_parent_candidate_list_size(protocol_interface_info_entry_t
266306
return parent_list_size;
267307
}
268308

309+
void rpl_control_neighbor_delete_from_instance(protocol_interface_info_entry_t *interface, rpl_instance_t *instance, const uint8_t ll_addr[16])
310+
{
311+
rpl_neighbour_t *neighbour = rpl_lookup_neighbour_by_ll_address(instance, ll_addr, interface->id);
312+
if (neighbour) {
313+
rpl_delete_neighbour(instance, neighbour);
314+
}
315+
}
269316

270317
void rpl_control_neighbor_delete(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16])
271318
{
@@ -274,14 +321,26 @@ void rpl_control_neighbor_delete(protocol_interface_info_entry_t *interface, con
274321
}
275322
// go through instances and delete address.
276323
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
324+
rpl_control_neighbor_delete_from_instance(interface, instance, ll_addr);
325+
}
326+
}
277327

278-
rpl_neighbour_t *neighbour = rpl_lookup_neighbour_by_ll_address(instance, ll_addr, interface->id);
279-
if (neighbour) {
280-
rpl_delete_neighbour(instance, neighbour);
281-
}
328+
bool rpl_control_find_worst_neighbor(protocol_interface_info_entry_t *interface, rpl_instance_t *rpl_instance, uint8_t ll_addr[static 16])
329+
{
330+
if (!interface->rpl_domain) {
331+
return false;
332+
}
333+
334+
rpl_neighbour_t *neighbour = rpl_lookup_last_candidate_from_list(rpl_instance);
335+
if (neighbour) {
336+
memcpy(ll_addr, rpl_neighbour_ll_address(neighbour), 16);
337+
return true;
282338
}
339+
340+
return false;
283341
}
284342

343+
285344
/* Address changes need to trigger DAO target re-evaluation */
286345
static void rpl_control_addr_notifier(struct protocol_interface_info_entry *interface, const if_address_entry_t *addr, if_address_callback_t reason)
287346
{
@@ -1015,7 +1074,7 @@ static buffer_t *rpl_control_dio_handler(protocol_interface_info_entry_t *cur, r
10151074
const rpl_dodag_conf_t *conf = rpl_dodag_get_config(dodag);
10161075
if (!conf) {
10171076
/* TODO - rate limit DIS? */
1018-
if (domain->new_parent_add && !domain->new_parent_add(buf->src_sa.address, domain->cb_handle)) {
1077+
if (domain->new_parent_add && !domain->new_parent_add(buf->src_sa.address, domain->cb_handle, instance, rank)) {
10191078
goto invalid_parent;
10201079
}
10211080
rpl_control_transmit_dis(domain, cur, RPL_SOLINFO_PRED_DODAGID | RPL_SOLINFO_PRED_INSTANCEID, instance_id, dodagid, 0, buf->src_sa.address);
@@ -1049,15 +1108,21 @@ static buffer_t *rpl_control_dio_handler(protocol_interface_info_entry_t *cur, r
10491108

10501109
/* Now we create the neighbour, if we don't already have a record */
10511110
if (!neighbour) {
1111+
1112+
if (domain->new_parent_add) {
1113+
1114+
if (!domain->new_parent_add(buf->src_sa.address, domain->cb_handle, instance, rank)) {
1115+
goto invalid_parent;
1116+
}
1117+
}
1118+
10521119
neighbour = rpl_create_neighbour(version, buf->src_sa.address, cur->id, g_mop_prf, dtsn);
10531120
//Call Here new parent create
10541121
if (!neighbour) {
10551122
goto invalid_parent;
10561123
}
10571124

1058-
if (domain->new_parent_add && !domain->new_parent_add(buf->src_sa.address, domain->cb_handle)) {
1059-
goto invalid_parent;
1060-
}
1125+
10611126

10621127
}
10631128

@@ -1776,12 +1841,25 @@ static void rpl_domain_print(const rpl_domain_t *domain, route_print_fn_t *print
17761841

17771842
void rpl_control_print(route_print_fn_t *print_fn)
17781843
{
1779-
print_fn("RPL memory usage %zu", rpl_alloc_total);
1844+
unsigned t = protocol_core_monotonic_time % 10;
1845+
unsigned s_full = protocol_core_monotonic_time / 10;
1846+
unsigned m = s_full / 60;
1847+
unsigned s = s_full % 60;
1848+
unsigned h = m / 60;
1849+
m %= 60;
1850+
print_fn("Time %02u:%02u:%02u.%u (%u.%u)", h, m, s, t, s_full, t);
1851+
// %zu doesn't work on some Mbed toolchains
1852+
print_fn("RPL memory usage %" PRIu32, (uint32_t) rpl_alloc_total);
17801853
ns_list_foreach(rpl_domain_t, domain, &rpl_domains) {
17811854
rpl_domain_print(domain, print_fn);
17821855
}
17831856
}
17841857

1858+
uint8_t rpl_policy_mrhof_parent_set_size_get(const rpl_domain_t *domain)
1859+
{
1860+
return rpl_policy_mrhof_parent_set_size(domain);
1861+
}
1862+
17851863
#ifdef RPL_STRUCTURES_H_
17861864
#error "rpl_structures.h should not be included by rpl_control.c"
17871865
#endif

0 commit comments

Comments
 (0)