Merge commit '396dae52ab4eef15910011432f2c7a4261fc22b7'

* commit '396dae52ab4eef15910011432f2c7a4261fc22b7':
  Squashed 'features/nanostack/sal-stack-nanostack/' changes from 4a19dc4..c473148
pull/11423/head
Jarkko Paso 2019-09-05 14:28:22 +03:00
commit 4ebbbc592d
37 changed files with 920 additions and 225 deletions

View File

@ -37,7 +37,7 @@ override CFLAGS += -I$(EVENTLOOP_DIR)/nanostack-event-loop
override CFLAGS += -I$(NSDL_DIR)/nsdl-c
override CFLAGS += -I$(COAP_DIR)
override CFLAGS += -I$(COAP_SERVICE_LIB)/coap-service
override CFLAGS += -I$(MBEDTLS_DIR)/include
override CFLAGS += -I$(MBEDTLS_DIR)/include -I$(MBEDTLS_DIR)/crypto/include
override CFLAGS += $(addprefix -I,$(INCLUDE_DIRS))
override CFLAGS += $(addprefix -D,$(FLAGS))
@ -153,7 +153,7 @@ mbed-release-build-$(1): $(1)-$(2)-$(3)-build
.PHONY: $(1)-$(2)-build
$(1)-$(2)-$(3)-build: export-headers
@echo Build $(2) on $(1) for $(3)
make CC=$(CC_$(1)) CONFIG=$(2) CPU=$(3) APPEND_LIB_NAME=1 CFLAGS="-DNS_USE_EXTERNAL_MBED_TLS -I../mbedtls/include/"
make CC=$(CC_$(1)) CONFIG=$(2) CPU=$(3) APPEND_LIB_NAME=1 CFLAGS="-DNS_USE_EXTERNAL_MBED_TLS -I../mbedtls/include/ -I../crypto/include/"
# Generate target directory name
# Like: FEATURE_NANOSTACK/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M0P

View File

@ -120,4 +120,24 @@ int ws_bbr_node_keys_remove(int8_t interface_id, uint8_t *eui64);
*/
int ws_bbr_node_access_revoke_start(int8_t interface_id);
/**
* Set EAPOL node limit
*
* Border router stores EAPOL key information for each authenticated node.
* Sets the maximum number of EAPOL nodes stored by border router. If count
* of node's exceed the limit, border router deletes the node information
* starting from oldest node (node that has authenticated longest time
* ago), to make room for new nodes. When network keys are updated, nodes
* which have been removed from storage, must make full authentication again.
* Value for this parameter should be set to be more than maximum amount of
* nodes that are expected to be connected to border router.
*
* \param interface_id Network interface ID.
* \param limit Limit for nodes
*
* \return 0, Node limit set
* \return <0 Node limit set failed.
*/
int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit);
#endif /* WS_BBR_API_H_ */

View File

@ -1787,7 +1787,7 @@ bootstrap_finish_check:
*/
if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
//rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true);
//rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, cur);
//rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, NULL, cur);
}
#endif
cur->configure_flags |= INTERFACE_BOOTSTRAP_DEFINED;
@ -2182,7 +2182,7 @@ void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t *
// arm_nwk_6lowpan_rpl_dodag_poison from a previous connection may have left force_leaf set
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, false);
rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, true);
rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, cur);
rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, NULL, cur);
}
// Send unicast DIS to coordinator
nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(cur);

View File

@ -609,7 +609,6 @@ int ws_bbr_node_keys_remove(int8_t interface_id, uint8_t *eui64)
{
(void) interface_id;
(void) eui64;
#ifdef HAVE_WS_BORDER_ROUTER
return ws_pae_controller_node_keys_remove(interface_id, eui64);
#else
@ -620,7 +619,6 @@ int ws_bbr_node_keys_remove(int8_t interface_id, uint8_t *eui64)
int ws_bbr_node_access_revoke_start(int8_t interface_id)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER
return ws_pae_controller_node_access_revoke_start(interface_id);
#else
@ -628,3 +626,13 @@ int ws_bbr_node_access_revoke_start(int8_t interface_id)
#endif
}
int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit)
{
(void) interface_id;
#ifdef HAVE_WS_BORDER_ROUTER
return ws_pae_controller_node_limit_set(interface_id, limit);
#else
(void) limit;
return -1;
#endif
}

View File

@ -81,7 +81,7 @@ static void ws_bootstrap_state_change(protocol_interface_info_entry_t *cur, icmp
static bool ws_bootstrap_state_discovery(struct protocol_interface_info_entry *cur);
static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t interface_id, arm_library_event_priority_e priority, void *event_data);
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, bool multicast);
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);
static uint16_t ws_bootstrap_routing_cost_calculate(protocol_interface_info_entry_t *cur);
static uint16_t ws_bootstrap_rank_get(protocol_interface_info_entry_t *cur);
static uint16_t ws_bootstrap_min_rank_inc_get(protocol_interface_info_entry_t *cur);
@ -97,6 +97,7 @@ static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *
static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry_t *cur, void *neighbor);
static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr);
static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
static bool ws_rpl_dio_new_parent_accept(struct protocol_interface_info_entry *interface);
typedef enum {
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
@ -104,6 +105,7 @@ typedef enum {
WS_EAPOL_PARENT_SYNCH, /**< Broadcast synch with EAPOL parent*/
} ws_parent_synch_e;
static void ws_bootsrap_create_ll_address(uint8_t *ll_address, const uint8_t *mac64)
{
memcpy(ll_address, ADDR_LINK_LOCAL_PREFIX, 8);
@ -925,7 +927,7 @@ static void ws_bootstrap_pan_advertisement_analyse(struct protocol_interface_inf
// Save route cost for all neighbours
llc_neighbour_req_t neighbor_info;
neighbor_info.neighbor = NULL;
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false, false)) {
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) {
neighbor_info.ws_neighbor->routing_cost = pan_information.routing_cost;
}
@ -1080,10 +1082,10 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
if (cur->ws_info->configuration_learned || cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
//If we are border router or learned configuration we only update already learned neighbours.
neighbour_pointer_valid = ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false, true);
neighbour_pointer_valid = ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false);
} else {
neighbour_pointer_valid = ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, true, true);
neighbour_pointer_valid = ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, true);
if (!neighbour_pointer_valid) {
return;
}
@ -1169,7 +1171,7 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in
*/
llc_neighbour_req_t neighbor_info;
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false, false)) {
if (ws_bootstrap_neighbor_info_request(cur, data->SrcAddr, &neighbor_info, false)) {
etx_lqi_dbm_update(cur->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index);
ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, ws_utt, data->timestamp);
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us);
@ -1366,19 +1368,10 @@ static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_ent
}
}
uint32_t link_min_timeout;
//Read current timestamp
uint32_t time_from_last_unicast_shedule = ws_time_from_last_unicast_traffic(current_time_stamp, ws_neighbor);
if (cur->trusted_device) {
link_min_timeout = WS_NEIGHBOR_TRUSTED_LINK_MIN_TIMEOUT;
} else {
link_min_timeout = WS_NEIGHBOR_NOT_TRUSTED_LINK_MIN_TIMEOUT;
}
if (time_from_last_unicast_shedule > link_min_timeout || !ws_neighbor->unicast_data_rx) {
if (time_from_last_unicast_shedule > WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT || !ws_neighbor->unicast_data_rx) {
//Accept only Enough Old Device
if (!neighbor_entry_ptr) {
//Accept first compare
@ -1399,8 +1392,9 @@ static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_ent
}
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, bool multicast)
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)
{
neighbor_buffer->ws_neighbor = NULL;
neighbor_buffer->neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(interface), mac_64, ADDR_802_15_4_LONG);
if (neighbor_buffer->neighbor) {
neighbor_buffer->ws_neighbor = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, neighbor_buffer->neighbor->index);
@ -1421,27 +1415,6 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
return false;
}
if (multicast) {
//for multicast neighbour we must limit if we have already enough information
if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
//Border router never allocate neighbors by multicast
return false;
}
uint16_t parent_candidate_size = rpl_control_parent_candidate_list_size(interface, false);
//if we have enough candidates at list do not accept new multicast neighbours
if (parent_candidate_size >= 4) {
return false;
}
parent_candidate_size = rpl_control_parent_candidate_list_size(interface, true);
//If we have already enough parent selected Candidates count is bigger tahn 4
if (parent_candidate_size >= 2) {
return false;
}
}
ws_bootstrap_neighbor_table_clean(interface);
neighbor_buffer->neighbor = ws_bootstrap_mac_neighbor_add(interface, mac_64);
@ -1458,6 +1431,24 @@ static bool ws_bootstrap_neighbor_info_request(struct protocol_interface_info_en
return true;
}
static bool ws_rpl_dio_new_parent_accept(struct protocol_interface_info_entry *interface)
{
uint16_t parent_candidate_size = rpl_control_parent_candidate_list_size(interface, false);
//TODO check bootstarap state for review
//if we have enough candidates at list do not accept new multicast neighbours
if (parent_candidate_size > WS_NEIGHBOUR_MAX_CANDIDATE_PROBE) {
return false;
}
parent_candidate_size = rpl_control_parent_candidate_list_size(interface, true);
//If we have already enough parent selected Candidates count is bigger tahn 4
if (parent_candidate_size >= 2) {
return false;
}
return true;
}
static void ws_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
{
@ -2010,6 +2001,48 @@ static void ws_rpl_prefix_callback(prefix_entry_t *prefix, void *handle, uint8_t
}
}
static bool ws_rpl_new_parent_callback_t(uint8_t *ll_parent_address, void *handle)
{
protocol_interface_info_entry_t *cur = handle;
if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) {
return false;
}
uint8_t mac64[8];
memcpy(mac64, ll_parent_address + 8, 8);
mac64[0] ^= 2;
llc_neighbour_req_t neigh_buffer;
if (ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, false)) {
return true;
}
if (!ws_rpl_dio_new_parent_accept(cur)) {
return false;
}
//Discover Multicast temporary entry
ws_neighbor_temp_class_t *entry = ws_llc_get_multicast_temp_entry(cur, mac64);
if (!entry) {
return false;
}
//Create entry
bool create_ok = ws_bootstrap_neighbor_info_request(cur, mac64, &neigh_buffer, true);
if (create_ok) {
ws_neighbor_class_entry_t *ws_neigh = neigh_buffer.ws_neighbor;
//Copy fhss temporary data
*ws_neigh = entry->neigh_info_list;
//ETX Create here
etx_lqi_dbm_update(cur->id, entry->mpduLinkQuality, entry->signal_dbm, neigh_buffer.neighbor->index);
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(cur), neigh_buffer.neighbor, true);
}
ws_llc_free_multicast_temp_entry(cur, entry);
return create_ok;
}
static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
{
tr_debug("RPL Activate");
@ -2018,7 +2051,7 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
addr_add_router_groups(cur);
rpl_control_set_domain_on_interface(cur, protocol_6lowpan_rpl_domain, downstream);
rpl_control_set_callback(protocol_6lowpan_rpl_domain, ws_bootstrap_rpl_callback, ws_rpl_prefix_callback, cur);
rpl_control_set_callback(protocol_6lowpan_rpl_domain, ws_bootstrap_rpl_callback, ws_rpl_prefix_callback, ws_rpl_new_parent_callback_t, cur);
// If i am router I Do this
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, leaf);
rpl_control_request_parent_link_confirmation(true);
@ -2493,6 +2526,9 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
cur->ws_info->trickle_pas_running = false;
cur->ws_info->trickle_pcs_running = false;
// Indicate PAE controller that bootstrap is ready
ws_pae_controller_bootstrap_done(cur);
ws_bootstrap_advertise_start(cur);
ws_bootstrap_state_change(cur, ER_BOOTSRAP_DONE);
break;
@ -2520,7 +2556,7 @@ void ws_bootstrap_network_scan_process(protocol_interface_info_entry_t *cur)
// Add EAPOL neighbour
llc_neighbour_req_t neighbor_info;
if (!ws_bootstrap_neighbor_info_request(cur, cur->ws_info->parent_info.addr, &neighbor_info, true, false)) {
if (!ws_bootstrap_neighbor_info_request(cur, cur->ws_info->parent_info.addr, &neighbor_info, true)) {
return;
}

View File

@ -27,6 +27,7 @@
#include "6LoWPAN/ws/ws_common.h"
#include "6LoWPAN/ws/ws_bootstrap.h"
#include "6LoWPAN/ws/ws_bbr_api_internal.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "Service_Libs/etx/etx.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "Service_Libs/blacklist/blacklist.h"
@ -327,7 +328,7 @@ void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint
} else {
ws_bbr_rpl_config(0, 0, 0);
}
ws_pae_controller_timing_adjust(1); // Fast and reactive network
} else if (network_size < 300) {
// Configure the Wi-SUN discovery trickle parameters
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_medium;
@ -336,6 +337,7 @@ void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint
// doublings:5 (960s)
// redundancy; 10
ws_bbr_rpl_config(15, 5, 10);
ws_pae_controller_timing_adjust(9); // medium limited network
} else {
// Configure the Wi-SUN discovery trickle parameters
cur->ws_info->trickle_params_pan_discovery = trickle_params_pan_discovery_large;
@ -344,6 +346,7 @@ void ws_common_network_size_configure(protocol_interface_info_entry_t *cur, uint
// doublings:1 (1048s, 17 min)
// redundancy; 10 May need some tuning still
ws_bbr_rpl_config(19, 1, 10);
ws_pae_controller_timing_adjust(24); // Very slow and high latency network
}
return;
}
@ -423,7 +426,7 @@ bool ws_common_negative_aro_mark(protocol_interface_info_entry_t *interface, con
}
ws_neighbor_class_entry_t *ws_neighbor = ws_neighbor_class_entry_get(&interface->ws_info->neighbor_storage, neighbour->index);
ws_neighbor->negative_aro_send = true;
neighbour->lifetime = WS_NEIGHBOR_NOT_TRUSTED_LINK_MIN_TIMEOUT; //Remove anyway if Packet is freed before MAC push
neighbour->lifetime = WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT; //Remove anyway if Packet is freed before MAC push
return true;
}

View File

@ -143,6 +143,5 @@ uint32_t ws_common_version_timeout_get(uint8_t config);
#define ws_common_etx_validate(interface, neigh) ((void) 0)
#define ws_common_negative_aro_mark(interface, eui64)(false)
#endif //HAVE_WS
#endif //WS_COMMON_H_

View File

@ -186,8 +186,7 @@ typedef struct ws_bs_ie {
#define WS_FAN_VERSION_1_0 1
#define WS_NEIGHBOR_LINK_TIMEOUT 2200
#define WS_NEIGHBOR_NOT_TRUSTED_LINK_MIN_TIMEOUT 60
#define WS_NEIGHBOR_TRUSTED_LINK_MIN_TIMEOUT 15
#define WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT 120
#define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2
#define WS_NEIGBOR_ETX_SAMPLE_MAX 3

View File

@ -30,6 +30,7 @@ struct mlme_security_s;
struct ws_hopping_schedule_s;
struct ws_neighbor_class_entry;
struct mac_neighbor_table_entry;
struct ws_neighbor_temp_class_s;
/**
@ -77,6 +78,19 @@ typedef struct llc_neighbour_req {
struct ws_neighbor_class_entry *ws_neighbor; /**< Wi-sun Neighbor information entry. */
} llc_neighbour_req_t;
/**
* Neighbor temporary structure for storage FHSS data before create a real Neighbour info
*/
typedef struct ws_neighbor_temp_class_s {
struct ws_neighbor_class_entry neigh_info_list; /*!< Allocated hopping info array*/
uint8_t mac64[8];
uint8_t mpduLinkQuality;
int8_t signal_dbm;
ns_list_link_t link;
} ws_neighbor_temp_class_t;
typedef NS_LIST_HEAD(ws_neighbor_temp_class_t, link) ws_neighbor_temp_list_t;
/**
* @brief ws_asynch_ind ws asynch data indication
* @param interface Interface pointer
@ -99,12 +113,11 @@ typedef void ws_asynch_confirm(struct protocol_interface_info_entry *interface,
* @param mac_64 Neighbor 64-bit address
* @param neighbor_buffer Buffer where neighbor infor is buffered
* @param request_new true if is possible to allocate new entry
* @param multicast true if packet is multicast
*
* @return true when neighbor info is available
* @return false when no neighbor info
*/
typedef bool ws_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, llc_neighbour_req_t *neighbor_buffer, bool request_new, bool multicast);
typedef bool ws_neighbor_info_request(struct protocol_interface_info_entry *interface, const uint8_t *mac_64, llc_neighbour_req_t *neighbor_buffer, bool request_new);
/**
* @brief ws_llc_create ws LLC module create
@ -204,6 +217,8 @@ void ws_llc_set_pan_information_pointer(struct protocol_interface_info_entry *in
*/
void ws_llc_hopping_schedule_config(struct protocol_interface_info_entry *interface, struct ws_hopping_schedule_s *hopping_schedule);
ws_neighbor_temp_class_t *ws_llc_get_multicast_temp_entry(struct protocol_interface_info_entry *interface, const uint8_t *mac64);
void ws_llc_free_multicast_temp_entry(struct protocol_interface_info_entry *interface, ws_neighbor_temp_class_t *neighbor);
#endif /* WS_LLC_H_ */

View File

@ -95,18 +95,29 @@ typedef struct {
typedef NS_LIST_HEAD(llc_message_t, link) llc_message_list_t;
#define MAX_NEIGH_TEMPORRY_MULTICAST_SIZE 5
typedef struct {
ws_neighbor_temp_class_t neighbour_temporary_table[MAX_NEIGH_TEMPORRY_MULTICAST_SIZE];
ws_neighbor_temp_list_t active_temp_neigh;
ws_neighbor_temp_list_t free_temp_neigh;
} temp_entriest_t;
typedef struct {
uint8_t mac_handle_base; /**< Mac handle id base this will be updated by 1 after use */
uint8_t llc_message_list_size; /**< llc_message_list list size */
mpx_class_t mpx_data_base; /**< MPX data be including USER API Class and user call backs */
llc_message_list_t llc_message_list; /**< Active Message list */
llc_ie_params_t ie_params; /**< LLC IE header and Payload data configuration */
temp_entriest_t *temp_entries;
ws_asynch_ind *asynch_ind; /**< LLC Asynch data indication call back configured by user */
ws_asynch_confirm *asynch_confirm; /**< LLC Asynch data confirmation call back configured by user */
ws_neighbor_info_request *ws_neighbor_info_request_cb; /**< LLC Neighbour discover API*/
uint8_t ws_enhanced_ack_elements[WH_IE_ELEMENT_HEADER_LENGTH + 4 + WH_IE_ELEMENT_HEADER_LENGTH + 1];
ns_ie_iovec_t ws_header_vector;
protocol_interface_info_entry_t *interface_ptr; /**< List link entry */
ns_list_link_t link; /**< List link entry */
} llc_data_base_t;
@ -138,6 +149,9 @@ static uint16_t ws_llc_mpx_header_size_get(const mpx_api_t *api, uint16_t user_i
static uint8_t ws_llc_mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
static void ws_llc_mpx_init(mpx_class_t *mpx_class);
static void ws_llc_temp_neigh_info_table_reset(temp_entriest_t *base);
static ws_neighbor_temp_class_t *ws_allocate_multicast_temp_entry(temp_entriest_t *base, const uint8_t *mac64);
/** Discover Message by message handle id */
static llc_message_t *llc_message_discover_by_mac_handle(uint8_t handle, llc_message_list_t *list)
{
@ -352,12 +366,19 @@ static mpx_user_t *ws_llc_mpx_user_discover(mpx_class_t *mpx_class, uint16_t use
static llc_data_base_t *ws_llc_base_allocate(void)
{
llc_data_base_t *base = ns_dyn_mem_temporary_alloc(sizeof(llc_data_base_t));
if (!base) {
llc_data_base_t *base = ns_dyn_mem_alloc(sizeof(llc_data_base_t));
temp_entriest_t *temp_entries = ns_dyn_mem_alloc(sizeof(temp_entriest_t));
if (!base || !temp_entries) {
ns_dyn_mem_free(base);
ns_dyn_mem_free(temp_entries);
return NULL;
}
memset(base, 0, sizeof(llc_data_base_t));
memset(temp_entries, 0, sizeof(temp_entriest_t));
ns_list_init(&temp_entries->active_temp_neigh);
ns_list_init(&temp_entries->free_temp_neigh);
base->temp_entries = temp_entries;
ns_list_init(&base->llc_message_list);
ns_list_add_to_end(&llc_data_base_list, base);
@ -395,7 +416,7 @@ static void ws_llc_mac_confirm_cb(const mac_api_t *api, const mcps_data_conf_t *
success = true;
}
if (message->dst_address_type == MAC_ADDR_MODE_64_BIT && base->ws_neighbor_info_request_cb(interface, message->dst_address, &neighbor_info, false, false)) {
if (message->dst_address_type == MAC_ADDR_MODE_64_BIT && base->ws_neighbor_info_request_cb(interface, message->dst_address, &neighbor_info, false)) {
etx_transm_attempts_update(interface->id, 1 + data->tx_retries, success, neighbor_info.neighbor->index);
//TODO discover RSL from Enchanced ACK Header IE elements
ws_utt_ie_t ws_utt;
@ -523,27 +544,37 @@ static void ws_llc_mac_indication_cb(const mac_api_t *api, const mcps_data_ind_t
llc_neighbour_req_t neighbor_info;
bool multicast;
bool request_new_entry;
if (data->DstAddrMode == ADDR_802_15_4_LONG) {
multicast = false;
request_new_entry = us_ie_inline;
} else {
multicast = true;
request_new_entry = false;
}
if (!base->ws_neighbor_info_request_cb(interface, data->SrcAddr, &neighbor_info, us_ie_inline, multicast)) {
if (!base->ws_neighbor_info_request_cb(interface, data->SrcAddr, &neighbor_info, request_new_entry)) {
if (!multicast || ws_utt.message_type == WS_FT_EAPOL) {
tr_debug("Drop message no neighbor");
return;
} else {
goto mpx_data_ind;
//Allocate temporary entry
ws_neighbor_temp_class_t *temp_entry = ws_allocate_multicast_temp_entry(base->temp_entries, data->SrcAddr);
neighbor_info.ws_neighbor = &temp_entry->neigh_info_list;
//Storage Signal info for future ETX update possibility
temp_entry->mpduLinkQuality = data->mpduLinkQuality;
temp_entry->signal_dbm = data->signal_dbm;
}
}
multicast = false;
ws_neighbor_class_neighbor_unicast_time_info_update(neighbor_info.ws_neighbor, &ws_utt, data->timestamp);
if (us_ie_inline) {
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, &us_ie);
}
//Update BS if it is part of message
if (bs_ie_inline) {
ws_neighbor_class_neighbor_broadcast_schedule_set(neighbor_info.ws_neighbor, &ws_bs_ie);
}
if (ws_utt.message_type == WS_FT_EAPOL) {
uint8_t auth_eui64[8];
@ -551,17 +582,14 @@ static void ws_llc_mac_indication_cb(const mac_api_t *api, const mcps_data_ind_t
if (ws_wh_ea_read(ie_ext->headerIeList, ie_ext->headerIeListLength, auth_eui64)) {
ws_pae_controller_border_router_addr_write(base->interface_ptr, auth_eui64);
}
}
}
//Update BS if it is part of message
if (bs_ie_inline) {
ws_neighbor_class_neighbor_broadcast_schedule_set(neighbor_info.ws_neighbor, &ws_bs_ie);
}
//Update BT if it is part of message
ws_bt_ie_t ws_bt;
if (ws_wh_bt_read(ie_ext->headerIeList, ie_ext->headerIeListLength, &ws_bt)) {
ws_neighbor_class_neighbor_broadcast_time_info_update(neighbor_info.ws_neighbor, &ws_bt, data->timestamp);
if (neighbor_info.neighbor) {
if (neighbor_info.neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
// We have broadcast schedule set up set the broadcast parent schedule
ns_fhss_ws_set_parent(interface->ws_info->fhss_api, neighbor_info.neighbor->mac64, &neighbor_info.ws_neighbor->fhss_data.bc_timing_info, false);
@ -569,6 +597,7 @@ static void ws_llc_mac_indication_cb(const mac_api_t *api, const mcps_data_ind_t
ws_bootstrap_eapol_parent_synch(interface, &neighbor_info);
}
}
}
if (ws_utt.message_type == WS_FT_DATA) {
@ -576,24 +605,25 @@ static void ws_llc_mac_indication_cb(const mac_api_t *api, const mcps_data_ind_t
neighbor_info.ws_neighbor->unicast_data_rx = true;
}
//Refresh ETX dbm
etx_lqi_dbm_update(interface->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index);
// Calculate RSL for all UDATA packages heard
ws_neighbor_class_rsl_in_calculate(neighbor_info.ws_neighbor, data->signal_dbm);
if (neighbor_info.neighbor) {
//Refresh ETX dbm
etx_lqi_dbm_update(interface->id, data->mpduLinkQuality, data->signal_dbm, neighbor_info.neighbor->index);
if (data->Key.SecurityLevel) {
//SET trusted state
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), neighbor_info.neighbor, true);
}
}
}
mpx_data_ind:
// Discover MPX
user_cb = ws_llc_mpx_user_discover(&base->mpx_data_base, mpx_frame.multiplex_id);
if (user_cb && user_cb->data_ind) {
mcps_data_ind_t data_ind = *data;
if (multicast) {
if (!neighbor_info.neighbor) {
data_ind.Key.SecurityLevel = 0; //Mark unknow device
}
data_ind.msdu_ptr = mpx_frame.frame_ptr;
@ -892,6 +922,82 @@ static void ws_llc_clean(llc_data_base_t *base)
}
memset(&base->ie_params, 0, sizeof(llc_ie_params_t));
ws_llc_temp_neigh_info_table_reset(base->temp_entries);
}
static void ws_llc_temp_neigh_info_table_reset(temp_entriest_t *base)
{
//Empty active list
ns_list_init(&base->active_temp_neigh);
ns_list_init(&base->free_temp_neigh);
//Add to free list to full
for (int i = 0; i < MAX_NEIGH_TEMPORRY_MULTICAST_SIZE; i++) {
ns_list_add_to_end(&base->free_temp_neigh, &base->neighbour_temporary_table[i]);
}
}
static ws_neighbor_temp_class_t *ws_llc_discover_temp_entry(temp_entriest_t *base, const uint8_t *mac64)
{
ns_list_foreach_safe(ws_neighbor_temp_class_t, entry, &base->active_temp_neigh) {
if (memcmp(entry->mac64, mac64, 8) == 0) {
return entry;
}
}
return NULL;
}
ws_neighbor_temp_class_t *ws_llc_get_multicast_temp_entry(protocol_interface_info_entry_t *interface, const uint8_t *mac64)
{
llc_data_base_t *base = ws_llc_discover_by_interface(interface);
if (!base) {
return NULL;
}
return ws_llc_discover_temp_entry(base->temp_entries, mac64);
}
static ws_neighbor_temp_class_t *ws_allocate_multicast_temp_entry(temp_entriest_t *base, const uint8_t *mac64)
{
ws_neighbor_temp_class_t *entry = ws_llc_discover_temp_entry(base, mac64);
if (entry) {
ns_list_remove(&base->active_temp_neigh, entry);
ns_list_add_to_start(&base->active_temp_neigh, entry);
return entry;
}
entry = ns_list_get_first(&base->free_temp_neigh);
if (entry) {
ns_list_remove(&base->free_temp_neigh, entry);
} else {
//Replace last entry and put it to first
entry = ns_list_get_last(&base->active_temp_neigh);
ns_list_remove(&base->active_temp_neigh, entry);
}
//Add to list
ns_list_add_to_start(&base->active_temp_neigh, entry);
//Clear Old data
memset(&entry->neigh_info_list, 0, sizeof(ws_neighbor_class_entry_t));
entry->neigh_info_list.rsl_in = RSL_UNITITIALIZED;
entry->neigh_info_list.rsl_out = RSL_UNITITIALIZED;
memcpy(entry->mac64, mac64, 8);
return entry;
}
void ws_llc_free_multicast_temp_entry(protocol_interface_info_entry_t *cur, ws_neighbor_temp_class_t *neighbor)
{
llc_data_base_t *base = ws_llc_discover_by_interface(cur);
if (!base) {
return;
}
ns_list_remove(&base->temp_entries->active_temp_neigh, neighbor);
ns_list_add_to_end(&base->temp_entries->free_temp_neigh, neighbor);
}
@ -917,6 +1023,7 @@ int8_t ws_llc_create(struct protocol_interface_info_entry *interface, ws_asynch_
base->interface_ptr->mac_api->mac_mcps_extension_enable(base->interface_ptr->mac_api, &ws_llc_mac_indication_cb, &ws_llc_mac_confirm_cb, &ws_llc_ack_data_req_ext);
//Init MPX class
ws_llc_mpx_init(&base->mpx_data_base);
ws_llc_temp_neigh_info_table_reset(base->temp_entries);
return 0;
}
@ -932,6 +1039,7 @@ int8_t ws_llc_delete(struct protocol_interface_info_entry *interface)
ns_list_remove(&llc_data_base_list, base);
//Disable Mac extension
base->interface_ptr->mac_api->mac_mcps_extension_enable(base->interface_ptr->mac_api, NULL, NULL, NULL);
ns_dyn_mem_free(base->temp_entries);
ns_dyn_mem_free(base);
return 0;
}

View File

@ -45,6 +45,7 @@ typedef struct ws_neighbor_class_s {
uint8_t list_size; /*!< List size*/
} ws_neighbor_class_t;
/**
* ws_neighbor_class_alloc a function for allocate giving list size
*

View File

@ -63,6 +63,13 @@
long to wait for previous negotiation to complete */
#define EAP_TLS_NEGOTIATION_TRIGGER_TIMEOUT 60 * 10 // 60 seconds
// Default for maximum number of supplicants
#define SUPPLICANT_MAX_NUMBER 1000
/* Default for number of supplicants to purge per garbage collect call from
nanostack monitor */
#define SUPPLICANT_NUMBER_TO_PURGE 5
typedef struct {
ns_list_link_t link; /**< Link */
kmp_service_t *kmp_service; /**< KMP service */
@ -77,6 +84,7 @@ typedef struct {
sec_prot_gtk_keys_t *next_gtks; /**< Next GTKs */
const sec_prot_certs_t *certs; /**< Certificates */
timer_settings_t *timer_settings; /**< Timer settings */
uint16_t supp_max_number; /**< Max number of stored supplicants */
uint16_t slow_timer_seconds; /**< Slow timer seconds */
bool timer_running : 1; /**< Timer is running */
bool gtk_new_inst_req_exp : 1; /**< GTK new install required timer expired */
@ -140,6 +148,8 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
pae_auth->next_gtks = next_gtks;
pae_auth->certs = certs;
pae_auth->timer_settings = timer_settings;
pae_auth->supp_max_number = SUPPLICANT_MAX_NUMBER;
pae_auth->slow_timer_seconds = 0;
pae_auth->gtk_new_inst_req_exp = false;
pae_auth->gtk_new_act_time_exp = false;
@ -202,6 +212,14 @@ error:
return -1;
}
int8_t ws_pae_auth_timing_adjust(uint8_t timing)
{
auth_gkh_sec_prot_timing_adjust(timing);
auth_fwh_sec_prot_timing_adjust(timing);
auth_eap_tls_sec_prot_timing_adjust(timing);
return 0;
}
int8_t ws_pae_auth_addresses_set(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
{
if (!interface_ptr || !remote_addr) {
@ -407,6 +425,38 @@ int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *int
return 0;
}
int8_t ws_pae_auth_node_limit_set(protocol_interface_info_entry_t *interface_ptr, uint16_t limit)
{
if (!interface_ptr) {
return -1;
}
pae_auth_t *pae_auth = ws_pae_auth_get(interface_ptr);
if (!pae_auth) {
return -1;
}
pae_auth->supp_max_number = limit;
return 0;
}
void ws_pae_auth_forced_gc(protocol_interface_info_entry_t *interface_ptr)
{
if (!interface_ptr) {
return;
}
pae_auth_t *pae_auth = ws_pae_auth_get(interface_ptr);
if (!pae_auth) {
return;
}
/* Purge in maximum five entries from supplicant list (starting from oldest one)
per call to the function (called by nanostack monitor) */
ws_pae_lib_supp_list_purge(&pae_auth->active_supp_list, &pae_auth->inactive_supp_list, 0, SUPPLICANT_NUMBER_TO_PURGE);
}
static int8_t ws_pae_auth_network_keys_from_gtks_set(pae_auth_t *pae_auth)
{
// Authenticator keys are always fresh
@ -758,6 +808,9 @@ static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, kmp_type_
// If does not exists add it to list
if (!supp_entry) {
// Checks if maximum number of supplicants is reached and purge supplicant list (starting from oldest one)
ws_pae_lib_supp_list_purge(&pae_auth->active_supp_list, &pae_auth->inactive_supp_list, pae_auth->supp_max_number, 0);
supp_entry = ws_pae_lib_supp_list_add(&pae_auth->active_supp_list, addr);
if (!supp_entry) {
return 0;

View File

@ -54,6 +54,28 @@
*/
int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks, sec_prot_gtk_keys_t *next_gtks, const sec_prot_certs_t *certs, timer_settings_t *timer_settings);
/**
* ws_pae_auth_timing_adjust Adjust retries and timings of the security protocols
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_auth_timing_adjust(uint8_t timing);
/**
* ws_pae_auth_addresses_set set relay addresses
*
@ -146,6 +168,26 @@ int8_t ws_pae_auth_node_keys_remove(protocol_interface_info_entry_t *interface_p
*/
int8_t ws_pae_auth_node_access_revoke_start(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_auth_node_limit_set set node limit
*
* \param interface_ptr interface
* \param limit limit for nodes
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_auth_node_limit_set(protocol_interface_info_entry_t *interface_ptr, uint16_t limit);
/**
* ws_pae_auth_forced_gc garbage cleanup call
*
* \param interface_ptr interface
*
*/
void ws_pae_auth_forced_gc(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_auth_gtk_hash_set GTK hash set callback
*
@ -190,6 +232,7 @@ void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
#else
#define ws_pae_auth_init(interface_ptr, gtks, next_gtks, certs, timer_settings) 1
#define ws_pae_auth_timing_adjust(timing) 1
#define ws_pae_auth_addresses_set(interface_ptr, local_port, remote_addr, remote_port) 1
#define ws_pae_auth_delete NULL
#define ws_pae_auth_cb_register(interface_ptr, hash_set, nw_key_insert, nw_key_index_set) {(void) hash_set;}
@ -198,6 +241,8 @@ void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
#define ws_pae_auth_nw_key_index_update NULL
#define ws_pae_auth_node_keys_remove(interface_ptr, eui64) -1
#define ws_pae_auth_node_access_revoke_start(interface_ptr)
#define ws_pae_auth_node_limit_set(interface_ptr, limit)
#define ws_pae_auth_forced_gc(interface_ptr)
#define ws_pae_auth_fast_timer NULL
#define ws_pae_auth_slow_timer NULL

View File

@ -97,6 +97,11 @@ typedef struct {
bool key_index_set : 1; /**< NW key index is set */
} pae_controller_t;
typedef struct {
uint16_t node_limit; /**< Max number of stored supplicants */
bool node_limit_set : 1; /**< Node limit set */
} pae_controller_config_t;
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr);
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry);
static void ws_pae_controller_frame_counter_store(pae_controller_t *entry);
@ -119,6 +124,11 @@ static const char *FRAME_COUNTER_FILE = FRAME_COUNTER_FILE_NAME;
static NS_LIST_DEFINE(pae_controller_list, pae_controller_t, link);
pae_controller_config_t pae_controller_config = {
.node_limit = 0,
.node_limit_set = false
};
#if !defined(HAVE_PAE_SUPP) && !defined(HAVE_PAE_AUTH)
static void ws_pae_controller_test_keys_set(sec_prot_gtk_keys_t *gtks)
@ -172,6 +182,25 @@ int8_t ws_pae_controller_authenticate(protocol_interface_info_entry_t *interface
return 0;
}
int8_t ws_pae_controller_bootstrap_done(protocol_interface_info_entry_t *interface_ptr)
{
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
if (!controller) {
return -1;
}
#ifdef HAVE_PAE_SUPP
// RPL parent is known, remove EAPOL target that what was set using the authenticate call */
ws_pae_supp_eapol_target_remove(interface_ptr);
/* Trigger GTK hash update to supplicant, so it can check whether keys have been updated
during bootstrap. Does nothing if GTKs are up to date. */
ws_pae_supp_gtk_hash_update(interface_ptr, controller->gtkhash);
#endif
return 0;
}
int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port)
{
(void) local_port;
@ -204,6 +233,10 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
return -1;
}
if (pae_controller_config.node_limit_set) {
ws_pae_auth_node_limit_set(controller->interface_ptr, pae_controller_config.node_limit);
}
ws_pae_auth_cb_register(interface_ptr, ws_pae_controller_gtk_hash_set, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_nw_key_index_check_and_set);
ws_pae_auth_start(interface_ptr);
@ -696,6 +729,13 @@ int8_t ws_pae_controller_delete(protocol_interface_info_entry_t *interface_ptr)
return 0;
}
int8_t ws_pae_controller_timing_adjust(uint8_t timing)
{
ws_pae_supp_timing_adjust(timing);
ws_pae_auth_timing_adjust(timing);
return 0;
}
int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry_s *new_chain)
{
if (!new_chain) {
@ -990,6 +1030,41 @@ int8_t ws_pae_controller_node_access_revoke_start(int8_t interface_id)
return -1;
}
int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit)
{
#ifdef HAVE_PAE_AUTH
pae_controller_config.node_limit = limit;
pae_controller_config.node_limit_set = true;
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
if (!controller) {
return -1;
}
ws_pae_auth_node_limit_set(controller->interface_ptr, limit);
return 0;
#else
(void) interface_id;
(void) limit;
return -1;
#endif
}
void ws_pae_controller_forced_gc(bool full_gc)
{
/* Purge only when on critical limit since node limit should handle limiting
of entries in normal case */
if (!full_gc) {
return;
}
// Purge authenticators for each interface
ns_list_foreach(pae_controller_t, entry, &pae_controller_list) {
ws_pae_auth_forced_gc(entry->interface_ptr);
}
}
static void ws_pae_controller_gtk_hash_set(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash)
{
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
@ -1086,7 +1161,6 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry)
}
}
static int8_t ws_pae_controller_nvm_frame_counter_read(uint8_t *index, uint8_t *hash, uint32_t *frame_counter)
{
nvm_tlv_list_t tlv_list;

View File

@ -45,6 +45,17 @@ int8_t ws_pae_controller_set_target(protocol_interface_info_entry_t *interface_p
*/
int8_t ws_pae_controller_authenticate(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_controller_bootstrap_done indicates to PAE controller that bootstrap is ready
*
* \param interface_ptr interface
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_controller_bootstrap_done(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_controller_authenticator_start start PAE authenticator
*
@ -114,6 +125,28 @@ int8_t ws_pae_controller_stop(protocol_interface_info_entry_t *interface_ptr);
*/
int8_t ws_pae_controller_delete(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_controller_timing_adjust Adjust retries and timings of the security protocols
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_controller_timing_adjust(uint8_t timing);
/**
* ws_pae_controller_certificate_chain_set set certificate chain
*
@ -293,6 +326,18 @@ int8_t ws_pae_controller_node_keys_remove(int8_t interface_id, uint8_t *eui_64);
*/
int8_t ws_pae_controller_node_access_revoke_start(int8_t interface_id);
/**
* ws_pae_controller_node_limit_set set node limit
*
* \param interface_id interface identifier
* \param limit limit for nodes
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit);
/**
* ws_pae_controller_active_key_update update active key (test interface)
*
@ -437,7 +482,6 @@ int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_
*/
void ws_pae_controller_fast_timer(uint16_t ticks);
/**
* ws_pae_controller_slow_timer PAE controller slow timer call
*
@ -448,6 +492,14 @@ void ws_pae_controller_slow_timer(uint16_t seconds);
struct nvm_tlv_entry *ws_pae_controller_nvm_tlv_get(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_controller_forced_gc PAE controller garbage cleanup callback
*
* \param full_gc Full cleanup (true for critical garbage cleanup)
*
*/
void ws_pae_controller_forced_gc(bool full_gc);
#else
#define ws_pae_controller_set_target(interface_ptr, target_pan_id, target_dest_eui_64)
@ -470,6 +522,8 @@ struct nvm_tlv_entry *ws_pae_controller_nvm_tlv_get(protocol_interface_info_entr
#define ws_pae_controller_cb_register(interface_ptr, completed, nw_key_set, nw_key_clear, nw_send_key_index_set, pan_ver_increment) 1
#define ws_pae_controller_nvm_tlv_get(interface_ptr) NULL
#define ws_pae_controller_forced_gc NULL
#endif
#endif /* WS_PAE_CONTROLLER_H_ */

View File

@ -316,6 +316,30 @@ void ws_pae_lib_supp_list_to_inactive(supp_list_t *active_supp_list, supp_list_t
memset(entry->addr.relay_address, 0, 16);
}
void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, uint16_t max_number, uint8_t max_purge)
{
uint16_t active_supp = ns_list_count(active_supp_list);
uint16_t inactive_supp = ns_list_count(inactive_supp_list);
if (active_supp + inactive_supp > max_number) {
uint16_t remove_count = active_supp + inactive_supp - max_number;
if (max_purge > 0 && remove_count > max_purge) {
remove_count = max_purge;
}
// Remove entries from inactive list
ns_list_foreach_safe(supp_entry_t, entry, inactive_supp_list) {
if (remove_count > 0) {
tr_info("Inactive supplicant removed, eui-64: %s", trace_array(kmp_address_eui_64_get(&entry->addr), 8));
ws_pae_lib_supp_list_remove(inactive_supp_list, entry);
remove_count--;
} else {
break;
}
}
}
}
uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type)
{
uint16_t kmp_count = 0;

View File

@ -280,6 +280,18 @@ void ws_pae_lib_supp_list_to_active(supp_list_t *active_supp_list, supp_list_t *
*/
void ws_pae_lib_supp_list_to_inactive(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, supp_entry_t *entry);
/**
* ws_pae_lib_supp_list_purge purge inactive supplicants list
*
* \param active_supp_list list of active supplicants
* \param inactive_supp_list list of inactive supplicants
* \param max_number maximum number of supplicant entries, can be set to 0 in combination with max_purge
* to free list entries even when maximum number supplicant entries has not been reached
* \param max_purge maximum number of supplicants to purge in one call, 0 means not limited
*
*/
void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, uint16_t max_number, uint8_t max_purge);
/**
* ws_pae_lib_supp_list_kmp_count counts the number of KMPs of a certain type in a list of supplicants
*

View File

@ -166,6 +166,11 @@ static void ws_pae_supp_address_set(pae_supp_t *pae_supp, kmp_addr_t *address)
}
}
static bool ws_pae_supp_address_is_set(pae_supp_t *pae_supp)
{
return pae_supp->entry_address_active;
}
int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64)
{
pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr);
@ -321,6 +326,9 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
ws_pae_supp_timer_start(pae_supp);
tr_info("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i", pae_supp->timer_settings->gtk_request_imin, pae_supp->timer_settings->gtk_request_imax, pae_supp->timer_settings->gtk_max_mismatch, pae_supp->auth_trickle_timer.t);
} else {
// If trickle is already running, set inconsistent heard to speed up the trickle
trickle_inconsistent_heard(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params);
}
}
@ -346,6 +354,19 @@ int8_t ws_pae_supp_nw_key_index_update(protocol_interface_info_entry_t *interfac
return 0;
}
int8_t ws_pae_supp_eapol_target_remove(protocol_interface_info_entry_t *interface_ptr)
{
pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr);
if (!pae_supp) {
return -1;
}
// Sets target/parent address to null
ws_pae_supp_address_set(pae_supp, NULL);
return 0;
}
static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp)
{
// Check if NW info or GTKs have been changed
@ -450,14 +471,20 @@ static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp)
if (!pae_supp->auth_requested) {
// If not making initial authentication updates target (RPL parent) for each EAPOL-key message
uint8_t parent_eui_64[8];
if (ws_pae_supp_parent_eui_64_get(pae_supp->interface_ptr, parent_eui_64) < 0) {
return -1;
}
if (ws_pae_supp_parent_eui_64_get(pae_supp->interface_ptr, parent_eui_64) >= 0) {
// Stores target/parent address
kmp_address_init(KMP_ADDR_EUI_64, &pae_supp->target_addr, parent_eui_64);
// Sets parent address in use
ws_pae_supp_address_set(pae_supp, &pae_supp->target_addr);
} else if (ws_pae_supp_address_is_set(pae_supp)) {
/* If there is no RPL parent but there is target address from initial authentication
bootstrap, tries to use it. This can happen if BR updates keys after EAPOL authentication
but before bootstrap is completed and RPL parent is known */
tr_info("EAPOL initial auth target used");
} else {
// No target, failure
return -1;
}
ws_pae_lib_supp_timer_ticks_set(&pae_supp->entry, WAIT_FOR_REAUTHENTICATION_TICKS);
tr_info("PAE wait for auth seconds: %i", WAIT_FOR_REAUTHENTICATION_TICKS / 10);
@ -656,6 +683,13 @@ int8_t ws_pae_supp_delete(protocol_interface_info_entry_t *interface_ptr)
return 0;
}
int8_t ws_pae_supp_timing_adjust(uint8_t timing)
{
supp_fwh_sec_prot_timing_adjust(timing);
supp_eap_sec_prot_timing_adjust(timing);
return 0;
}
static void ws_pae_supp_free(pae_supp_t *pae_supp)
{
if (!pae_supp) {
@ -751,10 +785,7 @@ void ws_pae_supp_fast_timer(uint16_t ticks)
// Checks whether timer needs to be active
if (!pae_supp->initial_key_timer && !pae_supp->auth_trickle_running && !running) {
tr_debug("PAE idle");
// Sets target/parent address to null
ws_pae_supp_address_set(pae_supp, NULL);
// If not already completed, restart bootstrap
ws_pae_supp_authenticate_response(pae_supp, false);
@ -770,7 +801,9 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
// Checks whether initial EAPOL-Key message needs to be re-send or new GTK request to be sent
if (pae_supp->auth_trickle_running) {
if (trickle_timer(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params, seconds)) {
ws_pae_supp_initial_key_send(pae_supp);
if (ws_pae_supp_initial_key_send(pae_supp) < 0) {
tr_info("EAPOL-Key send failed");
}
}
// Maximum number of trickle expires, authentication fails
if (!trickle_running(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params)) {
@ -793,14 +826,15 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
pae_supp->initial_key_timer = 0;
// Sends initial EAPOL-Key message
ws_pae_supp_initial_key_send(pae_supp);
if (ws_pae_supp_initial_key_send(pae_supp) < 0) {
tr_info("EAPOL-Key send failed");
}
// Starts trickle
pae_supp->auth_trickle_params = initial_eapol_key_trickle_params;
trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params);
pae_supp->auth_trickle_running = true;
}
}
}
}

View File

@ -57,6 +57,29 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
*/
int8_t ws_pae_supp_delete(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_supp_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_supp_timing_adjust(uint8_t timing);
/**
* ws_pae_supp_fast_timer PAE supplicant fast timer call
*
@ -159,6 +182,17 @@ int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_pt
*/
int8_t ws_pae_supp_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index);
/**
* ws_pae_supp_eapol_target_remove remove EAPOL target set using authentication start
*
* \param interface_ptr interface
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t ws_pae_supp_eapol_target_remove(protocol_interface_info_entry_t *interface_ptr);
/**
* ws_pae_supp_nw_key_index_set network send key index set callback
*
@ -204,6 +238,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
#define ws_pae_supp_init(interface_ptr, certs, timer_settings) 1
#define ws_pae_supp_delete NULL
#define ws_pae_supp_timing_adjust(timing) 1
#define ws_pae_supp_cb_register(interface_ptr, completed, nw_key_insert, nw_key_index_set)
#define ws_pae_supp_nw_info_set(interface_ptr, pan_id, network_name) -1
#define ws_pae_supp_nw_key_valid(interface_ptr) -1
@ -214,6 +249,7 @@ void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
#define ws_pae_supp_border_router_addr_read NULL
#define ws_pae_supp_gtk_hash_update NULL
#define ws_pae_supp_nw_key_index_update NULL
#define ws_pae_supp_eapol_target_remove(interface_ptr)
#endif

View File

@ -1049,8 +1049,10 @@ buffer_t *icmpv6_up(buffer_t *buf)
buf->options.code = *dptr++;
if (buf->options.ll_security_bypass_rx) {
if (!ws_info(buf->interface) || !(buf->options.type == ICMPV6_TYPE_INFO_RPL_CONTROL && buf->options.code == ICMPV6_CODE_RPL_DIS)) {
//tr_debug("ICMP: Drop by EP");
if (!ws_info(buf->interface)
|| (buf->options.type == ICMPV6_TYPE_INFO_RPL_CONTROL
&& (buf->options.code != ICMPV6_CODE_RPL_DIO
&& buf->options.code != ICMPV6_CODE_RPL_DIS))) {
goto drop;
}
}

View File

@ -33,6 +33,8 @@
#include "nsdynmemLIB.h"
#include "ipv6_stack/ipv6_routing_table.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/ws/ws_pae_controller.h"
#include "NWK_INTERFACE/Include/protocol.h"
#define TRACE_GROUP "mntr"
@ -68,7 +70,8 @@ typedef void (ns_maintenance_gc_cb)(bool full_gc);
*
*/
static ns_maintenance_gc_cb *ns_maintenance_gc_functions[] = {
ipv6_destination_cache_forced_gc
ipv6_destination_cache_forced_gc,
ws_pae_controller_forced_gc
};
static void ns_monitor_heap_gc(bool full_gc)

View File

@ -380,11 +380,12 @@ void rpl_control_remove_domain_from_interface(protocol_interface_info_entry_t *c
}
}
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, void *cb_handle)
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, rpl_new_parent_callback_t new_parent_add, void *cb_handle)
{
domain->callback = callback;
domain->prefix_cb = prefix_learn_cb;
domain->cb_handle = cb_handle;
domain->new_parent_add = new_parent_add;
}
/* To do - this should live somewhere nicer. Basically a bootstrap
@ -976,6 +977,9 @@ malformed:
const rpl_dodag_conf_t *conf = rpl_dodag_get_config(dodag);
if (!conf) {
/* TODO - rate limit DIS? */
if (domain->new_parent_add && !domain->new_parent_add(buf->src_sa.address, domain->cb_handle)) {
goto invalid_parent;
}
rpl_control_transmit_dis(domain, cur, RPL_SOLINFO_PRED_DODAGID | RPL_SOLINFO_PRED_INSTANCEID, instance_id, dodagid, 0, buf->src_sa.address);
goto invalid_parent;
}
@ -1008,9 +1012,15 @@ malformed:
/* Now we create the neighbour, if we don't already have a record */
if (!neighbour) {
neighbour = rpl_create_neighbour(version, buf->src_sa.address, cur->id, g_mop_prf, dtsn);
//Call Here new parent create
if (!neighbour) {
goto invalid_parent;
}
if (domain->new_parent_add && !domain->new_parent_add(buf->src_sa.address, domain->cb_handle)) {
goto invalid_parent;
}
}
/* Update neighbour info */

View File

@ -42,6 +42,8 @@ typedef void rpl_domain_callback_t(rpl_event_t event, void *handle);
typedef void rpl_prefix_callback_t(struct prefix_entry_t *prefix, void *handle, uint8_t *parent_link_local);
typedef bool rpl_new_parent_callback_t(uint8_t *ll_parent_address, void *handle);
typedef struct rpl_domain {
NS_LIST_HEAD_INCOMPLETE(struct rpl_instance) instances;
ns_list_link_t link;
@ -54,6 +56,7 @@ typedef struct rpl_domain {
bool force_leaf;
rpl_domain_callback_t *callback;
rpl_prefix_callback_t *prefix_cb;
rpl_new_parent_callback_t *new_parent_add;
void *cb_handle;
} rpl_domain_t;
@ -142,7 +145,7 @@ rpl_domain_t *rpl_control_create_domain(void);
void rpl_control_delete_domain(rpl_domain_t *domain);
void rpl_control_set_domain_on_interface(struct protocol_interface_info_entry *cur, rpl_domain_t *domain, bool downstream);
void rpl_control_remove_domain_from_interface(struct protocol_interface_info_entry *cur);
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, void *cb_handle);
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, rpl_new_parent_callback_t new_parent_add, void *cb_handle);
/* Target publishing */
void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t lifetime);

View File

@ -180,6 +180,16 @@ static void rpl_downward_target_refresh(rpl_dao_target_t *target)
target->info.non_root.path_lifetime = 0;
}
static bool rpl_instance_parent_selection_ready(rpl_instance_t *instance)
{
rpl_neighbour_t *neighbour = ns_list_get_first(&instance->candidate_neighbours);
if (neighbour && neighbour->dodag_parent && neighbour->dao_path_control) {
//We have a Primary parent with Dao patha control
return true;
}
return false;
}
void rpl_downward_neighbour_gone(rpl_instance_t *instance, rpl_neighbour_t *neighbour)
{
if (neighbour->dao_path_control == 0) {
@ -380,6 +390,7 @@ void rpl_instance_publish_dao_target(rpl_instance_t *instance, const uint8_t *pr
tr_debug("New Target %s", trace_ipv6(target->prefix));
/* Path lifetime left as 0 for now - will be filled in on transmission, along with refresh timer */
rpl_instance_dao_trigger(instance, 0);
}
void rpl_instance_dao_trigger(rpl_instance_t *instance, uint16_t delay)
@ -627,6 +638,11 @@ static rpl_dao_target_t *rpl_instance_get_pending_target_confirmation(rpl_instan
void rpl_instance_send_address_registration(rpl_instance_t *instance, const uint8_t addr[16])
{
if (!rpl_instance_parent_selection_ready(instance)) {
return;
}
if (addr) {
rpl_dao_target_t *target = rpl_instance_get_pending_target_confirmation_for_address(instance, addr);
if (!target) {
@ -1751,7 +1767,18 @@ static if_address_entry_t *rpl_interface_addr_get(protocol_interface_info_entry_
return NULL;
}
static void rpl_instance_address_registration_cancel(rpl_instance_t *instance)
{
ns_list_foreach_safe(rpl_dao_target_t, n, &instance->dao_targets) {
n->active_confirmation_state = false;
n->trig_confirmation_state = false;
n->response_wait_time = 0;
}
instance->wait_response = NULL;
instance->pending_neighbour_confirmation = false;
instance->delay_dao_timer = 0;
}
void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint16_t seconds)
{
@ -1759,6 +1786,12 @@ void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint
return; //No need validate any confirmation
}
//Verify that we have selected parent and it have a dao path control
if (!rpl_instance_parent_selection_ready(instance)) {
rpl_instance_address_registration_cancel(instance);
return;
}
//Get Pendig active target
rpl_dao_target_t *dao_target = rpl_instance_get_active_target_confirmation(instance);
if (!dao_target) {
@ -1772,8 +1805,7 @@ void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint
}
if (instance->wait_response) {
uint16_t wait_time = dao_target->response_wait_time;
if (seconds < wait_time) {
if (seconds < dao_target->response_wait_time) {
//Must Wait response time untill finish
dao_target->response_wait_time -= seconds;
return;
@ -1792,17 +1824,13 @@ void rpl_instance_parent_address_reg_timer_update(rpl_instance_t *instance, uint
//Get address and buffer
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(neighbour->interface_id);
if (!interface) {
dao_target->response_wait_time = 0;
instance->wait_response = NULL;
dao_target->active_confirmation_state = false;
rpl_instance_address_registration_cancel(instance);
return;
}
if_address_entry_t *address = rpl_interface_addr_get(interface, dao_target->prefix);
if (!address) {
dao_target->response_wait_time = 0;
instance->wait_response = NULL;
dao_target->active_confirmation_state = false;
rpl_instance_address_registration_cancel(instance);
return;
}
@ -1839,6 +1867,7 @@ void rpl_instance_address_registration_done(protocol_interface_info_entry_t *int
} else {
tr_error("Address registration failed");
rpl_delete_neighbour(instance, neighbour);
rpl_instance_address_registration_cancel(instance);
}
}

View File

@ -69,9 +69,18 @@ typedef struct {
bool send_pending: 1; /**< TLS data is not yet send to network */
} eap_tls_sec_prot_int_t;
static const trickle_params_t eap_tls_trickle_params = {
.Imin = 200, /* 20s; ticks are 100ms */
.Imax = 450, /* 45s */
/*Small network setup*/
#define EAP_TLS_SMALL_IMIN 300 // retries done in 30 seconds
#define EAP_TLS_SMALL_IMAX 900 // Largest value 90 seconds
/* Large network setup*/
#define EAP_TLS_LARGE_IMIN 600 // retries done in 60 seconds
#define EAP_TLS_LARGE_IMAX 2400 // Largest value 240 seconds
static trickle_params_t eap_tls_trickle_params = {
.Imin = EAP_TLS_SMALL_IMIN, /* ticks are 100ms */
.Imax = EAP_TLS_SMALL_IMAX, /* ticks are 100ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 2
};
@ -109,6 +118,19 @@ int8_t auth_eap_tls_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t auth_eap_tls_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
eap_tls_trickle_params.Imin = EAP_TLS_SMALL_IMIN;
eap_tls_trickle_params.Imax = EAP_TLS_SMALL_IMAX;
} else {
eap_tls_trickle_params.Imin = EAP_TLS_LARGE_IMIN;
eap_tls_trickle_params.Imax = EAP_TLS_LARGE_IMAX;
}
return 0;
}
static uint16_t auth_eap_tls_sec_prot_size(void)
{
return sizeof(eap_tls_sec_prot_int_t);
@ -430,8 +452,6 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
return;
}
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE);
// EAP response
if (data->eap_code == EAP_RESPONSE) {
// Handle EAP response, TLS EAP
@ -445,6 +465,8 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
return;
}
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE);
// All fragments received for a message
if (result == EAP_TLS_MSG_RECEIVE_DONE) {
auth_eap_tls_sec_prot_init_tls(prot);

View File

@ -33,4 +33,26 @@
*/
int8_t auth_eap_tls_sec_prot_register(kmp_service_t *service);
/**
* auth_eap_tls_sec_prot_timing_adjust Adjust retries and timings of the EAP-TLS protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t auth_eap_tls_sec_prot_timing_adjust(uint8_t timing);
#endif /* AUTH_EAP_TLS_SEC_PROT_H_ */

View File

@ -72,12 +72,10 @@ typedef struct {
bool send_pending: 1; /**< TLS data is not yet send to network */
} eap_tls_sec_prot_int_t;
static const trickle_params_t eap_tls_trickle_params = {
.Imin = 200, /* 20s; ticks are 100ms */
.Imax = 450, /* 45s */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 2
};
#define FWH_RETRY_TIMEOUT_SMALL 330*10 // retry timeout for small network additional 30 seconds for authenticator delay
#define FWH_RETRY_TIMEOUT_LARGE 750*10 // retry timeout for large network additional 30 seconds for authenticator delay
static uint16_t retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
static uint16_t supp_eap_tls_sec_prot_size(void);
static int8_t supp_eap_tls_sec_prot_init(sec_prot_t *prot);
@ -112,6 +110,17 @@ int8_t supp_eap_tls_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t supp_eap_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
} else {
retry_timeout = FWH_RETRY_TIMEOUT_LARGE;
}
return 0;
}
static uint16_t supp_eap_tls_sec_prot_size(void)
{
return sizeof(eap_tls_sec_prot_int_t);
@ -281,7 +290,7 @@ static void supp_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks
data->burst_filt_timer = 0;
}
sec_prot_timer_timeout_handle(prot, &data->common, &eap_tls_trickle_params, ticks);
sec_prot_timer_timeout_handle(prot, &data->common, NULL, ticks);
}
static void supp_eap_tls_sec_prot_tls_create_confirm(sec_prot_t *tls_prot, sec_prot_result_e result)
@ -420,9 +429,6 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
// Send EAP response, Identity
supp_eap_tls_sec_prot_message_send(prot, EAP_RESPONSE, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE);
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST_TLS_EAP);
} else {
// Ready to be deleted
@ -431,12 +437,6 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
break;
case EAP_TLS_STATE_REQUEST_TLS_EAP:
// On timeout
if (sec_prot_result_timeout_check(&data->common)) {
/* Waits for next trickle expire. If trickle expirations reach the limit,
terminates EAP-TLS */
return;
}
// Handle EAP request (expected TLS EAP start)
result = supp_eap_tls_sec_prot_message_handle(prot);
@ -456,6 +456,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
supp_eap_tls_sec_prot_seq_id_update(prot);
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST);
data->common.ticks = retry_timeout;
// Initialize TLS protocol
supp_eap_tls_sec_prot_init_tls(prot);
@ -464,12 +465,6 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
break;
case EAP_TLS_STATE_REQUEST:
// On timeout
if (sec_prot_result_timeout_check(&data->common)) {
/* Waits for next trickle expire. If trickle expirations reach the limit,
terminates EAP-TLS */
return;
}
// EAP success
if (data->eap_code == EAP_SUCCESS) {
@ -514,8 +509,9 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
supp_eap_tls_sec_prot_message_send(prot, EAP_RESPONSE, EAP_TLS, EAP_TLS_EXCHANGE_ONGOING);
data->send_pending = false;
// Start trickle timer to re-send if no response
sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
// Add more time for re-send if no response
data->common.ticks = retry_timeout;
break;
case EAP_TLS_STATE_FINISH:

View File

@ -33,5 +33,27 @@
*/
int8_t supp_eap_tls_sec_prot_register(kmp_service_t *service);
/**
* supp_eap_sec_prot_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t supp_eap_sec_prot_timing_adjust(uint8_t timing);
#endif /* SUPP_EAP_TLS_SEC_PROT_H_ */

View File

@ -68,11 +68,19 @@ typedef struct {
uint16_t recv_size; /**< received pdu size */
} fwh_sec_prot_int_t;
static const trickle_params_t fwh_trickle_params = {
.Imin = 50, /* 5000ms; ticks are 100ms */
.Imax = 150, /* 15000ms */
/*Small network setup*/
#define FWH_SMALL_IMIN 300 // retries done in 30 seconds
#define FWH_SMALL_IMAX 900 // Largest value 90 seconds
/* Large network setup*/
#define FWH_LARGE_IMIN 600 // retries done in 60 seconds
#define FWH_LARGE_IMAX 2400 // Largest value 240 seconds
static trickle_params_t fwh_trickle_params = {
.Imin = FWH_SMALL_IMIN, /* ticks are 100ms */
.Imax = FWH_SMALL_IMAX, /* ticks are 100ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 4
.TimerExpirations = 2
};
static uint16_t auth_fwh_sec_prot_size(void);
@ -105,6 +113,18 @@ int8_t auth_fwh_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t auth_fwh_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
fwh_trickle_params.Imin = FWH_SMALL_IMIN;
fwh_trickle_params.Imax = FWH_SMALL_IMAX;
} else {
fwh_trickle_params.Imin = FWH_LARGE_IMIN;
fwh_trickle_params.Imax = FWH_LARGE_IMAX;
}
return 0;
}
static uint16_t auth_fwh_sec_prot_size(void)
{
return sizeof(fwh_sec_prot_int_t);

View File

@ -34,4 +34,26 @@
*/
int8_t auth_fwh_sec_prot_register(kmp_service_t *service);
/**
* auth_fwh_sec_prot_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t auth_fwh_sec_prot_timing_adjust(uint8_t timing);
#endif /* AUTH_FWH_SEC_PROT_H_ */

View File

@ -82,6 +82,11 @@ typedef struct {
bool recv_replay_cnt_set : 1; /**< received replay counter set */
} fwh_sec_prot_int_t;
#define FWH_RETRY_TIMEOUT_SMALL 300*10 // retry timeout for small network
#define FWH_RETRY_TIMEOUT_LARGE 720*10 // retry timeout for large network
static uint16_t retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
static uint16_t supp_fwh_sec_prot_size(void);
static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot);
@ -119,6 +124,15 @@ int8_t supp_fwh_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t supp_fwh_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
retry_timeout = FWH_RETRY_TIMEOUT_SMALL;
} else {
retry_timeout = FWH_RETRY_TIMEOUT_LARGE;
}
return 0;
}
static uint16_t supp_fwh_sec_prot_size(void)
{
@ -138,7 +152,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot)
sec_prot_init(&data->common);
sec_prot_state_set(prot, &data->common, FWH_STATE_INIT);
data->common.ticks = 30 * 10; // 30 seconds
data->common.ticks = retry_timeout;
data->msg3_received = false;
data->msg3_retry_wait = false;
data->recv_replay_cnt = 0;
@ -332,7 +346,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
if (sec_prot_result_ok_check(&data->common)) {
// Send 4WH message 2
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_2);
data->common.ticks = 30 * 10; // 30 seconds
data->common.ticks = retry_timeout;
sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_3);
} else {
// Ready to be deleted
@ -360,7 +374,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
// Send 4WH message 2
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_2);
data->common.ticks = 30 * 10; // 30 seconds
data->common.ticks = retry_timeout;
return;
} else if (data->recv_msg != FWH_MESSAGE_3) {
return;
@ -387,7 +401,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
// Sends 4WH Message 4
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_4);
data->common.ticks = 30 * 10; // 30 seconds
data->common.ticks = retry_timeout;
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISH);
break;

View File

@ -34,4 +34,26 @@
*/
int8_t supp_fwh_sec_prot_register(kmp_service_t *service);
/**
* supp_fwh_sec_prot_timing_adjust Adjust retries and timings of the 4WH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t supp_fwh_sec_prot_timing_adjust(uint8_t timing);
#endif /* SUPP_FWH_SEC_PROT_H_ */

View File

@ -60,11 +60,19 @@ typedef struct {
uint16_t recv_size; /**< Received pdu size */
} gkh_sec_prot_int_t;
static const trickle_params_t gkh_trickle_params = {
.Imin = 50, /* 5000ms; ticks are 100ms */
.Imax = 150, /* 15000ms */
/*Small network setup*/
#define GKH_SMALL_IMIN 300 // retries done in 30 seconds
#define GKH_SMALL_IMAX 900 // Largest value 90 seconds
/* Large network setup*/
#define GKH_LARGE_IMIN 600 // retries done in 60 seconds
#define GKH_LARGE_IMAX 2400 // Largest value 240 seconds
static trickle_params_t gkh_trickle_params = {
.Imin = GKH_SMALL_IMIN, /* ticks are 100ms */
.Imax = GKH_SMALL_IMAX, /* ticks are 100ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 4
.TimerExpirations = 2
};
static uint16_t auth_gkh_sec_prot_size(void);
@ -95,6 +103,18 @@ int8_t auth_gkh_sec_prot_register(kmp_service_t *service)
return 0;
}
int8_t auth_gkh_sec_prot_timing_adjust(uint8_t timing)
{
if (timing < 16) {
gkh_trickle_params.Imin = GKH_SMALL_IMIN;
gkh_trickle_params.Imax = GKH_SMALL_IMAX;
} else {
gkh_trickle_params.Imin = GKH_LARGE_IMIN;
gkh_trickle_params.Imax = GKH_LARGE_IMAX;
}
return 0;
}
static uint16_t auth_gkh_sec_prot_size(void)
{
return sizeof(gkh_sec_prot_int_t);

View File

@ -28,4 +28,26 @@
*/
int8_t auth_gkh_sec_prot_register(kmp_service_t *service);
/**
* auth_gkh_sec_prot_timing_adjust Adjust retries and timings of the GKH protocol
*
* Timing value is a generic number between 0 to 32 that goes from fast and
* reactive network to low bandwidth and long latency.
*
* example value definitions:
* 0-8 very fast network
* 9-16 medium network
* 16-24 slow network
* 25-32 extremely slow network
*
* There is no need to have lots variations in every layer if protocol is not very active in any case.
*
* \param timing Timing value.
*
* \return < 0 failure
* \return >= 0 success
*
*/
int8_t auth_gkh_sec_prot_timing_adjust(uint8_t timing);
#endif /* AUTH_GKH_SEC_PROT_H_ */

View File

@ -60,13 +60,6 @@ typedef struct {
uint16_t recv_size; /**< Received pdu size */
} gkh_sec_prot_int_t;
static const trickle_params_t gkh_trickle_params = {
.Imin = 50, /* 5000ms; ticks are 100ms */
.Imax = 150, /* 15000ms */
.k = 0, /* infinity - no consistency checking */
.TimerExpirations = 4
};
static uint16_t supp_gkh_sec_prot_size(void);
static int8_t supp_gkh_sec_prot_init(sec_prot_t *prot);
@ -227,7 +220,7 @@ static int8_t supp_gkh_sec_prot_message_send(sec_prot_t *prot, gkh_sec_prot_msg_
static void supp_gkh_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
{
gkh_sec_prot_int_t *data = gkh_sec_prot_get(prot);
sec_prot_timer_timeout_handle(prot, &data->common, &gkh_trickle_params, ticks);
sec_prot_timer_timeout_handle(prot, &data->common, NULL, ticks);
}
static void supp_gkh_sec_prot_state_machine(sec_prot_t *prot)

View File

@ -70,12 +70,6 @@ struct tls_security_s {
mbedtls_x509_crl *crl; /**< Certificate Revocation List */
mbedtls_x509_crt owncert; /**< Own certificate(s) */
mbedtls_pk_context pkey; /**< Private key for own certificate */
uint8_t client_random[32]; /**< Client random (from Client Hello) */
uint8_t server_random[32]; /**< Server random (from Server Hello) */
uint8_t step; /**< Random extract step */
void *handle; /**< Handle provided in callbacks (defined by library user) */
tls_sec_prot_lib_send *send; /**< Send callback */
tls_sec_prot_lib_receive *receive; /**< Receive callback */
@ -89,9 +83,11 @@ static int tls_sec_prot_lib_ssl_get_timer(void *ctx);
static int tls_sec_lib_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen);
static int tls_sec_prot_lib_ssl_send(void *ctx, const unsigned char *buf, size_t len);
static int tls_sec_prot_lib_ssl_recv(void *ctx, unsigned char *buf, size_t len);
static int tls_sec_prot_lib_ssl_export_keys(void *ctx, const unsigned char *ms,
const unsigned char *kb, size_t maclen, size_t keylen, size_t ivlen);
static void tls_sec_prot_lib_random_extract(tls_security_t *sec, const uint8_t *buf, uint16_t len);
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *ms,
const unsigned char *kb, size_t maclen, size_t keylen,
size_t ivlen, unsigned char client_random[32],
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type);
#ifdef TLS_SEC_PROT_LIB_TLS_DEBUG
static void tls_sec_prot_lib_debug(void *ctx, int level, const char *file, int line, const char *string);
#endif
@ -126,7 +122,6 @@ int8_t tls_sec_prot_lib_init(tls_security_t *sec)
mbedtls_pk_init(&sec->pkey);
sec->crl = NULL;
sec->step = 0;
if (mbedtls_entropy_add_source(&sec->entropy, tls_sec_lib_entropy_poll, NULL,
128, MBEDTLS_ENTROPY_SOURCE_WEAK) < 0) {
@ -331,7 +326,7 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
#endif
// Export keys callback
mbedtls_ssl_conf_export_keys_cb(&sec->conf, tls_sec_prot_lib_ssl_export_keys, sec);
mbedtls_ssl_conf_export_keys_ext_cb(&sec->conf, tls_sec_prot_lib_ssl_export_keys, sec);
mbedtls_ssl_conf_min_version(&sec->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
mbedtls_ssl_conf_max_version(&sec->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
@ -394,9 +389,6 @@ static int tls_sec_prot_lib_ssl_get_timer(void *ctx)
static int tls_sec_prot_lib_ssl_send(void *ctx, const unsigned char *buf, size_t len)
{
tls_security_t *sec = (tls_security_t *)ctx;
tls_sec_prot_lib_random_extract(sec, buf, len);
return sec->send(sec->handle, buf, len);
}
@ -408,75 +400,35 @@ static int tls_sec_prot_lib_ssl_recv(void *ctx, unsigned char *buf, size_t len)
if (ret == TLS_SEC_PROT_LIB_NO_DATA) {
return MBEDTLS_ERR_SSL_WANT_READ;
}
tls_sec_prot_lib_random_extract(sec, buf, len);
return ret;
}
static void tls_sec_prot_lib_random_extract(tls_security_t *sec, const uint8_t *buf, uint16_t len)
{
if (sec->step == 0) {
if (*buf++ != 22 && len < 5) {
return;
}
buf++; // version
buf++;
buf++; // length
buf++;
sec->step++;
if (len < 6) {
return;
}
}
if (sec->step == 1) {
uint8_t *random_ptr;
if (*buf == 0x01) { // Client hello
random_ptr = sec->client_random;
} else if (*buf == 0x02) { // Server hello
random_ptr = sec->server_random;
} else {
return;
}
buf++;
buf++; // length
buf++;
buf++;
buf++; // version
buf++;
memcpy(random_ptr, buf, 32);
sec->step = 0;
}
}
static int tls_sec_prot_lib_ssl_export_keys(void *ctx, const unsigned char *ms,
const unsigned char *kb, size_t maclen,
size_t keylen, size_t ivlen)
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *ms,
const unsigned char *kb, size_t maclen, size_t keylen,
size_t ivlen, unsigned char client_random[32],
unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type)
{
(void) kb;
(void) maclen;
(void) keylen;
(void) ivlen;
tls_security_t *sec = (tls_security_t *)ctx;
tls_security_t *sec = (tls_security_t *)p_expkey;
uint8_t eap_tls_key_material[128];
uint8_t random[64];
memcpy(random, sec->client_random, 32);
memcpy(&random[32], sec->server_random, 32);
memcpy(random, client_random, 32);
memcpy(&random[32], server_random, 32);
sec->ssl.handshake->tls_prf(ms, 48, "client EAP encryption",
int ret = mbedtls_ssl_tls_prf(tls_prf_type, ms, 48, "client EAP encryption",
random, 64, eap_tls_key_material, 128);
if (ret != 0) {
tr_error("key material PRF error");
return 0;
}
sec->export_keys(sec->handle, ms, eap_tls_key_material);
return 0;
}

View File

@ -969,7 +969,7 @@ void ipv6_interface_slaac_handler(protocol_interface_info_entry_t *cur, const ui
cur->ipv6_configure->IPv6_ND_state = IPV6_GP_CONFIG;
}
// If DAD not enabled address is valid right away
if (cur->dup_addr_detect_transmits == 0) {
if (cur->ipv6_configure && cur->dup_addr_detect_transmits == 0) {
address_entry->cb(cur, address_entry, ADDR_CALLBACK_DAD_COMPLETE);
}
}