Skip to content

Commit 3569c8a

Browse files
Mleid bbr fix (ARMmbed#1697)
route source added and route info autofree implemented.
1 parent 1fc81fc commit 3569c8a

File tree

8 files changed

+87
-24
lines changed

8 files changed

+87
-24
lines changed

source/6LoWPAN/Thread/thread_bbr_api.c

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ typedef struct {
9191
ns_list_link_t link;
9292
} thread_bbr_t;
9393

94+
/*
95+
* Thread PBBR ML-EID map structure
96+
*/
97+
typedef struct {
98+
uint8_t mleid_ptr[8];
99+
uint32_t last_contact_time;
100+
} thread_bbr_mleid_map_t;
101+
94102
/* Neighbor discovery options according to RFC6106 (rfc4861) */
95103
#define RFC6106_RECURSIVE_DNS_SERVER_OPTION 25
96104
#define RFC6106_DNS_SEARCH_LIST_OPTION 31
@@ -955,18 +963,18 @@ static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 1
955963
return 0;
956964

957965
}
958-
int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr) {
959-
(void) mleid_ptr;
966+
967+
int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info)
968+
{
960969
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
961970
if (!this || this->backbone_interface_id < 0) {
962-
tr_err("bbr not ready");
963971
return -1;
964972
}
965973
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_HOST, info, 0, lifetime, 0);
966974
// We are using route info field to store sequence number
967975
if (!route) {
968976
// Direct route to host allows ND proxying to work
969-
tr_err("out of resources");
977+
tr_err("bbr out of resources");
970978
return -2;
971979
}
972980
// send NA
@@ -975,14 +983,44 @@ int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr,
975983
return 0;
976984
}
977985

978-
int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) {
979-
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL);
980-
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST ) {
981-
//Not found
986+
int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr)
987+
{
988+
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
989+
if (!this || this->backbone_interface_id < 0) {
982990
return -1;
983991
}
984-
//TODO get information to route to parameters eq mleid, timeout
992+
thread_bbr_mleid_map_t *map = ns_dyn_mem_alloc(sizeof(thread_bbr_mleid_map_t));
993+
if (!map) {
994+
goto error;
995+
}
996+
memcpy(map->mleid_ptr, mleid_ptr, 8);
997+
map->last_contact_time = protocol_core_monotonic_time;
998+
999+
// We are using route info field to store BBR MLEID map
1000+
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_DUA_HOST, map, 0, lifetime, 0);
1001+
if (!route) {
1002+
// Direct route to host allows ND proxying to work
1003+
ns_dyn_mem_free(map);
1004+
goto error;
1005+
}
1006+
// Route info autofreed
1007+
route->info_autofree = true;
1008+
// send NA
1009+
thread_bbr_na_send(this->backbone_interface_id, addr_data_ptr);
1010+
9851011
return 0;
1012+
error:
1013+
tr_err("out of resources");
1014+
return -2;
1015+
}
1016+
1017+
ipv6_route_info_t *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) {
1018+
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL);
1019+
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_DUA_HOST ) {
1020+
//Not found
1021+
return NULL;
1022+
}
1023+
return route->info.info;
9861024
}
9871025

9881026
int thread_bbr_proxy_state_update(int8_t caller_interface_id , int8_t handler_interface_id, bool status)

source/6LoWPAN/Thread/thread_bbr_api_internal.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include "net_interface.h"
3838
#ifdef HAVE_THREAD_ROUTER
39+
3940
/**
4041
* \brief Initialize Thread Commissioner relay for BBR and Routers
4142
*
@@ -98,23 +99,31 @@ void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur)
9899
/**
99100
* \brief Add new nd entry to bbr
100101
*
102+
* \param interface_id addr_data_ptr lifetime info
103+
*/
104+
int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info);
105+
106+
/**
107+
* \brief Add new dua entry to bbr
108+
*
101109
* \param interface_id addr_data_ptr lifetime info mleid_ptr
102110
*/
103-
int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr);
111+
int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr);
104112

105113
/**
106-
* \brief Find if bbr has nd entry
114+
* \brief Find if bbr has dua entry
107115
*
108116
* \param interface_id addr_data_ptr
109117
*/
110-
int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr);
118+
ipv6_route_info_t *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr);
111119

112120
#else
113121
#define thread_bbr_proxy_state_update(caller_interface_id , handler_interface_id, status) (NULL)
114122
#define thread_bbr_routing_enabled(cur) false
115123
#define thread_bbr_network_data_update_notify(cur)
116-
#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info, mleid_ptr) (0)
117-
#define thread_bbr_nd_entry_find(interface_id, addr_data_ptr) (0)
124+
#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info) (0)
125+
#define thread_bbr_dua_entry_add(interface_id, addr_data_ptr, lifetime, mleid_ptr) (0)
126+
#define thread_bbr_dua_entry_find(interface_id, addr_data_ptr) (NULL)
118127
#endif //HAVE_THREAD_BORDER_ROUTER
119128

120129

source/6LoWPAN/Thread/thread_bootstrap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,6 +2242,7 @@ void thread_bootstrap_stop(protocol_interface_info_entry_t *cur)
22422242
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL);
22432243
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL);
22442244
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
2245+
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
22452246
thread_leader_service_leader_data_free(cur->thread_info);
22462247
thread_bootstrap_all_nodes_multicast_unregister(cur);
22472248
thread_data_base_init(cur->thread_info, cur->id);

source/6LoWPAN/Thread/thread_extension_bbr.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ static int thread_pbbr_bb_qry_cb(int8_t service_id, uint8_t source_address[16],
460460
return 0;
461461
}
462462
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, this->interface_id, NULL);
463-
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST ) {
463+
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_DUA_HOST ) {
464464
//address not in mesh
465465
return 0;
466466
}
@@ -493,7 +493,7 @@ static int thread_pbbr_dua_duplicate_address_detection(int8_t service_id, uint8_
493493
}
494494

495495
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, this->interface_id, NULL);
496-
if (!route || route->prefix_len != 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST) {
496+
if (!route || route->prefix_len != 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_DUA_HOST) {
497497
// Not found
498498
tr_debug("route not found");
499499
return 0;
@@ -509,7 +509,7 @@ static int thread_pbbr_dua_duplicate_address_detection(int8_t service_id, uint8_
509509
tr_debug("Remove from neigh Cache: %s", tr_ipv6(tr_ptr->target_eid));
510510
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour_entry);
511511
}
512-
ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_HOST);
512+
ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_DUA_HOST);
513513
}
514514
return 0;
515515

@@ -528,6 +528,8 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16],
528528
uint8_t destination_address[16] = {0};
529529
uint8_t *ml_eid_ptr;
530530
uint32_t last_transaction_time;
531+
uint8_t *network_name_ptr;
532+
uint8_t network_name_len;
531533
tr_info("Thread BBR BB_ANS.ntf receive");
532534
thread_pbbr_t *this = thread_border_router_find_by_service(service_id);
533535

@@ -544,10 +546,10 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16],
544546
// Received from own address no need to process
545547
return 0;
546548
}
547-
548549
addr_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_TARGET_EID, &addr_data_ptr);
549550
ml_eid_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_ML_EID, &ml_eid_ptr);
550551
last_transaction_time_len = thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_LAST_TRANSACTION_TIME, &last_transaction_time);
552+
network_name_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_NETWORK_NAME, &network_name_ptr);
551553

552554
if ( addr_len < 16|| ml_eid_len < 8 || last_transaction_time_len < 4 ) {
553555
tr_err("Invalid message");
@@ -560,6 +562,11 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16],
560562

561563
// If rloc16 is present then a/an is sent to the thread device with the rloc
562564
if (thread_tmfcop_tlv_data_get_uint16(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_RLOC16, &rloc16) != 2) {
565+
// this is Pro active ANS to inform that device has moved in new network
566+
// This message was sent to multicast address
567+
// in spec there is checks for Last transaction time, but we always know that this message has zero and we have lower
568+
// TODO create function to process
569+
// Delete route to DUA as it is moved
563570
return 0;
564571
}
565572

@@ -781,11 +788,10 @@ static int thread_extension_bbr_dua_cb(int8_t service_id, uint8_t source_address
781788

782789
entry_keep_alive = false;
783790
// TODO add ml_eid to structure saved in info pointer to detect duplicates
784-
if (thread_bbr_nd_entry_find(this->interface_id, addr_data_ptr) == 0) {
791+
if (thread_bbr_dua_entry_find(this->interface_id, addr_data_ptr) != NULL) {
785792
entry_keep_alive = true;
786793
}
787-
788-
if (thread_bbr_nd_entry_add(this->interface_id, addr_data_ptr, 0xFFFFFFFF, NULL, ml_eid_ptr) != 0) {
794+
if (thread_bbr_dua_entry_add(this->interface_id, addr_data_ptr, 0xFFFFFFFF, ml_eid_ptr) != 0) {
789795
bbr_status = THREAD_BBR_STATUS_RESOURCE_SHORTAGE;
790796
goto send_response;
791797
}

source/6LoWPAN/Thread/thread_host_bootstrap.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ static void thread_merge_prepare(protocol_interface_info_entry_t *cur)
122122
thread_clean_old_16_bit_address_based_addresses(cur);
123123
mpl_clear_realm_scope_seeds(cur);
124124
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
125+
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
125126
thread_partition_data_purge(cur);
126127
thread_network_data_clean(cur);
127128
cur->nwk_mode = ARM_NWK_GP_IP_MODE;

source/DHCPv6_Server/DHCPv6_Server_service.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,14 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
106106
// coverity[returned_null] for ignoring protocol_stack_interface_info_get_by_id NULL return
107107
DHCPV6_server_service_remove_GUA_from_neighcache(protocol_stack_interface_info_get_by_id(serverBase->interfaceId), nonTemporalAddress.requestedAddress);
108108
}
109-
if (thread_bbr_nd_entry_add(serverBase->interfaceId,dhcp_allocated_address->nonTemporalAddress, nonTemporalAddress.validLifeTime, serverBase->guaPrefix, NULL) == -1) {
109+
if (thread_bbr_nd_entry_add(serverBase->interfaceId,dhcp_allocated_address->nonTemporalAddress, nonTemporalAddress.validLifeTime, serverBase->guaPrefix) == -1) {
110110
// No nanostack BBR present we will put entry for application implemented BBR
111111
ipv6_route_t *route = ipv6_route_add_with_info(dhcp_allocated_address->nonTemporalAddress, 128, serverBase->interfaceId, NULL, ROUTE_THREAD_PROXIED_HOST,serverBase->guaPrefix,0, nonTemporalAddress.validLifeTime, 0);
112112
if (!route) {
113113
address_allocated = false;
114114
libdhcpv6_address_rm_from_allocated_list(serverBase,dhcp_allocated_address->nonTemporalAddress);
115115
}
116116

117-
118117
}
119118
}
120119

source/ipv6_stack/ipv6_routing_table.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,10 @@ static const char *route_src_names[] = {
10881088
[ROUTE_MPL] = "MPL",
10891089
[ROUTE_RIP] = "RIP",
10901090
[ROUTE_THREAD] = "Thread",
1091-
[ROUTE_THREAD_BORDER_ROUTER] = "Thread BR",
1091+
[ROUTE_THREAD_BORDER_ROUTER] = "Thread Network data",
10921092
[ROUTE_THREAD_PROXIED_HOST] = "Thread Proxy",
1093+
[ROUTE_THREAD_BBR] = "Thread BBR",
1094+
[ROUTE_THREAD_PROXIED_DUA_HOST] = "Thread DUA Proxy",
10931095
[ROUTE_REDIRECT] = "Redirect",
10941096
};
10951097

@@ -1199,6 +1201,9 @@ static void ipv6_route_entry_remove(ipv6_route_t *route)
11991201
#ifdef FEA_TRACE_SUPPORT
12001202
ipv6_route_print(route, trace_debug_print);
12011203
#endif
1204+
if (route->info_autofree) {
1205+
ns_dyn_mem_free(route->info.info);
1206+
}
12021207
if (protocol_core_buffers_in_event_queue > 0) {
12031208
// Alert any buffers in the queue already routed by this source
12041209
ipv6_route_source_invalidated[route->info.source] = true;
@@ -1548,6 +1553,7 @@ ipv6_route_t *ipv6_route_add_metric(const uint8_t *prefix, uint8_t prefix_len, i
15481553
route->lifetime = lifetime;
15491554
route->metric = metric;
15501555
route->info.source = source;
1556+
route->info_autofree = false;
15511557
route->info.info = info;
15521558
route->info.source_id = source_id;
15531559
route->info.interface_id = interface_id;

source/ipv6_stack/ipv6_routing_table.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ typedef enum ipv6_route_src {
8282
ROUTE_THREAD,
8383
ROUTE_THREAD_BORDER_ROUTER,
8484
ROUTE_THREAD_PROXIED_HOST,
85+
ROUTE_THREAD_PROXIED_DUA_HOST,
8586
ROUTE_THREAD_BBR,
8687
ROUTE_REDIRECT, /* Only occurs in destination cache */
8788
ROUTE_MAX,
@@ -215,13 +216,15 @@ void ipv6_destination_cache_timer(uint8_t ticks);
215216
#ifdef HAVE_IPV6_ND
216217
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);
217218
#endif
219+
218220
/* Combined Routing Table (RFC 4191) and Prefix List (RFC 4861) */
219221
/* On-link prefixes have the on_link flag set and next_hop is unset */
220222
typedef struct ipv6_route {
221223
uint8_t prefix_len;
222224
bool on_link: 1;
223225
bool search_skip: 1;
224226
bool probe: 1;
227+
bool info_autofree:1;
225228
uint8_t metric; // 0x40 = RFC 4191 pref high, 0x80 = default, 0xC0 = RFC 4191 pref low
226229
ipv6_route_info_t info;
227230
uint32_t lifetime; // (seconds); 0xFFFFFFFF means permanent

0 commit comments

Comments
 (0)