Skip to content

Commit

Permalink
Destination cache update:
Browse files Browse the repository at this point in the history
Fixed possible memory leak if cache reference count is updated in future.

Added API for clean Destination cache by given interface Id.

Updated Destination cache print also interface id.
  • Loading branch information
Juha Heiskanen committed Mar 1, 2021
1 parent f92c385 commit 71b0588
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
32 changes: 23 additions & 9 deletions source/ipv6_stack/ipv6_routing_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static NS_LIST_DEFINE(ipv6_routing_table, ipv6_route_t, link);
static ipv6_destination_t *ipv6_destination_lookup(const uint8_t *address, int8_t interface_id);
static void ipv6_destination_cache_forget_router(ipv6_neighbour_cache_t *cache, const uint8_t neighbour_addr[16]);
static void ipv6_destination_cache_forget_neighbour(const ipv6_neighbour_t *neighbour);
static void ipv6_destination_release(ipv6_destination_t *dest);
static bool ipv6_destination_release(ipv6_destination_t *dest);
static void ipv6_route_table_remove_router(int8_t interface_id, const uint8_t *addr, ipv6_route_src_t source);
static uint16_t total_metric(const ipv6_route_t *route);
static uint8_t ipv6_route_table_count_source(int8_t interface_id, ipv6_route_src_t source);
Expand Down Expand Up @@ -863,7 +863,7 @@ void ipv6_destination_cache_print(route_print_fn_t *print_fn)
print_fn("Destination Cache:");
ns_list_foreach(ipv6_destination_t, entry, &ipv6_destination_cache) {
ROUTE_PRINT_ADDR_STR_BUFFER_INIT(addr_str);
print_fn(" %s (life %u)", ROUTE_PRINT_ADDR_STR_FORMAT(addr_str, entry->destination), entry->lifetime);
print_fn(" %s (%d id) (life %u)", ROUTE_PRINT_ADDR_STR_FORMAT(addr_str, entry->destination), entry->interface_id, entry->lifetime);
#ifdef HAVE_IPV6_ND
if (entry->redirected) {
print_fn(" Redirect %s%%%u", ROUTE_PRINT_ADDR_STR_FORMAT(addr_str, entry->redirect_addr), entry->interface_id);
Expand Down Expand Up @@ -939,7 +939,6 @@ ipv6_destination_t *ipv6_destination_lookup_or_create(const uint8_t *address, in
if (!entry) {
if (count > destination_cache_config.max_entries) {
entry = ns_list_get_last(&ipv6_destination_cache);
ns_list_remove(&ipv6_destination_cache, entry);
ipv6_destination_release(entry);
}

Expand Down Expand Up @@ -1082,18 +1081,31 @@ void ipv6_destination_cache_forced_gc(bool full_gc)
**/
ns_list_foreach_reverse_safe(ipv6_destination_t, entry, &ipv6_destination_cache) {
if (entry->lifetime == 0 || gc_count > destination_cache_config.long_term_entries || full_gc) {
ns_list_remove(&ipv6_destination_cache, entry);
if (ipv6_destination_release(entry)) {
gc_count--;
}
}
}
}

void ipv6_destination_cache_clean(int8_t interface_id)
{
ns_list_foreach_reverse_safe(ipv6_destination_t, entry, &ipv6_destination_cache) {
if (entry->interface_id == interface_id) {
ipv6_destination_release(entry);
gc_count--;
}
}
}

static void ipv6_destination_release(ipv6_destination_t *dest)
static bool ipv6_destination_release(ipv6_destination_t *dest)
{
if (--dest->refcount == 0) {
ns_list_remove(&ipv6_destination_cache, dest);
tr_debug("Destination cache remove: %s", trace_ipv6(dest->destination));
ns_dyn_mem_free(dest);
return true;
}
return false;
}

static void ipv6_destination_cache_gc_periodic(void)
Expand Down Expand Up @@ -1137,9 +1149,11 @@ static void ipv6_destination_cache_gc_periodic(void)
*/
ns_list_foreach_reverse_safe(ipv6_destination_t, entry, &ipv6_destination_cache) {
if (entry->lifetime == 0 || gc_count > destination_cache_config.short_term_entries) {
ns_list_remove(&ipv6_destination_cache, entry);
ipv6_destination_release(entry);
if (--gc_count <= destination_cache_config.long_term_entries) {
if (ipv6_destination_release(entry)) {
gc_count--;
}

if (gc_count <= destination_cache_config.long_term_entries) {
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions source/ipv6_stack/ipv6_routing_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ void ipv6_destination_cache_timer(uint8_t ticks);
void ipv6_destination_redirect(const uint8_t *dest_addr, const uint8_t *sender_addr, const uint8_t *redirect_addr, int8_t interface_id, addrtype_t ll_type, const uint8_t *ll_address);
#endif
void ipv6_destination_cache_forced_gc(bool full_gc);
void ipv6_destination_cache_clean(int8_t interface_id);

/* Combined Routing Table (RFC 4191) and Prefix List (RFC 4861) */
/* On-link prefixes have the on_link flag set and next_hop is unset */
Expand Down
5 changes: 5 additions & 0 deletions test/nanostack/unittest/stub/ipv6_routing_table_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,8 @@ void ipv6_route_table_source_invalidated_reset(void)
{

}

void ipv6_destination_cache_clean(int8_t interface_id)
{

}

0 comments on commit 71b0588

Please sign in to comment.