From 902fdd883ae206e779a7afd3faf0f8d4bef727dc Mon Sep 17 00:00:00 2001 From: Mika Tervonen Date: Mon, 25 Mar 2019 14:37:51 +0200 Subject: [PATCH] create multicast forward check for PBBR --- source/6LoWPAN/Thread/thread_bbr_api.c | 41 ++++++++++++++++++-- source/6LoWPAN/Thread/thread_extension_bbr.c | 22 +++++++++++ source/6LoWPAN/Thread/thread_extension_bbr.h | 2 + 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_bbr_api.c b/source/6LoWPAN/Thread/thread_bbr_api.c index a41bc1ad298c..88ec7898c883 100644 --- a/source/6LoWPAN/Thread/thread_bbr_api.c +++ b/source/6LoWPAN/Thread/thread_bbr_api.c @@ -517,6 +517,34 @@ static int thread_border_relay_to_leader_cb(int8_t service_id, uint8_t source_ad } #ifdef HAVE_THREAD_BORDER_ROUTER +static bool thread_bbr_default_route_exists(struct protocol_interface_info_entry *cur, uint8_t prefix_ptr[8]) +{ + uint16_t rloc16 = mac_helper_mac16_address_get(cur); + ns_list_foreach(thread_network_data_prefix_cache_entry_t, prefix, &cur->thread_info->networkDataStorage.localPrefixList) { + + if (prefix_ptr && + (prefix->servicesPrefixLen != 64 || + memcmp(prefix_ptr, prefix->servicesPrefix, 8) != 0)) { + // Only matching prefixes are counted + continue; + } + + ns_list_foreach(thread_network_server_data_entry_t, br, &prefix->borderRouterList) { + if (br->routerID == 0xfffe) { + continue; + } + if (!br->P_default_route) { + continue; + } + if (rloc16 != br->routerID) { + // different default route exists + return true; + } + } + } + return false; +} + static bool thread_bbr_i_host_prefix(struct protocol_interface_info_entry *cur, uint8_t prefix_ptr[8], uint8_t *br_count, bool *i_am_lowest) { bool i_host_this_prefix = false; @@ -600,14 +628,15 @@ static void thread_bbr_network_data_send(thread_bbr_t *this, uint8_t prefix[8], this->br_info_published = true; } -static void thread_bbr_routing_enable(thread_bbr_t *this) +static void thread_bbr_routing_enable(thread_bbr_t *this, bool multicast_routing_enabled) { if (this->routing_enabled) { return; } tr_info("br: enable routing"); // Start multicast proxying - multicast_fwd_set_forwarding(this->interface_id, true); + // We do not enable multicast forwarding as there is other default router present in network + multicast_fwd_set_forwarding(this->interface_id, multicast_routing_enabled); this->routing_enabled = true; } @@ -663,7 +692,13 @@ static void thread_bbr_status_check(thread_bbr_t *this, uint32_t seconds) // Check from network data are we currently BR or not and change routing state if (this->br_hosted) { - thread_bbr_routing_enable(this); + + //If there is a default router present in any prefix other than us we do not forward multicast + //This prevents multicasts to different interfaces where Thread Mesh is forwarder + bool forward_multicast = !thread_bbr_default_route_exists(cur, NULL); + thread_extension_bbr_mcast_fwd_check(cur->id, &forward_multicast); + + thread_bbr_routing_enable(this, forward_multicast); } else { thread_bbr_routing_disable(this); } diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index 2be3c2ea89d7..6433d001822b 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -1526,4 +1526,26 @@ void thread_extension_bbr_status_override_set(uint8_t dua_status, uint8_t dua_co ba_response_status_count = ba_failure_count; } +void thread_extension_bbr_mcast_fwd_check(int8_t interface_id, bool *multicast_fwd) +{ + thread_pbbr_t *this = thread_bbr_find_by_interface(interface_id); + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); + + if (!cur || !this || multicast_fwd) { + return; + } + + if (this->pbbr_started) { + //We are Primary BBR so we always forward multicast + *multicast_fwd = true; + return; + } + if (0 == thread_extension_primary_bbr_get(cur, NULL, NULL, NULL, NULL)) { + // We are secondary BBR we newer forward + *multicast_fwd = false; + return; + } + // No modification made +} + #endif //HAVE_THREAD_BORDER_ROUTER && HAVE_THREAD_V2 diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.h b/source/6LoWPAN/Thread/thread_extension_bbr.h index 532cfb9f0230..8289c4456228 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.h +++ b/source/6LoWPAN/Thread/thread_extension_bbr.h @@ -60,6 +60,7 @@ void thread_extension_bbr_old_partition_data_clean(int8_t interface_id); void thread_extension_bbr_status_override_get(uint8_t *dua_status, uint8_t *dua_count, uint8_t *ba_failure_count); void thread_extension_bbr_status_override_set(uint8_t dua_status, uint8_t dua_count, uint8_t ba_failure_count); void thread_extension_status_override_count_set(uint8_t value); +void thread_extension_bbr_mcast_fwd_check(int8_t interface_id, bool *multicast_fwd); #else @@ -77,6 +78,7 @@ void thread_extension_status_override_count_set(uint8_t value); #define thread_extension_bbr_status_override_get(dua_status, dua_count, ba_failure_count); #define thread_extension_bbr_status_override_set(dua_status, dua_count, ba_failure_count); #define thread_extension_status_override_count_set(value) +#define thread_extension_bbr_mcast_fwd_check(interface_id, multicast_fwd) #endif #ifdef __cplusplus