mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '396dae52ab4eef15910011432f2c7a4261fc22b7'
* commit '396dae52ab4eef15910011432f2c7a4261fc22b7': Squashed 'features/nanostack/sal-stack-nanostack/' changes from 4a19dc4..c473148pull/11423/head
commit
4ebbbc592d
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -73,10 +74,23 @@ typedef struct asynch_request_s {
|
|||
* @brief LLC neighbour info request parameters
|
||||
*/
|
||||
typedef struct llc_neighbour_req {
|
||||
struct mac_neighbor_table_entry *neighbor; /**< Generic Link Layer Neighbor information entry. */
|
||||
struct ws_neighbor_class_entry *ws_neighbor; /**< Wi-sun Neighbor information entry. */
|
||||
struct mac_neighbor_table_entry *neighbor; /**< Generic Link Layer Neighbor information entry. */
|
||||
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_ */
|
||||
|
|
|
@ -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,22 +582,20 @@ 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->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);
|
||||
} else if (ws_utt.message_type == WS_FT_EAPOL) {
|
||||
ws_bootstrap_eapol_parent_synch(interface, &neighbor_info);
|
||||
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);
|
||||
} else if (ws_utt.message_type == WS_FT_EAPOL) {
|
||||
ws_bootstrap_eapol_parent_synch(interface, &neighbor_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 (data->Key.SecurityLevel) {
|
||||
//SET trusted state
|
||||
mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), neighbor_info.neighbor, true);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef NS_LIST_HEAD(kmp_entry_t, link) kmp_list_t;
|
|||
|
||||
typedef struct {
|
||||
kmp_list_t kmp_list; /**< Ongoing KMP negotiations */
|
||||
kmp_addr_t addr; /**< EUI-64 (Relay IP address, Relay port) */
|
||||
kmp_addr_t addr; /**< EUI-64 (Relay IP address, Relay port) */
|
||||
sec_prot_keys_t sec_keys; /**< Security keys */
|
||||
uint32_t ticks; /**< Ticks */
|
||||
uint16_t retry_ticks; /**< Retry ticks */
|
||||
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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,15 +471,21 @@ 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,74 +400,34 @@ 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",
|
||||
random, 64, eap_tls_key_material, 128);
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue