Skip to content

Commit 6e063b6

Browse files
author
Mika Tervonen
committed
added Wi-SUN neighbor table management to Wi-SUN
check if ARO registrations are allowed Cleans neighbors that are not concerned valid if there is no room for new neighbour Defined temporary entry count and RPL parent set size child count is currently set to 22 Added RPL function to set if address is our parent Added neighbor table function to check if neighbor has valid ARO registration
1 parent 59a65ea commit 6e063b6

File tree

14 files changed

+131
-0
lines changed

14 files changed

+131
-0
lines changed

source/6LoWPAN/ND/nd_router_object.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,12 @@ bool nd_ns_aro_handler(protocol_interface_info_entry_t *cur_interface, const uin
923923
}
924924

925925
/* TODO - check hard upper limit on registrations? */
926+
if (ws_info(cur_interface) &&
927+
!ws_common_allow_child_registration(cur_interface)) {
928+
aro_out->present = true;
929+
aro_out->status = ARO_FULL;
930+
return true;
931+
}
926932

927933
/* We need to have entry in the Neighbour Cache */
928934
ipv6_neighbour_t *neigh = ipv6_neighbour_lookup_or_create(&cur_interface->ipv6_neighbour_cache, src_addr);

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,49 @@ static void ws_bootstrap_asynch_confirm(struct protocol_interface_info_entry *in
11691169
(void)interface;
11701170
(void)asynch_message;
11711171
}
1172+
static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_entry *interface)
1173+
{
1174+
uint8_t ll_target[16];
1175+
1176+
if (mac_neighbor_info(interface)->neighbour_list_size <= mac_neighbor_info(interface)->list_total_size - WS_NON_CHILD_NEIGHBOUR_COUNT ) {
1177+
// Enough neighbor entries
1178+
return;
1179+
}
1180+
memcpy(ll_target, ADDR_LINK_LOCAL_PREFIX, 8);
1181+
1182+
mac_neighbor_table_entry_t *neighbor_entry_ptr = NULL;
1183+
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) {
1184+
1185+
if (cur->link_role == PRIORITY_PARENT_NEIGHBOUR) {
1186+
//This is our primary parent we cannot delete
1187+
continue;
1188+
}
1189+
1190+
if (neighbor_entry_ptr && neighbor_entry_ptr->lifetime < cur->lifetime) {
1191+
// We have already shorter link entry found this cannot replace it
1192+
continue;
1193+
}
1194+
1195+
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, cur->mac64)) {
1196+
// We have registered entry so we have been selected as parent
1197+
continue;
1198+
}
1199+
1200+
memcpy(ll_target + 8, cur->mac64, 8);
1201+
ll_target[8] ^= 2;
1202+
1203+
if (rpl_control_is_dodag_parent(interface, ll_target)) {
1204+
// Possible parent is limited to 3 by default?
1205+
continue;
1206+
}
1207+
neighbor_entry_ptr = cur;
1208+
}
1209+
if (neighbor_entry_ptr) {
1210+
tr_info("dropped oldest neighbour %s", trace_array(neighbor_entry_ptr->mac64, 8));
1211+
mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), neighbor_entry_ptr);
1212+
}
1213+
1214+
}
11721215

11731216
static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, llc_neighbour_req_t *neighbor_buffer, bool request_new)
11741217
{
@@ -1183,6 +1226,7 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
11831226
if (!request_new) {
11841227
return false;
11851228
}
1229+
ws_bootstrap_neighbor_table_clean(interface);
11861230

11871231
neighbor_buffer->neighbor = ws_bootstrap_mac_neighbor_add(interface, mac_64);
11881232

source/6LoWPAN/ws/ws_common.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <ns_list.h>
2424
#include <nsdynmemLIB.h>
2525
#include "NWK_INTERFACE/Include/protocol.h"
26+
#include "6LoWPAN/ws/ws_config.h"
2627
#include "6LoWPAN/ws/ws_common_defines.h"
2728
#include "6LoWPAN/ws/ws_common.h"
2829
#include "6LoWPAN/ws/ws_bootstrap.h"
@@ -201,6 +202,23 @@ void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8
201202
}
202203
}
203204

205+
bool ws_common_allow_child_registration(protocol_interface_info_entry_t *interface)
206+
{
207+
uint8_t child_count = 0;
208+
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) {
209+
210+
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, cur->mac64)) {
211+
child_count++;
212+
if (child_count > (mac_neighbor_info(interface)->list_total_size - WS_NON_CHILD_NEIGHBOUR_COUNT)) {
213+
tr_warn("Child registration not allowed %d/%d, max:%d", child_count, (mac_neighbor_info(interface)->list_total_size - WS_NON_CHILD_NEIGHBOUR_COUNT), mac_neighbor_info(interface)->list_total_size);
214+
return false;
215+
}
216+
}
217+
}
218+
tr_info("Child registration allowed %d/%d, max:%d", child_count, (mac_neighbor_info(interface)->list_total_size - WS_NON_CHILD_NEIGHBOUR_COUNT), mac_neighbor_info(interface)->list_total_size);
219+
return true;
220+
}
221+
204222

205223
#endif // HAVE_WS
206224

source/6LoWPAN/ws/ws_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,15 @@ void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
106106

107107
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
108108

109+
bool ws_common_allow_child_registration(protocol_interface_info_entry_t *cur);
110+
109111
#define ws_info(cur) ((cur)->ws_info)
110112
#else
111113
#define ws_info(cur) ((ws_info_t *) NULL)
112114
#define ws_common_seconds_timer(cur, seconds)
113115
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
114116
#define ws_common_fast_timer(cur, ticks) ((void) 0)
117+
#define ws_common_allow_child_registration(cur) (false)
115118

116119

117120
#endif //HAVE_WS

source/6LoWPAN/ws/ws_config.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,14 @@ extern int8_t DEVICE_MIN_SENS;
9999
#define WS_DHCP_SOLICIT_MAX_RC 0
100100

101101

102+
/* Neighbour table configuration
103+
*
104+
* Amount of RPL candidate parents
105+
* Amount of ND reply entries left
106+
* rest are used as child count, but is related to neighbour table size
107+
*/
108+
#define WS_RPL_CANDIDATE_PARENT_COUNT 3 // Largest possible value
109+
#define WS_TEMPORARY_NEIGHBOUR_ENTRIES 7
110+
#define WS_NON_CHILD_NEIGHBOUR_COUNT (WS_RPL_CANDIDATE_PARENT_COUNT + WS_TEMPORARY_NEIGHBOUR_ENTRIES)
111+
102112
#endif /* WS_CONFIG_H_ */

source/RPL/rpl_control.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,17 @@ void rpl_control_address_register_done(struct buffer *buf, uint8_t status)
227227
}
228228
}
229229

230+
bool rpl_control_is_dodag_parent(protocol_interface_info_entry_t *interface, const uint8_t ll_addr[16])
231+
{
232+
// go through instances and parents and check if they match the address.
233+
ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
234+
if (rpl_instance_address_is_parent(instance, ll_addr)){
235+
return true;
236+
}
237+
}
238+
return false;
239+
}
240+
230241
/* Address changes need to trigger DAO target re-evaluation */
231242
static void rpl_control_addr_notifier(struct protocol_interface_info_entry *interface, const if_address_entry_t *addr, if_address_callback_t reason)
232243
{

source/RPL/rpl_control.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[1
148148
void rpl_control_unpublish_address(rpl_domain_t *domain, const uint8_t addr[16]);
149149
void rpl_control_register_address(struct protocol_interface_info_entry *interface, if_address_entry_t *addr);
150150
void rpl_control_address_register_done(struct buffer *buf, uint8_t status);
151+
bool rpl_control_is_dodag_parent(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16]);
151152

152153
/* Configure and return the routing lookup predicate for a specified RPL instance ID */
153154
ipv6_route_predicate_fn_t *rpl_control_get_route_predicate(rpl_domain_t *domain, uint8_t instance_id, const uint8_t src[16], const uint8_t dst[16]);

source/RPL/rpl_upward.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,20 @@ uint16_t rpl_instance_current_rank(const rpl_instance_t *instance)
15641564
return instance->current_rank;
15651565
}
15661566

1567+
bool rpl_instance_address_is_parent(rpl_instance_t *instance, const uint8_t *ipv6_addr)
1568+
{
1569+
ns_list_foreach(rpl_neighbour_t, neighbour, &instance->candidate_neighbours) {
1570+
if (neighbour->dodag_parent && addr_ipv6_equal(neighbour->ll_address, ipv6_addr)) {
1571+
return true;
1572+
}
1573+
if (!neighbour->dodag_parent) {
1574+
// list is ordered so first encounter of false means no more parents in list
1575+
return false;
1576+
}
1577+
}
1578+
return false;
1579+
}
1580+
15671581
void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds)
15681582
{
15691583
ns_list_foreach(rpl_dodag_t, dodag, &instance->dodags) {

source/RPL/rpl_upward.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void rpl_instance_dio_trigger(rpl_instance_t *instance, struct protocol_interfac
8383
void rpl_instance_set_local_repair(rpl_instance_t *instance, bool repair);
8484
bool rpl_instance_local_repair(const rpl_instance_t *instance);
8585
uint16_t rpl_instance_current_rank(const rpl_instance_t *instance);
86+
bool rpl_instance_address_is_parent(rpl_instance_t *instance, const uint8_t *ipv6_addr);
8687
void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds);
8788

8889
rpl_dodag_t *rpl_lookup_dodag(const rpl_instance_t *instance, const uint8_t *dodagid);

source/ipv6_stack/ipv6_routing_table.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,16 @@ void ipv6_neighbour_delete_registered_by_eui64(ipv6_neighbour_cache_t *cache, co
410410
}
411411
}
412412

413+
bool ipv6_neighbour_has_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64)
414+
{
415+
ns_list_foreach_safe(ipv6_neighbour_t, cur, &cache->list) {
416+
if (cur->type != IP_NEIGHBOUR_GARBAGE_COLLECTIBLE && memcmp(ipv6_neighbour_eui64(cache, cur), eui64, 8) == 0) {
417+
return true;
418+
}
419+
}
420+
return false;
421+
}
422+
413423
void ipv6_neighbour_set_state(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, ip_neighbour_cache_state_t state)
414424
{
415425
if (!ipv6_neighbour_state_is_probably_reachable(entry->state) &&

source/ipv6_stack/ipv6_routing_table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ extern bool ipv6_neighbour_addr_is_probably_reachable(ipv6_neighbour_cache_t *ca
160160
extern bool ipv6_neighbour_ll_addr_match(const ipv6_neighbour_t *entry, addrtype_t ll_type, const uint8_t *ll_address);
161161
extern void ipv6_neighbour_invalidate_ll_addr(ipv6_neighbour_cache_t *cache, addrtype_t ll_type, const uint8_t *ll_address);
162162
extern void ipv6_neighbour_delete_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64);
163+
extern bool ipv6_neighbour_has_registered_by_eui64(ipv6_neighbour_cache_t *cache, const uint8_t *eui64);
163164
extern void ipv6_neighbour_entry_update_unsolicited(ipv6_neighbour_cache_t *cache, ipv6_neighbour_t *entry, addrtype_t type, const uint8_t *ll_address/*, bool tentative*/);
164165
extern ipv6_neighbour_t *ipv6_neighbour_update_unsolicited(ipv6_neighbour_cache_t *cache, const uint8_t *ip_address, addrtype_t ll_type, const uint8_t *ll_address);
165166
extern void ipv6_neighbour_reachability_confirmation(const uint8_t ip_address[__static 16], int8_t interface_id);

test/nanostack/unittest/6LoWPAN/nd_router_object/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ TEST_SRC_FILES = \
2929
../../stub/protocol_core_stub.c \
3030
../../stub/protocol_6lowpan_stub.c \
3131
../../stub/whiteboard_stub.c \
32+
../../stub/ws_common_stub.c \
3233
../../stub/lowpan_context_stub.c \
3334
../../stub/rpl_control_stub.c \
3435
../../stub/rpl_data_stub.c \

test/nanostack/unittest/stub/rpl_upward_stub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,11 @@ uint16_t rpl_instance_current_rank(const rpl_instance_t *instance)
418418
return 0;
419419
}
420420

421+
bool rpl_instance_address_is_parent(rpl_instance_t *instance, const uint8_t *ipv6_addr)
422+
{
423+
return false;
424+
}
425+
421426
void rpl_instance_slow_timer(rpl_instance_t *instance, uint16_t seconds)
422427
{
423428
}

test/nanostack/unittest/stub/ws_common_stub.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,9 @@ void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8
5555
(void) cur;
5656
(void) ll_address;
5757
}
58+
bool ws_common_allow_child_registration(protocol_interface_info_entry_t *interface)
59+
{
60+
(void) interface;
61+
return true;
62+
}
63+

0 commit comments

Comments
 (0)