Skip to content

Commit a91a2b4

Browse files
author
Arto Kinnunen
authored
Thread discovery response update (#2024)
Thread discovery response update Do not reply to discovery request if CCM is disabled or domain certificate is missing.
1 parent 4ac7842 commit a91a2b4

File tree

4 files changed

+89
-46
lines changed

4 files changed

+89
-46
lines changed

source/6LoWPAN/Thread/thread_extension.c

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
* POSSIBILITY OF SUCH DAMAGE.
2828
*/
2929

30-
3130
#include "nsconfig.h"
3231
#include <ns_types.h>
3332
#include <string.h>
@@ -68,7 +67,10 @@
6867

6968
#define TRACE_GROUP "comm"
7069

71-
#define SECURITY_POLICY_CCM_DISABLED 0x04 /* Thread Commercial Commissioning Mode is enabled when this bit is set. This is Thread 1.2 feature. */
70+
/* See thread_management_if.h for reserved Thread 1.1 bits */
71+
#define SECURITY_POLICY_CCM_DISABLED 0x04 /* M-bit, Commercial Commissioning Mode is disabled when this bit is set. This is Thread 1.2 feature. */
72+
#define SECURITY_POLICY_AUTONOMOUS_ENROLLMENT_DISABLED 0x02 /* A-bit, Autonomous enrollement disabled when this bit is set */
73+
#define SECURITY_POLICY_NMKP_DISABLED 0x01 /* P-bit, NMKP is disabled when bit is set */
7274

7375
typedef struct thread_extension_info {
7476
int8_t coap_service_id;
@@ -976,75 +978,100 @@ static void thread_extension_relay_socket_cb(void *cb_res)
976978
ns_dyn_mem_free(data_ptr);
977979
}
978980

979-
static void thread_extension_joiner_router_deinit(protocol_interface_info_entry_t *cur)
981+
static void thread_extension_joiner_router_ae_deinit(protocol_interface_info_entry_t *cur)
980982
{
983+
if (cur->thread_info->extension_info->relay_port_ae > 0) {
984+
tr_debug("deinit AE");
985+
coap_service_unregister_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_TRI_TX_NTF);
986+
socket_close(cur->thread_info->extension_info->listen_socket_ae);
987+
cur->thread_info->extension_info->listen_socket_ae = -1;
988+
cur->thread_info->extension_info->relay_port_ae = 0;
989+
}
990+
}
981991

982-
tr_debug("deinit joiner router");
983-
coap_service_unregister_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_TRI_TX_NTF);
984-
coap_service_unregister_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_NMK_TX_NTF);
985-
986-
socket_close(cur->thread_info->extension_info->listen_socket_ae);
987-
socket_close(cur->thread_info->extension_info->listen_socket_nmkp);
988-
cur->thread_info->extension_info->listen_socket_ae = -1;
989-
cur->thread_info->extension_info->listen_socket_nmkp = -1;
990-
cur->thread_info->extension_info->relay_port_ae = 0;
991-
cur->thread_info->extension_info->relay_port_nmkp = 0;
992-
return;
992+
static void thread_extension_joiner_router_nmkp_deinit(protocol_interface_info_entry_t *cur)
993+
{
994+
if (cur->thread_info->extension_info->relay_port_nmkp > 0) {
995+
tr_debug("deinit NMKP");
996+
coap_service_unregister_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_NMK_TX_NTF);
997+
socket_close(cur->thread_info->extension_info->listen_socket_nmkp);
998+
cur->thread_info->extension_info->listen_socket_nmkp = -1;
999+
cur->thread_info->extension_info->relay_port_nmkp = 0;
1000+
}
9931001
}
9941002

9951003
static int thread_extension_joiner_router_init(protocol_interface_info_entry_t *cur)
9961004
{
1005+
9971006
int8_t securityLinkLayer = 0;
9981007

999-
if (!cur->thread_info->extension_info) {
1008+
if (!cur->thread_info->extension_info || thread_info(cur)->version < THREAD_VERSION_1_2) {
10001009
return -1;
10011010
}
10021011

10031012
if (0 != thread_extension_primary_bbr_get(cur, NULL, NULL, NULL, NULL)) {
1004-
if (cur->thread_info->extension_info->relay_port_ae ||
1005-
cur->thread_info->extension_info->relay_port_nmkp) {
1006-
// Need to disable Joiner router either because port changed or moving to disabled
1007-
tr_info("Commercial Joiner router Disable joining");
1008-
thread_extension_joiner_router_deinit(cur);
1009-
}
1013+
// Need to disable Joiner router either because port changed or moving to disabled
1014+
thread_extension_joiner_router_ae_deinit(cur);
1015+
thread_extension_joiner_router_nmkp_deinit(cur);
10101016
// Joiner router should be disabled
10111017
return 0;
10121018
}
1013-
// Primary border router is present Enable relays to AE and NMKP
1014-
if (cur->thread_info->extension_info->relay_port_ae ||
1015-
cur->thread_info->extension_info->relay_port_nmkp) {
1016-
// Setup is OK
1019+
1020+
// Is this a CCM network?
1021+
uint16_t securityPolicy = thread_joiner_application_security_policy_get(cur->id);
1022+
if (securityPolicy & SECURITY_POLICY_CCM_DISABLED) {
1023+
// Not a CCM network, de-initialize
1024+
thread_extension_joiner_router_ae_deinit(cur);
1025+
thread_extension_joiner_router_nmkp_deinit(cur);
10171026
return 0;
1027+
}
10181028

1029+
if (thread_extension_bootstrap_network_certificate_available(cur) == false) {
1030+
// No domain certificate available
1031+
return 0;
10191032
}
10201033

1021-
if (cur->thread_info->extension_info->listen_socket_ae < 0) {
1022-
// Start AE relay
1023-
cur->thread_info->extension_info->relay_port_ae = THREAD_DEFAULT_AE_PORT;
1024-
cur->thread_info->extension_info->listen_socket_ae = socket_open(SOCKET_UDP, cur->thread_info->extension_info->relay_port_ae, thread_extension_relay_socket_cb);
1025-
socket_setsockopt(cur->thread_info->extension_info->listen_socket_ae, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
1034+
if (!(securityPolicy & SECURITY_POLICY_AUTONOMOUS_ENROLLMENT_DISABLED)) {
10261035
if (cur->thread_info->extension_info->listen_socket_ae < 0) {
1027-
tr_warn("Commercial Joiner router ae failed");
1028-
cur->thread_info->extension_info->relay_port_ae = 0;
1036+
// Start AE relay
1037+
cur->thread_info->extension_info->listen_socket_ae = socket_open(SOCKET_UDP, THREAD_DEFAULT_AE_PORT, thread_extension_relay_socket_cb);
1038+
if (cur->thread_info->extension_info->listen_socket_ae >= 0) {
1039+
cur->thread_info->extension_info->relay_port_ae = THREAD_DEFAULT_AE_PORT;
1040+
socket_setsockopt(cur->thread_info->extension_info->listen_socket_ae, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
1041+
// The regular TX is usable from joiner router, because it is stateless, but it neds to be forced on
1042+
coap_service_register_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_TRI_TX_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_relay_tx_cb);
1043+
} else {
1044+
tr_warn("Joiner AE failed");
1045+
cur->thread_info->extension_info->relay_port_ae = 0;
1046+
}
10291047
}
1048+
} else {
1049+
thread_extension_joiner_router_ae_deinit(cur);
10301050
}
1031-
if (cur->thread_info->extension_info->listen_socket_nmkp < 0) {
1032-
// Start nmkp relay
1033-
cur->thread_info->extension_info->relay_port_nmkp = THREAD_DEFAULT_NMKP_PORT;
1034-
cur->thread_info->extension_info->listen_socket_nmkp = socket_open(SOCKET_UDP, cur->thread_info->extension_info->relay_port_nmkp, thread_extension_relay_socket_cb);
1035-
socket_setsockopt(cur->thread_info->extension_info->listen_socket_nmkp, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
1051+
1052+
if (!(securityPolicy & SECURITY_POLICY_NMKP_DISABLED)) {
10361053
if (cur->thread_info->extension_info->listen_socket_nmkp < 0) {
1037-
tr_warn("Commercial Joiner router nmkp failed");
1038-
cur->thread_info->extension_info->relay_port_nmkp = 0;
1054+
// Start nmkp relay
1055+
cur->thread_info->extension_info->listen_socket_nmkp = socket_open(SOCKET_UDP, THREAD_DEFAULT_NMKP_PORT, thread_extension_relay_socket_cb);
1056+
if (cur->thread_info->extension_info->listen_socket_nmkp >= 0) {
1057+
cur->thread_info->extension_info->relay_port_nmkp = THREAD_DEFAULT_NMKP_PORT;
1058+
socket_setsockopt(cur->thread_info->extension_info->listen_socket_nmkp, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &securityLinkLayer, sizeof(int8_t));
1059+
// The regular TX is usable from joiner router, because it is stateless, but it neds to be forced on
1060+
coap_service_register_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_NMK_TX_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_relay_tx_cb);
1061+
} else {
1062+
tr_warn("Joiner NMKP failed");
1063+
cur->thread_info->extension_info->relay_port_nmkp = 0;
1064+
}
10391065
}
1066+
} else {
1067+
thread_extension_joiner_router_nmkp_deinit(cur);
10401068
}
1069+
10411070
tr_info("init commercial joiner router ae:%d nmkp:%d", cur->thread_info->extension_info->relay_port_ae, cur->thread_info->extension_info->relay_port_nmkp);
10421071

1043-
// The regular TX is usable from joiner router, because it is stateless, but it neds to be forced on
1044-
coap_service_register_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_TRI_TX_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_relay_tx_cb);
1045-
coap_service_register_uri(cur->thread_info->extension_info->coap_service_id, THREAD_URI_BBR_NMK_TX_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_relay_tx_cb);
10461072
return 0;
10471073
}
1074+
10481075
bool thread_extension_joining_enabled(int8_t interface_id)
10491076
{
10501077
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
@@ -1120,7 +1147,7 @@ uint8_t thread_extension_discover_response_len(protocol_interface_info_entry_t *
11201147
length += 4;
11211148
}
11221149
/* Thread 1.2 CCM add-ons */
1123-
if (cur->thread_info->version == THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
1150+
if (cur->thread_info->version >= THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
11241151
// Calculate also following optional TLV's:
11251152
// Thread domain name TLV
11261153
domain_name_len = thread_extension_bootstrap_thread_name_length_get(cur);
@@ -1146,7 +1173,7 @@ uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_
11461173
ptr = thread_meshcop_tlv_data_write_uint16(ptr, MESHCOP_TLV_NMKP_PORT, cur->thread_info->extension_info->relay_port_nmkp);
11471174
}
11481175
/* Thread 1.2 CCM add-ons */
1149-
if (cur->thread_info->version == THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
1176+
if (cur->thread_info->version >= THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
11501177
// Thread domain name TLV
11511178
if (thread_extension_bootstrap_thread_name_length_get(cur)) {
11521179
ptr = thread_meshcop_tlv_data_write(ptr, MESHCOP_TLV_DOMAIN_NAME, thread_extension_bootstrap_thread_name_length_get(cur), thread_extension_bootstrap_thread_name_ptr_get(cur));

source/6LoWPAN/Thread/thread_extension_bootstrap.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,14 @@ int thread_extension_bootstrap_device_certificate_set(protocol_interface_info_en
564564
return 0;
565565
}
566566

567+
bool thread_extension_bootstrap_network_certificate_available(protocol_interface_info_entry_t *cur)
568+
{
569+
if (!thread_info(cur)->extension_credentials_ptr || !thread_info(cur)->extension_credentials_ptr->domain_certificate_ptr) {
570+
return false;
571+
}
572+
573+
return true;
574+
}
567575

568576
int thread_extension_bootstrap_network_certificate_set(protocol_interface_info_entry_t *cur, const unsigned char *domain_certificate_ptr, uint16_t domain_certificate_len)
569577
{
@@ -640,7 +648,7 @@ int thread_extension_bootstrap_commission_start(protocol_interface_info_entry_t
640648
{
641649
discovery_additional_info_t *discovery_add_info = (discovery_additional_info_t *)nwk_info->reserved_opaque;
642650

643-
if (thread_info(cur)->version == THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
651+
if (thread_info(cur)->version >= THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
644652
if (thread_info(cur)->extension_credentials_ptr->domain_certificate_ptr && discovery_add_info->nmk_port) {
645653
return thread_joiner_application_nmkp_commission_start(cur->id, parent_address, discovery_add_info->nmk_port, done_cb);
646654
} else if (thread_info(cur)->extension_credentials_ptr->device_certificate_ptr && discovery_add_info->ae_port) {
@@ -658,7 +666,7 @@ discovery_response_list_t *thread_extension_bootstrap_network_select(protocol_in
658666
{
659667
discovery_response_list_t *discovered_network_ptr = NULL;
660668

661-
if (thread_info(cur)->version == THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
669+
if (thread_info(cur)->version >= THREAD_VERSION_1_2 && thread_info(cur)->extension_credentials_ptr) {
662670
/* If we have domain certificate, search for domain to join */
663671
if (thread_info(cur)->extension_credentials_ptr->domain_certificate_ptr) {
664672
ns_list_foreach_safe(discovery_response_list_t, cur_class, discover_response) {

source/6LoWPAN/Thread/thread_extension_bootstrap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ int thread_extension_bootstrap_network_certificate_set(protocol_interface_info_e
4444

4545
int thread_extension_bootstrap_network_private_key_set(protocol_interface_info_entry_t *cur, const unsigned char *priv_key_ptr, uint16_t priv_key_len);
4646

47+
bool thread_extension_bootstrap_network_certificate_available(protocol_interface_info_entry_t *cur);
48+
4749
int thread_extension_bootstrap_thread_name_set(protocol_interface_info_entry_t *cur, char thread_name[16]);
4850

4951
int thread_extension_bootstrap_commission_start(protocol_interface_info_entry_t *cur, uint8_t parent_address[16], discovery_response_list_t *nwk_info, thread_joiner_application_commission_done_cb *done_cb);
@@ -62,6 +64,7 @@ int thread_extension_bootstrap_reenrollment_start(protocol_interface_info_entry_
6264
#define thread_extension_bootstrap_free(cur);
6365
#define thread_extension_bootstrap_device_certificate_set(cur, device_certificate_ptr, device_certificate_len, priv_key_ptr, priv_key_len) (-1)
6466
#define thread_extension_bootstrap_network_certificate_set(cur, domain_certificate_ptr, domain_certificate_len) (-1)
67+
#define thread_extension_bootstrap_network_certificate_available(cur) (false)
6568
#define thread_extension_bootstrap_network_private_key_set(cur, priv_key_ptr, priv_key_len) (-1)
6669
#define thread_extension_bootstrap_thread_name_set(cur, thread_name) (-1)
6770
#define thread_extension_bootstrap_commission_start(cur, parent_address, port, done_cb) (-1)

test/nanostack/unittest/stub/thread_extension_bootstrap_stub.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ int thread_extension_bootstrap_network_private_key_set(protocol_interface_info_e
6363
return 0;
6464
}
6565

66+
bool thread_extension_bootstrap_network_certificate_available(protocol_interface_info_entry_t *cur)
67+
{
68+
return false;
69+
}
70+
6671
int thread_extension_bootstrap_thread_name_set(protocol_interface_info_entry_t *cur, char thread_name[16])
6772
{
6873
return 0;

0 commit comments

Comments
 (0)