mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '856da9bd60f3409f55b21d8951bb3cc010668396' into feature-wisun
* commit '856da9bd60f3409f55b21d8951bb3cc010668396': Squashed 'features/nanostack/sal-stack-nanostack/' changes from 91f3ff6d7f..25b9124cd2pull/14327/head
commit
3bb13c2405
|
@ -99,6 +99,7 @@ int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
|
|||
#define BBR_REQUIRE_DAO_REFRESH 0x0000 /**< Deprecated DAO Refresh is now the default functionality*/
|
||||
#define BBR_PERIODIC_VERSION_INC 0x0010 /**< Increment PAN version number Periodically*/
|
||||
#define BBR_GUA_SLAAC 0x0020 /**< in Global prefix use SLAAC address generation to reduce traffic during bootstrap */
|
||||
#define BBR_DHCP_ANONYMOUS 0x0040 /**< Generate anonymous addresses from DHCP server */
|
||||
|
||||
/**
|
||||
* Configure border router features.
|
||||
|
@ -108,6 +109,9 @@ int ws_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
|
|||
* BBR_ULA_C Configure Mesh local ULA prefix with SLAAC address
|
||||
* BBR_GUA_ROUTE Add more specific route for GUA
|
||||
* BBR_BB_WAIT Start Wi-SUN network only when backbone is ready
|
||||
* BBR_DHCP_ANONYMOUS if true give anonymous address (16 bit suffix) to
|
||||
* optimize data in RF interface (saves 12 bytes per hop)
|
||||
* or false to reduce RAM usage in Border router as assigned address list is not needed (40 bytes per device).
|
||||
*
|
||||
* By default Wi-SUN network is started and is treated as separate interface even if backbone is not available.
|
||||
*
|
||||
|
|
|
@ -95,6 +95,30 @@ extern "C" {
|
|||
*/
|
||||
#define WS_MANAGEMENT_API_VER_2 /**< Management API version */
|
||||
|
||||
/**
|
||||
* Deprecated!
|
||||
* Configure PHY mode ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param phy_mode_id PHY mode ID. Default 255 (not used).
|
||||
*
|
||||
* \return 0, Init OK.
|
||||
* \return <0 Init fail.
|
||||
*/
|
||||
#define ws_management_phy_mode_id_set(interface_id, phy_mode_id) ws_management_domain_configuration_set(interface_id, 0, phy_mode_id, 0)
|
||||
|
||||
/**
|
||||
* Deprecated!
|
||||
* Configure Channel plan ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param channel_plan_id Channel plan ID. Default 255 (not used).
|
||||
*
|
||||
* \return 0, Init OK.
|
||||
* \return <0 Init fail.
|
||||
*/
|
||||
#define ws_management_channel_plan_id_set(interface_id, channel_plan_id) ws_management_domain_configuration_set(interface_id, 0, 0, channel_plan_id)
|
||||
|
||||
/**
|
||||
* \brief Struct ws_statistics defines the Wi-SUN statistics storage structure.
|
||||
*/
|
||||
|
@ -187,80 +211,107 @@ int ws_management_network_name_validate(
|
|||
char *network_name_ptr);
|
||||
|
||||
/**
|
||||
* Configure PHY mode ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
|
||||
* Set domain configuration of Wi-SUN stack.
|
||||
*
|
||||
* Change the default configuration for Wi-SUN PHY operation.
|
||||
*
|
||||
* Supported values:
|
||||
* FSK without FEC:
|
||||
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
|
||||
* 1 50 0.5
|
||||
* 2 50 1.0
|
||||
* 3 100 0.5
|
||||
* 4 100 1.0
|
||||
* 5 150 0.5
|
||||
* 6 200 0.5
|
||||
* 7 200 1.0
|
||||
* 8 300 0.5
|
||||
* Regulatory domain: "NA"(0x01), "KR"(0x09), "EU"(0x03), "IN"(0x05), "BZ"(0x07), "JP"(0x09), "WW"(0x00)
|
||||
*
|
||||
* FSK with FEC:
|
||||
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
|
||||
* 17 50 0.5
|
||||
* 18 50 1.0
|
||||
* 19 100 0.5
|
||||
* 20 100 1.0
|
||||
* 21 150 0.5
|
||||
* 22 200 0.5
|
||||
* 23 200 1.0
|
||||
* 24 300 0.5
|
||||
* PHY mode ID:
|
||||
* FSK without FEC:
|
||||
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
|
||||
* 1 50 0.5
|
||||
* 2 50 1.0
|
||||
* 3 100 0.5
|
||||
* 4 100 1.0
|
||||
* 5 150 0.5
|
||||
* 6 200 0.5
|
||||
* 7 200 1.0
|
||||
* 8 300 0.5
|
||||
*
|
||||
* OFDM:
|
||||
* PHY mode ID | Option | MCS | Data rate (kbps)
|
||||
* 34 1 2 400
|
||||
* 35 1 3 800
|
||||
* 36 1 4 1200
|
||||
* 37 1 5 1600
|
||||
* 38 1 6 2400
|
||||
* 51 2 3 400
|
||||
* 52 2 4 600
|
||||
* 53 2 5 800
|
||||
* 54 2 6 1200
|
||||
* 68 3 4 300
|
||||
* 69 3 5 400
|
||||
* 70 3 6 600
|
||||
* 84 4 4 150
|
||||
* 85 4 5 200
|
||||
* 86 4 6 300
|
||||
* FSK with FEC:
|
||||
* PHY mode ID | Symbol Rate (kbps) | Modulation Index
|
||||
* 17 50 0.5
|
||||
* 18 50 1.0
|
||||
* 19 100 0.5
|
||||
* 20 100 1.0
|
||||
* 21 150 0.5
|
||||
* 22 200 0.5
|
||||
* 23 200 1.0
|
||||
* 24 300 0.5
|
||||
*
|
||||
* if value of 255 is given then previous value is used.
|
||||
* OFDM:
|
||||
* PHY mode ID | Option | MCS | Data rate (kbps)
|
||||
* 34 1 2 400
|
||||
* 35 1 3 800
|
||||
* 36 1 4 1200
|
||||
* 37 1 5 1600
|
||||
* 38 1 6 2400
|
||||
* 51 2 3 400
|
||||
* 52 2 4 600
|
||||
* 53 2 5 800
|
||||
* 54 2 6 1200
|
||||
* 68 3 4 300
|
||||
* 69 3 5 400
|
||||
* 70 3 6 600
|
||||
* 84 4 4 150
|
||||
* 85 4 5 200
|
||||
* 86 4 6 300
|
||||
*
|
||||
* Channel plan ID:
|
||||
* North America (NA): (1), (2), (5)
|
||||
* Brazil (BZ): (1), (2), (5)
|
||||
*
|
||||
* If value of 0 is given then previous value is used.
|
||||
* If value of 255 is given then default value is used.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param phy_mode_id PHY mode ID. Default 255 (not used).
|
||||
* \param regulatory_domain Regulatory domain.
|
||||
* \param phy_mode_id PHY mode ID.
|
||||
* \param channel_plan_id Channel plan ID.
|
||||
*
|
||||
* \return 0, Init OK.
|
||||
* \return <0 Init fail.
|
||||
* \return 0, OK.
|
||||
* \return <0 Fail.
|
||||
*/
|
||||
int ws_management_phy_mode_id_set(
|
||||
int ws_management_domain_configuration_set(
|
||||
int8_t interface_id,
|
||||
uint8_t phy_mode_id);
|
||||
uint8_t regulatory_domain,
|
||||
uint8_t phy_mode_id,
|
||||
uint8_t channel_plan_id);
|
||||
|
||||
/**
|
||||
* Configure Channel plan ID of Wi-SUN stack as defined by Wi-SUN FAN 1.1.
|
||||
*
|
||||
* Change the default channel configuration for Wi-SUN.
|
||||
*
|
||||
* Supported values: TBD
|
||||
*
|
||||
* if value of 255 is given then previous value is used.
|
||||
* Get domain configuration of Wi-SUN stack.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param channel_plan_id Channel plan ID. Default 255 (not used).
|
||||
* \param regulatory_domain Regulatory domain.
|
||||
* \param phy_mode_id PHY mode ID.
|
||||
* \param channel_plan_id Channel plan ID.
|
||||
*
|
||||
* \return 0, Init OK.
|
||||
* \return <0 Init fail.
|
||||
* \return 0, OK.
|
||||
* \return <0 Fail.
|
||||
*/
|
||||
int ws_management_channel_plan_id_set(
|
||||
int ws_management_domain_configuration_get(
|
||||
int8_t interface_id,
|
||||
uint8_t *regulatory_domain,
|
||||
uint8_t *phy_mode_id,
|
||||
uint8_t *channel_plan_id);
|
||||
|
||||
/**
|
||||
* Validate domain configuration of Wi-SUN stack.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param regulatory_domain Regulatory domain.
|
||||
* \param phy_mode_id PHY mode ID.
|
||||
* \param channel_plan_id Channel plan ID.
|
||||
*
|
||||
* \return 0, OK.
|
||||
* \return <0 Fail.
|
||||
*/
|
||||
int ws_management_domain_configuration_validate(
|
||||
int8_t interface_id,
|
||||
uint8_t regulatory_domain,
|
||||
uint8_t phy_mode_id,
|
||||
uint8_t channel_plan_id);
|
||||
|
||||
/**
|
||||
|
|
|
@ -2184,7 +2184,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, NULL, cur);
|
||||
rpl_control_set_callback(protocol_6lowpan_rpl_domain, protocol_6lowpan_bootstrap_rpl_callback, NULL, NULL, NULL, cur);
|
||||
}
|
||||
// Send unicast DIS to coordinator
|
||||
nwk_bootstrap_icmp_rpl_dis_coord_msg_tx(cur);
|
||||
|
|
|
@ -699,7 +699,7 @@ int thread_dhcpv6_server_set_anonymous_addressing(int8_t interface_id, uint8_t *
|
|||
return -1;
|
||||
}
|
||||
|
||||
return DHCPv6_server_service_set_address_autonous_flag(interface_id, prefix_ptr, anonymous, false);
|
||||
return DHCPv6_server_service_set_address_generation_anonymous(interface_id, prefix_ptr, anonymous, false);
|
||||
#else
|
||||
(void) interface_id;
|
||||
(void) prefix_ptr;
|
||||
|
|
|
@ -197,7 +197,7 @@ static void ws_bbr_rpl_version_increase(protocol_interface_info_entry_t *cur)
|
|||
ws_bbr_rpl_version_timer_start(cur, rpl_control_increment_dodag_version(protocol_6lowpan_rpl_root_dodag));
|
||||
}
|
||||
|
||||
void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase)
|
||||
void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase, uint32_t lifetime)
|
||||
{
|
||||
if (imin == 0 || doubling == 0) {
|
||||
// use default values
|
||||
|
@ -205,12 +205,33 @@ void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8
|
|||
doubling = WS_RPL_DIO_DOUBLING_SMALL;
|
||||
redundancy = WS_RPL_DIO_REDUNDANCY_SMALL;
|
||||
}
|
||||
uint8_t lifetime_unit = 60;
|
||||
uint8_t default_lifetime;
|
||||
|
||||
if (lifetime == 0) {
|
||||
// 2 hours default lifetime
|
||||
lifetime = 120 * 60;
|
||||
} else if (lifetime <= 250 * 60) {
|
||||
// Lifetime unit of 60 is ok up to 4 hours
|
||||
} else if (lifetime <= 250 * 120) {
|
||||
//more than 4 hours needs larger lifetime unit
|
||||
lifetime_unit = 120;
|
||||
} else if (lifetime <= 250 * 240) {
|
||||
lifetime_unit = 240;
|
||||
} else {
|
||||
// Maximum lifetime is 16 hours 40 minutes
|
||||
lifetime = 250 * 240;
|
||||
lifetime_unit = 240;
|
||||
}
|
||||
default_lifetime = lifetime / lifetime_unit;
|
||||
|
||||
if (rpl_conf.dio_interval_min == imin &&
|
||||
rpl_conf.dio_interval_doublings == doubling &&
|
||||
rpl_conf.dio_redundancy_constant == redundancy &&
|
||||
rpl_conf.dag_max_rank_increase == dag_max_rank_increase &&
|
||||
rpl_conf.min_hop_rank_increase == min_hop_rank_increase) {
|
||||
rpl_conf.min_hop_rank_increase == min_hop_rank_increase &&
|
||||
rpl_conf.default_lifetime == default_lifetime &&
|
||||
rpl_conf.lifetime_unit == lifetime_unit) {
|
||||
// Same values no update needed
|
||||
return;
|
||||
}
|
||||
|
@ -220,6 +241,8 @@ void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8
|
|||
rpl_conf.dio_redundancy_constant = redundancy;
|
||||
rpl_conf.dag_max_rank_increase = dag_max_rank_increase;
|
||||
rpl_conf.min_hop_rank_increase = min_hop_rank_increase;
|
||||
rpl_conf.default_lifetime = default_lifetime;
|
||||
rpl_conf.lifetime_unit = lifetime_unit;
|
||||
|
||||
if (protocol_6lowpan_rpl_root_dodag) {
|
||||
rpl_control_update_dodag_config(protocol_6lowpan_rpl_root_dodag, &rpl_conf);
|
||||
|
@ -343,6 +366,34 @@ static void ws_bbr_slaac_remove(protocol_interface_info_entry_t *cur, uint8_t *u
|
|||
addr_policy_table_delete_entry(ula_prefix, 64);
|
||||
}
|
||||
|
||||
/*
|
||||
* 0 static non rooted self generated own address
|
||||
* 1 static address with backbone connectivity
|
||||
*/
|
||||
static uint8_t *ws_bbr_bb_static_prefix_get(uint8_t *dodag_id_ptr)
|
||||
{
|
||||
|
||||
/* Get static ULA prefix if we have configuration in backbone and there is address we use that.
|
||||
*
|
||||
* If there is no address we can use our own generated ULA as a backup ULA
|
||||
*/
|
||||
|
||||
protocol_interface_info_entry_t *bb_interface = protocol_stack_interface_info_get_by_id(backbone_interface_id);
|
||||
|
||||
if (bb_interface && bb_interface->ipv6_configure->ipv6_stack_mode == NET_IPV6_BOOTSTRAP_STATIC) {
|
||||
ns_list_foreach(if_address_entry_t, addr, &bb_interface->ip_addresses) {
|
||||
if (bitsequal(addr->address, bb_interface->ipv6_configure->static_prefix64, 64)) {
|
||||
// static address available in interface copy the prefix and return the address
|
||||
if (dodag_id_ptr) {
|
||||
memcpy(dodag_id_ptr, bb_interface->ipv6_configure->static_prefix64, 8);
|
||||
}
|
||||
return addr->address;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int ws_bbr_static_dodagid_create(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
|
@ -350,6 +401,14 @@ static int ws_bbr_static_dodagid_create(protocol_interface_info_entry_t *cur)
|
|||
// address generated
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *static_address_ptr = ws_bbr_bb_static_prefix_get(NULL);
|
||||
if (static_address_ptr) {
|
||||
memcpy(current_dodag_id, static_address_ptr, 16);
|
||||
tr_info("BBR Static DODAGID %s", trace_ipv6(current_dodag_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This address is only used if no other address available.
|
||||
if_address_entry_t *add_entry = ws_bbr_slaac_generate(cur, static_dodag_id_prefix);
|
||||
if (!add_entry) {
|
||||
|
@ -362,29 +421,6 @@ static int ws_bbr_static_dodagid_create(protocol_interface_info_entry_t *cur)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0 static non rooted self generated own address
|
||||
* 1 static address with backbone connectivity
|
||||
*/
|
||||
static void ws_bbr_bb_static_prefix_get(uint8_t *dodag_id_ptr)
|
||||
{
|
||||
|
||||
/* Get static ULA prefix if we have configuration in backbone and there is address we use that.
|
||||
*
|
||||
* If there is no address we can use our own generated ULA as a backup ULA
|
||||
*/
|
||||
|
||||
protocol_interface_info_entry_t *bb_interface = protocol_stack_interface_info_get_by_id(backbone_interface_id);
|
||||
|
||||
if (bb_interface && bb_interface->ipv6_configure->ipv6_stack_mode == NET_IPV6_BOOTSTRAP_STATIC) {
|
||||
if (protocol_address_prefix_cmp(bb_interface, bb_interface->ipv6_configure->static_prefix64, 64)) {
|
||||
memcpy(dodag_id_ptr, bb_interface->ipv6_configure->static_prefix64, 8);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void ws_bbr_dodag_get(uint8_t *local_prefix_ptr, uint8_t *global_prefix_ptr)
|
||||
{
|
||||
uint8_t global_address[16];
|
||||
|
@ -500,8 +536,10 @@ static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8
|
|||
return;
|
||||
}
|
||||
DHCPv6_server_service_callback_set(cur->id, global_id, NULL, wisun_dhcp_address_add_cb);
|
||||
//Enable SLAAC mode to border router
|
||||
DHCPv6_server_service_set_address_autonous_flag(cur->id, global_id, true, false);
|
||||
//Check for anonymous mode
|
||||
bool anonymous = (configuration & BBR_DHCP_ANONYMOUS) ? true : false;
|
||||
|
||||
DHCPv6_server_service_set_address_generation_anonymous(cur->id, global_id, anonymous, false);
|
||||
DHCPv6_server_service_set_address_validlifetime(cur->id, global_id, dhcp_address_lifetime);
|
||||
//SEt max value for not limiting address allocation
|
||||
DHCPv6_server_service_set_max_clients_accepts_count(cur->id, global_id, MAX_SUPPORTED_ADDRESS_LIST_SIZE);
|
||||
|
@ -510,6 +548,7 @@ static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8
|
|||
|
||||
ws_dhcp_client_address_request(cur, global_id, ll);
|
||||
}
|
||||
|
||||
static void ws_bbr_dhcp_server_stop(protocol_interface_info_entry_t *cur, uint8_t *global_id)
|
||||
{
|
||||
if (!cur) {
|
||||
|
@ -626,9 +665,16 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
|
|||
*/
|
||||
if ((configuration & BBR_ULA_C) == 0 && memcmp(global_prefix, ADDR_UNSPECIFIED, 8) == 0) {
|
||||
//Global prefix not available count if backup ULA should be created
|
||||
uint32_t prefix_wait_time = BBR_BACKUP_ULA_DELAY;
|
||||
global_prefix_unavailable_timer += BBR_CHECK_INTERVAL;
|
||||
tr_debug("Check for backup prefix %"PRIu32"", global_prefix_unavailable_timer);
|
||||
if (global_prefix_unavailable_timer >= BBR_BACKUP_ULA_DELAY) {
|
||||
|
||||
if (NULL != ws_bbr_bb_static_prefix_get(NULL)) {
|
||||
// If we have a static configuration we activate it faster.
|
||||
prefix_wait_time = 40;
|
||||
}
|
||||
|
||||
tr_debug("Check for backup prefix %"PRIu32" / %"PRIu32"", prefix_wait_time, global_prefix_unavailable_timer);
|
||||
if (global_prefix_unavailable_timer >= prefix_wait_time) {
|
||||
if (memcmp(current_global_prefix, ADDR_UNSPECIFIED, 8) == 0) {
|
||||
tr_info("start using backup prefix %s", trace_ipv6_prefix(local_prefix, 64));
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur);
|
|||
|
||||
uint16_t ws_bbr_pan_size(protocol_interface_info_entry_t *cur);
|
||||
|
||||
void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase);
|
||||
void ws_bbr_rpl_config(protocol_interface_info_entry_t *cur, uint8_t imin, uint8_t doubling, uint8_t redundancy, uint16_t dag_max_rank_increase, uint16_t min_hop_rank_increase, uint32_t lifetime);
|
||||
|
||||
void ws_bbr_dhcp_address_lifetime_set(protocol_interface_info_entry_t *cur, uint32_t dhcp_address_lifetime);
|
||||
|
||||
|
@ -45,7 +45,7 @@ void ws_bbr_init(protocol_interface_info_entry_t *interface);
|
|||
#define ws_bbr_seconds_timer( cur, seconds)
|
||||
#define ws_bbr_pan_version_increase(cur)
|
||||
#define ws_bbr_pan_size(cur) 0
|
||||
#define ws_bbr_rpl_config( cur, imin, doubling, redundancy, dag_max_rank_increase, min_hop_rank_increase)
|
||||
#define ws_bbr_rpl_config( cur, imin, doubling, redundancy, dag_max_rank_increase, min_hop_rank_increase, lifetime)
|
||||
#define ws_bbr_dhcp_address_lifetime_set(cur, dhcp_address_lifetime)
|
||||
#define ws_bbr_ready_to_start(cur) true
|
||||
#define ws_bbr_backbone_address_get(address) 0
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "mac_common_defines.h"
|
||||
#include "sw_mac.h"
|
||||
#include "ccmLIB.h"
|
||||
#include "Core/include/ns_monitor.h"
|
||||
#include "NWK_INTERFACE/Include/protocol.h"
|
||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
|
||||
#include "6LoWPAN/Bootstraps/protocol_6lowpan_interface.h"
|
||||
|
@ -103,6 +104,7 @@ static void ws_bootstrap_nw_frame_counter_read(protocol_interface_info_entry_t *
|
|||
static void ws_bootstrap_nw_info_updated(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, uint16_t pan_version, char *network_name);
|
||||
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, auth_result_e result, uint8_t *target_eui_64);
|
||||
static const uint8_t *ws_bootstrap_authentication_next_target(protocol_interface_info_entry_t *cur, const uint8_t *previous_eui_64, uint16_t *pan_id);
|
||||
static bool ws_bootstrap_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp);
|
||||
static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur);
|
||||
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);
|
||||
|
@ -110,6 +112,7 @@ static bool ws_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr,
|
|||
|
||||
static void ws_address_registration_update(protocol_interface_info_entry_t *interface, const uint8_t addr[16]);
|
||||
static int8_t ws_bootstrap_neighbor_set(protocol_interface_info_entry_t *cur, parent_info_t *parent_ptr, bool clear_list);
|
||||
static void ws_bootstrap_parent_confirm(protocol_interface_info_entry_t *cur, struct rpl_instance *instance);
|
||||
|
||||
static void ws_bootstrap_candidate_table_reset(protocol_interface_info_entry_t *cur);
|
||||
static parent_info_t *ws_bootstrap_candidate_parent_get(struct protocol_interface_info_entry *cur, const uint8_t *addr, bool create);
|
||||
|
@ -118,6 +121,7 @@ static void ws_bootstrap_packet_congestion_init(protocol_interface_info_entry_t
|
|||
|
||||
static void ws_bootstrap_asynch_trickle_stop(protocol_interface_info_entry_t *cur);
|
||||
static void ws_bootstrap_advertise_start(protocol_interface_info_entry_t *cur);
|
||||
static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur);
|
||||
|
||||
typedef enum {
|
||||
WS_PARENT_SOFT_SYNCH = 0, /**< let FHSS make decision if synchronization is needed*/
|
||||
|
@ -1010,6 +1014,30 @@ static void ws_bootstrap_dhcp_info_notify_cb(int8_t interface, dhcp_option_notif
|
|||
|
||||
}
|
||||
|
||||
static void ws_bootstrap_memory_configuration()
|
||||
{
|
||||
/* Configure memory limits for garbage collection based on total memory size
|
||||
* Starting from these values
|
||||
* 5% for High mark
|
||||
* 2% for critical mark
|
||||
* 1% for Routing limit
|
||||
* Memory High Critical Drop routing
|
||||
* 32K RAM 3200 bytes 1280 Bytes 1024 bytes
|
||||
* 64K RAM 3200 bytes 1280 Bytes 1024 bytes
|
||||
* 128K RAM 6400 bytes 2560 Bytes 1280 bytes
|
||||
* 320K RAM 16000 byte 6400 Bytes 3200 bytes
|
||||
* 640K RAM 32000 byte 12800 Bytes 6400 bytes
|
||||
* 1000K RAM 50000 bytes 20000 Bytes 10000 bytes
|
||||
* 4000K RAM 120000 bytes 40000 Bytes 10000 bytes
|
||||
* */
|
||||
// In small memory devices there needs to lower limit so that there some change to be usable
|
||||
// and there is no use for having very large values on high memory devices
|
||||
ns_monitor_packet_ingress_rate_limit_by_memory(1024, 10000, 1);
|
||||
|
||||
ns_monitor_heap_gc_threshold_set(3200, 120000, 95, 1280, 40000, 98);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
|
@ -1066,7 +1094,8 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
|
|||
dhcp_client_solicit_timeout_set(cur->id, WS_DHCP_SOLICIT_TIMEOUT, WS_DHCP_SOLICIT_MAX_RT, WS_DHCP_SOLICIT_MAX_RC);
|
||||
dhcp_client_option_notification_cb_set(cur->id, ws_bootstrap_dhcp_info_notify_cb);
|
||||
|
||||
|
||||
// Configure memory limits and garbage collection values;
|
||||
ws_bootstrap_memory_configuration();
|
||||
ws_nud_table_reset(cur);
|
||||
|
||||
ws_bootstrap_candidate_table_reset(cur);
|
||||
|
@ -1590,6 +1619,13 @@ static void ws_bootstrap_pan_advertisement_solicit_analyse(struct protocol_inter
|
|||
|
||||
tr_info("Making parent selection in %u s", (cur->bootsrap_state_machine_cnt / 10));
|
||||
}
|
||||
|
||||
if (ws_bootstrap_state_active(cur) && cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), data->SrcAddr, ADDR_802_15_4_LONG);
|
||||
if (neighbor && neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
|
||||
ws_bootstrap_parent_confirm(cur, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1732,7 +1768,7 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
|
|||
// restart PAN version timer
|
||||
//Check Here Do we have a selected Primary parent
|
||||
if (!cur->ws_info->configuration_learned || cur->ws_info->rpl_state == RPL_EVENT_DAO_DONE) {
|
||||
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
|
||||
ws_common_border_router_alive_update(cur);
|
||||
}
|
||||
|
||||
cur->ws_info->pan_information.pan_version = pan_version;
|
||||
|
@ -1776,7 +1812,12 @@ static void ws_bootstrap_pan_config_solicit_analyse(struct protocol_interface_in
|
|||
ws_neighbor_class_neighbor_unicast_schedule_set(neighbor_info.ws_neighbor, ws_us, &cur->ws_info->hopping_schdule);
|
||||
}
|
||||
|
||||
|
||||
if (ws_bootstrap_state_active(cur) && cur->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), data->SrcAddr, ADDR_802_15_4_LONG);
|
||||
if (neighbor && neighbor->link_role == PRIORITY_PARENT_NEIGHBOUR) {
|
||||
ws_bootstrap_parent_confirm(cur, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A consistent transmission is defined as a PAN Configuration Solicit with
|
||||
|
@ -2290,11 +2331,11 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
|
|||
ret_val = -4;
|
||||
goto init_fail;
|
||||
}
|
||||
if (ws_pae_controller_cb_register(cur, &ws_bootstrap_authentication_completed, &ws_bootstrap_authentication_next_target, &ws_bootstrap_nw_key_set, &ws_bootstrap_nw_key_clear, &ws_bootstrap_nw_key_index_set, &ws_bootstrap_nw_frame_counter_set, &ws_bootstrap_nw_frame_counter_read, &ws_bootstrap_pan_version_increment, &ws_bootstrap_nw_info_updated) < 0) {
|
||||
if (ws_pae_controller_cb_register(cur, &ws_bootstrap_authentication_completed, &ws_bootstrap_authentication_next_target, &ws_bootstrap_nw_key_set, &ws_bootstrap_nw_key_clear, &ws_bootstrap_nw_key_index_set, &ws_bootstrap_nw_frame_counter_set, &ws_bootstrap_nw_frame_counter_read, &ws_bootstrap_pan_version_increment, &ws_bootstrap_nw_info_updated, &ws_bootstrap_congestion_get) < 0) {
|
||||
ret_val = -4;
|
||||
goto init_fail;
|
||||
}
|
||||
if (ws_pae_controller_configure(cur, &cur->ws_info->cfg->sec_timer, &cur->ws_info->cfg->sec_prot) < 0) {
|
||||
if (ws_pae_controller_configure(cur, &cur->ws_info->cfg->sec_timer, &cur->ws_info->cfg->sec_prot, &cur->ws_info->cfg->timing) < 0) {
|
||||
ret_val = -4;
|
||||
goto init_fail;
|
||||
}
|
||||
|
@ -2310,6 +2351,8 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
|
|||
goto init_fail;
|
||||
}
|
||||
|
||||
cur->ipv6_neighbour_cache.link_mtu = cur->max_link_mtu = WS_MPX_MAX_MTU;
|
||||
|
||||
cur->if_up = ws_bootstrap_up;
|
||||
cur->if_down = ws_bootstrap_down;
|
||||
cur->ws_info->neighbor_storage = neigh_info;
|
||||
|
@ -2576,6 +2619,63 @@ static void ws_address_parent_update(protocol_interface_info_entry_t *interface)
|
|||
ws_address_registration_update(interface, NULL);
|
||||
}
|
||||
|
||||
static void ws_bootstrap_parent_confirm(protocol_interface_info_entry_t *cur, struct rpl_instance *instance)
|
||||
{
|
||||
/* Possible problem with the parent connection
|
||||
* Give some time for parent to rejoin and confirm the connection with ARO and DAO
|
||||
*/
|
||||
const rpl_dodag_conf_t *config = NULL;
|
||||
uint32_t Imin_secs = 0;
|
||||
|
||||
if (!ws_bootstrap_state_active(cur)) {
|
||||
// If we are not in Active state no need to confirm parent
|
||||
return;
|
||||
}
|
||||
|
||||
tr_info("RPL parent confirm");
|
||||
|
||||
if (!instance) {
|
||||
// If we dont have instance we take any available to get reference
|
||||
instance = rpl_control_enumerate_instances(cur->rpl_domain, NULL);
|
||||
}
|
||||
|
||||
if (instance) {
|
||||
config = rpl_control_get_dodag_config(instance);
|
||||
}
|
||||
|
||||
if (config) {
|
||||
//dio imin Period caluclate in seconds
|
||||
uint32_t Imin_ms = config->dio_interval_min < 32 ? (1ul << config->dio_interval_min) : 0xfffffffful;
|
||||
//Covert to seconds and multiple by 2 so we give time to recovery so divide by 500 do that operation
|
||||
Imin_secs = (Imin_ms + 499) / 500;
|
||||
|
||||
if (Imin_secs > 0xffff) {
|
||||
Imin_secs = 0xffff;
|
||||
}
|
||||
}
|
||||
if (Imin_secs == 0) {
|
||||
// If we dont have RPL configuration we assume conservative value
|
||||
Imin_secs = 60;
|
||||
}
|
||||
|
||||
/*Speed up the ARO registration*/
|
||||
if (cur->ws_info->aro_registration_timer > Imin_secs) {
|
||||
cur->ws_info->aro_registration_timer = Imin_secs;
|
||||
}
|
||||
}
|
||||
|
||||
static void ws_rpl_parent_dis_callback(const uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance)
|
||||
{
|
||||
(void) ll_parent_address;
|
||||
protocol_interface_info_entry_t *cur = handle;
|
||||
if (!cur->rpl_domain || cur->interface_mode != INTERFACE_UP) {
|
||||
return;
|
||||
}
|
||||
//Multicast DIS from parent indicate that Parent is not valid in short time window possible
|
||||
ws_bootstrap_parent_confirm(cur, instance);
|
||||
}
|
||||
|
||||
|
||||
static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
|
||||
{
|
||||
|
||||
|
@ -2619,9 +2719,7 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
|
|||
}
|
||||
|
||||
// After successful DAO ACK connection to border router is verified
|
||||
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
|
||||
|
||||
|
||||
ws_common_border_router_alive_update(cur);
|
||||
}
|
||||
|
||||
if (!cur->ws_info->trickle_pa_running || !cur->ws_info->trickle_pc_running) {
|
||||
|
@ -2643,10 +2741,14 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle)
|
|||
|
||||
} else if (event == RPL_EVENT_LOCAL_REPAIR_START) {
|
||||
tr_debug("RPL local repair start");
|
||||
//Disable Asynchs
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
ws_nwk_event_post(cur, ARM_NWK_NWK_CONNECTION_DOWN);
|
||||
|
||||
//Disable Async and go to state 4 to confirm parent connection
|
||||
ws_bootstrap_parent_confirm(cur, NULL);
|
||||
// Move to state 4 if we see issues with primary parent
|
||||
if (ws_bootstrap_state_active(cur)) {
|
||||
tr_info("Move state 4 to wait parent connection confirmation");
|
||||
ws_bootstrap_rpl_scan_start(cur);
|
||||
ws_nwk_event_post(cur, ARM_NWK_NWK_CONNECTION_DOWN);
|
||||
}
|
||||
} else if (event == RPL_EVENT_DAO_PARENT_ADD) {
|
||||
ws_address_parent_update(cur);
|
||||
}
|
||||
|
@ -2861,7 +2963,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, ws_rpl_new_parent_callback, cur);
|
||||
rpl_control_set_callback(protocol_6lowpan_rpl_domain, ws_bootstrap_rpl_callback, ws_rpl_prefix_callback, ws_rpl_new_parent_callback, ws_rpl_parent_dis_callback, cur);
|
||||
// If i am router I Do this
|
||||
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, leaf);
|
||||
rpl_control_process_routes(protocol_6lowpan_rpl_domain, false); // Wi-SUN assumes that no default route needed
|
||||
|
@ -3070,7 +3172,7 @@ static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_
|
|||
if (result == AUTH_RESULT_OK) {
|
||||
tr_debug("authentication success");
|
||||
ws_bootstrap_event_configuration_start(cur);
|
||||
} else if (result == AUTH_RESULT_ERR_TX_NO_ACK) {
|
||||
} else if (result == AUTH_RESULT_ERR_TX_ERR) {
|
||||
// eapol parent selected is not working
|
||||
tr_debug("authentication TX failed");
|
||||
|
||||
|
@ -3112,6 +3214,70 @@ static const uint8_t *ws_bootstrap_authentication_next_target(protocol_interface
|
|||
return previous_eui_64;
|
||||
}
|
||||
|
||||
static bool ws_bootstrap_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp)
|
||||
{
|
||||
if (interface_ptr == NULL || interface_ptr->random_early_detection == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool return_value = false;
|
||||
static struct red_info_s *red_info = NULL;
|
||||
uint16_t average = 0;
|
||||
uint8_t active_max = 0;
|
||||
|
||||
//TODO implement API for HEAP info request
|
||||
uint32_t heap_size;
|
||||
const mem_stat_t *mem_stats = ns_dyn_mem_get_mem_stat();
|
||||
if (mem_stats) {
|
||||
heap_size = mem_stats->heap_sector_size;
|
||||
} else {
|
||||
heap_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For different memory sizes the max simultaneous authentications will be
|
||||
* 32k: (32k / 50k) * 2 + 1 = 1
|
||||
* 65k: (65k / 50k) * 2 + 1 = 3
|
||||
* 250k: (250k / 50k) * 2 + 1 = 11
|
||||
* 1000k: (1000k / 50k) * 2 + 1 = 41
|
||||
* 2000k: (2000k / 50k) * 2 + 1 = 50 (upper limit)
|
||||
*/
|
||||
active_max = (heap_size / 50000) * 2 + 1;
|
||||
if (active_max > 50) {
|
||||
active_max = 50;
|
||||
}
|
||||
|
||||
// Maximum for active supplicants based on memory reached, fail
|
||||
if (active_supp >= active_max) {
|
||||
return_value = true;
|
||||
goto congestion_get_end;
|
||||
}
|
||||
|
||||
// Always allow at least five negotiations (if memory does not limit)
|
||||
if (active_supp < 5) {
|
||||
goto congestion_get_end;
|
||||
}
|
||||
|
||||
if (red_info == NULL) {
|
||||
red_info = random_early_detection_create(
|
||||
interface_ptr->ws_info->cfg->sec_prot.max_simult_sec_neg_tx_queue_min,
|
||||
interface_ptr->ws_info->cfg->sec_prot.max_simult_sec_neg_tx_queue_max,
|
||||
100, RED_AVERAGE_WEIGHT_DISABLED);
|
||||
}
|
||||
if (red_info == NULL) {
|
||||
goto congestion_get_end;
|
||||
}
|
||||
|
||||
average = random_early_detetction_aq_read(interface_ptr->random_early_detection);
|
||||
average = random_early_detetction_aq_calc(red_info, average);
|
||||
return_value = random_early_detection_congestion_check(red_info);
|
||||
|
||||
congestion_get_end:
|
||||
tr_info("Active supplicant limit, active: %i max: %i averageQ: %i drop: %s", active_supp, active_max, average, return_value ? "T" : "F");
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Start configuration learning
|
||||
static void ws_bootstrap_start_configuration_learn(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
|
@ -3134,18 +3300,18 @@ static void ws_bootstrap_start_configuration_learn(protocol_interface_info_entry
|
|||
static void ws_bootstrap_rpl_scan_start(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
tr_debug("Start RPL learn");
|
||||
// Stop Trickle timers
|
||||
ws_bootstrap_asynch_trickle_stop(cur);
|
||||
|
||||
// routers wait until RPL root is contacted
|
||||
ws_bootstrap_state_change(cur, ER_RPL_SCAN);
|
||||
// Change state as the state is checked in state machine
|
||||
cur->ws_info->rpl_state = RPL_EVENT_LOCAL_REPAIR_START;
|
||||
//For Large network and medium should do passive scan
|
||||
if (ws_cfg_network_config_get(cur) > CONFIG_SMALL) {
|
||||
// Set timeout for check to 30 - 60 seconds
|
||||
cur->bootsrap_state_machine_cnt = randLIB_get_random_in_range(WS_RPL_DIS_INITIAL_TIMEOUT / 2, WS_RPL_DIS_INITIAL_TIMEOUT);
|
||||
}
|
||||
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
|
||||
* Router for an interval of PAN_TIMEOUT, a node MUST assume failure of the PAN Border Router and MUST
|
||||
* Transition to Join State 1
|
||||
*/
|
||||
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3500,6 +3666,11 @@ static void ws_bootstrap_event_handler(arm_event_s *event)
|
|||
ws_bootstrap_event_routing_ready(cur);
|
||||
} else {
|
||||
ws_bootstrap_rpl_scan_start(cur);
|
||||
/* While in Join State 4, if a non Border Router determines it has been unable to communicate with the PAN Border
|
||||
* Router for an interval of PAN_TIMEOUT, a node MUST assume failure of the PAN Border Router and MUST
|
||||
* Transition to Join State 1
|
||||
*/
|
||||
ws_common_border_router_alive_update(cur);
|
||||
}
|
||||
break;
|
||||
case WS_ROUTING_READY:
|
||||
|
|
|
@ -301,6 +301,8 @@ int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_
|
|||
set_function(&nw_size_cfg);
|
||||
}
|
||||
|
||||
uint8_t cfg_network_size = cfg->network_size;
|
||||
|
||||
/* If no longer in an automatic network size mode, frees automatic configuration,
|
||||
so that new configuration is set */
|
||||
if (nw_size_external_cfg && old_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
|
@ -309,7 +311,7 @@ int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_
|
|||
}
|
||||
|
||||
uint8_t set_flags = 0;
|
||||
if (cfg->network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
if (cfg_network_size == NETWORK_SIZE_AUTOMATIC) {
|
||||
set_flags = CFG_FLAGS_DISABLE_VAL_SET;
|
||||
}
|
||||
/* Sets values if changed or network size has been previously automatic (to make sure
|
||||
|
@ -336,7 +338,7 @@ int8_t ws_cfg_network_size_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_
|
|||
}
|
||||
|
||||
// If is in an automatic network size mode, updates automatic configuration
|
||||
if (cfg->network_size == NETWORK_SIZE_AUTOMATIC && cur) {
|
||||
if (cfg_network_size == NETWORK_SIZE_AUTOMATIC && cur) {
|
||||
ws_cfg_network_size_configure(cur, cur->ws_info->pan_information.pan_size);
|
||||
}
|
||||
return CFG_SETTINGS_OK;
|
||||
|
@ -448,6 +450,7 @@ static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg)
|
|||
cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_SMALL; // Disabled
|
||||
cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE;
|
||||
cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE;
|
||||
cfg->bbr.rpl_default_lifetime = WS_RPL_DEFAULT_LIFETIME;
|
||||
cfg->bbr.dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_SMALL;
|
||||
|
||||
// EAPOL configuration
|
||||
|
@ -456,8 +459,6 @@ static void ws_cfg_network_size_config_set_small(ws_cfg_nw_size_t *cfg)
|
|||
cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS;
|
||||
cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL;
|
||||
|
||||
cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL;
|
||||
|
||||
cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER;
|
||||
cfg->sec_prot.initial_key_imin = SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS;
|
||||
cfg->sec_prot.initial_key_imax = SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS;
|
||||
|
@ -492,6 +493,7 @@ static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg)
|
|||
cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_MEDIUM; // 10
|
||||
cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE;
|
||||
cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE;
|
||||
cfg->bbr.rpl_default_lifetime = WS_RPL_DEFAULT_LIFETIME_MEDIUM;
|
||||
cfg->bbr.dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_MEDIUM;
|
||||
|
||||
// EAPOL configuration
|
||||
|
@ -500,8 +502,6 @@ static void ws_cfg_network_size_config_set_medium(ws_cfg_nw_size_t *cfg)
|
|||
cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS;
|
||||
cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL;
|
||||
|
||||
cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM;
|
||||
|
||||
cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER;
|
||||
cfg->sec_prot.initial_key_imin = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS;
|
||||
cfg->sec_prot.initial_key_imax = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS;
|
||||
|
@ -535,6 +535,7 @@ static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg)
|
|||
cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_LARGE; // 10
|
||||
cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE;
|
||||
cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE;
|
||||
cfg->bbr.rpl_default_lifetime = WS_RPL_DEFAULT_LIFETIME_LARGE;
|
||||
cfg->bbr.dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_LARGE;
|
||||
|
||||
// EAPOL configuration
|
||||
|
@ -543,8 +544,6 @@ static void ws_cfg_network_size_config_set_large(ws_cfg_nw_size_t *cfg)
|
|||
cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS;
|
||||
cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_LARGE;
|
||||
|
||||
cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE;
|
||||
|
||||
cfg->sec_prot.initial_key_retry_delay = NONE_INITIAL_KEY_RETRY_TIMER;
|
||||
cfg->sec_prot.initial_key_imin = LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS;
|
||||
cfg->sec_prot.initial_key_imax = LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS;
|
||||
|
@ -579,6 +578,7 @@ static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg)
|
|||
cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_XLARGE; // 10
|
||||
cfg->bbr.dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE;
|
||||
cfg->bbr.min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE;
|
||||
cfg->bbr.rpl_default_lifetime = WS_RPL_DEFAULT_LIFETIME_XLARGE;
|
||||
cfg->bbr.dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_LARGE;
|
||||
|
||||
// EAPOL configuration
|
||||
|
@ -587,8 +587,6 @@ static void ws_cfg_network_size_config_set_xlarge(ws_cfg_nw_size_t *cfg)
|
|||
cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS;
|
||||
cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_LARGE;
|
||||
|
||||
cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE;
|
||||
|
||||
cfg->sec_prot.initial_key_retry_delay = NONE_INITIAL_KEY_RETRY_TIMER;
|
||||
cfg->sec_prot.initial_key_imin = EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMIN_SECS;
|
||||
cfg->sec_prot.initial_key_imax = EXTRA_LARGE_NW_INITIAL_KEY_TRICKLE_IMAX_SECS;
|
||||
|
@ -622,6 +620,7 @@ static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg)
|
|||
cfg->bbr.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_SMALL; // Disabled
|
||||
cfg->bbr.dag_max_rank_increase = WS_CERTIFICATE_RPL_MAX_HOP_RANK_INCREASE;
|
||||
cfg->bbr.min_hop_rank_increase = WS_CERTIFICATE_RPL_MIN_HOP_RANK_INCREASE;
|
||||
cfg->bbr.rpl_default_lifetime = WS_RPL_DEFAULT_LIFETIME;
|
||||
cfg->bbr.dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_SMALL;
|
||||
|
||||
// EAPOL configuration
|
||||
|
@ -630,8 +629,6 @@ static void ws_cfg_network_size_config_set_certificate(ws_cfg_nw_size_t *cfg)
|
|||
cfg->sec_prot.sec_prot_trickle_timer_exp = SEC_PROT_TIMER_EXPIRATIONS;
|
||||
cfg->sec_prot.sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL;
|
||||
|
||||
cfg->sec_prot.sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL;
|
||||
|
||||
cfg->sec_prot.initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER;
|
||||
cfg->sec_prot.initial_key_imin = SMALL_NW_INITIAL_KEY_TRICKLE_IMIN_SECS;
|
||||
cfg->sec_prot.initial_key_imax = SMALL_NW_INITIAL_KEY_TRICKLE_IMAX_SECS;
|
||||
|
@ -698,6 +695,7 @@ int8_t ws_cfg_gen_set(protocol_interface_info_entry_t *cur, ws_gen_cfg_t *cfg, w
|
|||
}
|
||||
ws_cfg_trace((ws_cfgs_t *) cfg, (ws_cfgs_t *) new_cfg, sizeof(ws_gen_cfg_t), "gen");
|
||||
|
||||
cfg->network_size = new_cfg->network_size;
|
||||
if (&cfg->network_name != &new_cfg->network_name) {
|
||||
strncpy(cfg->network_name, new_cfg->network_name, 32);
|
||||
}
|
||||
|
@ -883,6 +881,7 @@ int8_t ws_cfg_timing_set(protocol_interface_info_entry_t *cur, ws_timing_cfg_t *
|
|||
cur->ws_info->trickle_params_pan_discovery.Imax = new_cfg->disc_trickle_imax * 10;
|
||||
cur->ws_info->trickle_params_pan_discovery.k = new_cfg->disc_trickle_k;
|
||||
cur->ws_info->trickle_params_pan_discovery.TimerExpirations = TRICKLE_EXPIRATIONS_INFINITE;
|
||||
ws_pae_controller_configure(cur, NULL, NULL, new_cfg);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
|
@ -909,6 +908,7 @@ static int8_t ws_cfg_bbr_default_set(ws_bbr_cfg_t *cfg)
|
|||
cfg->dio_redundancy_constant = 10;
|
||||
cfg->dag_max_rank_increase = WS_RPL_MAX_HOP_RANK_INCREASE;
|
||||
cfg->min_hop_rank_increase = WS_RPL_MIN_HOP_RANK_INCREASE;
|
||||
cfg->rpl_default_lifetime = WS_RPL_DEFAULT_LIFETIME_MEDIUM;
|
||||
cfg->dhcp_address_lifetime = WS_DHCP_ADDRESS_LIFETIME_MEDIUM;
|
||||
|
||||
return CFG_SETTINGS_OK;
|
||||
|
@ -932,7 +932,8 @@ int8_t ws_cfg_bbr_validate(ws_bbr_cfg_t *cfg, ws_bbr_cfg_t *new_cfg)
|
|||
cfg->dio_redundancy_constant != new_cfg->dio_redundancy_constant ||
|
||||
cfg->dag_max_rank_increase != new_cfg->dag_max_rank_increase ||
|
||||
cfg->min_hop_rank_increase != new_cfg->min_hop_rank_increase ||
|
||||
cfg->dhcp_address_lifetime != new_cfg->dhcp_address_lifetime) {
|
||||
cfg->dhcp_address_lifetime != new_cfg->dhcp_address_lifetime ||
|
||||
cfg->rpl_default_lifetime != new_cfg->rpl_default_lifetime) {
|
||||
return CFG_SETTINGS_CHANGED;
|
||||
}
|
||||
|
||||
|
@ -954,7 +955,7 @@ int8_t ws_cfg_bbr_set(protocol_interface_info_entry_t *cur, ws_bbr_cfg_t *cfg, w
|
|||
// cur is optional, default values are for Wi-SUN small network parameters,
|
||||
ws_bbr_rpl_config(cur, new_cfg->dio_interval_min, new_cfg->dio_interval_doublings,
|
||||
new_cfg->dio_redundancy_constant, new_cfg->dag_max_rank_increase,
|
||||
new_cfg->min_hop_rank_increase);
|
||||
new_cfg->min_hop_rank_increase, new_cfg->rpl_default_lifetime);
|
||||
ws_bbr_dhcp_address_lifetime_set(cur, new_cfg->dhcp_address_lifetime);
|
||||
}
|
||||
|
||||
|
@ -1210,7 +1211,7 @@ int8_t ws_cfg_sec_timer_set(protocol_interface_info_entry_t *cur, ws_sec_timer_c
|
|||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
ws_pae_controller_configure(cur, new_cfg, NULL);
|
||||
ws_pae_controller_configure(cur, new_cfg, NULL, NULL);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
|
@ -1230,7 +1231,8 @@ static int8_t ws_cfg_sec_prot_default_set(ws_sec_prot_cfg_t *cfg)
|
|||
cfg->sec_prot_trickle_imax = SEC_PROT_SMALL_IMAX;
|
||||
cfg->sec_prot_trickle_timer_exp = 2;
|
||||
cfg->sec_prot_retry_timeout = SEC_PROT_RETRY_TIMEOUT_SMALL;
|
||||
cfg->sec_max_ongoing_authentication = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM;
|
||||
cfg->max_simult_sec_neg_tx_queue_min = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MIN;
|
||||
cfg->max_simult_sec_neg_tx_queue_max = MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MAX;
|
||||
cfg->initial_key_retry_delay = DEFAULT_INITIAL_KEY_RETRY_TIMER;
|
||||
cfg->initial_key_imin = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMIN_SECS;
|
||||
cfg->initial_key_imax = MEDIUM_NW_INITIAL_KEY_TRICKLE_IMAX_SECS;
|
||||
|
@ -1256,7 +1258,8 @@ int8_t ws_cfg_sec_prot_validate(ws_sec_prot_cfg_t *cfg, ws_sec_prot_cfg_t *new_c
|
|||
cfg->sec_prot_trickle_imax != new_cfg->sec_prot_trickle_imax ||
|
||||
cfg->sec_prot_trickle_timer_exp != new_cfg->sec_prot_trickle_timer_exp ||
|
||||
cfg->sec_prot_retry_timeout != new_cfg->sec_prot_retry_timeout ||
|
||||
cfg->sec_max_ongoing_authentication != new_cfg->sec_max_ongoing_authentication ||
|
||||
cfg->max_simult_sec_neg_tx_queue_min != new_cfg->max_simult_sec_neg_tx_queue_min ||
|
||||
cfg->max_simult_sec_neg_tx_queue_max != new_cfg->max_simult_sec_neg_tx_queue_max ||
|
||||
cfg->initial_key_retry_delay != new_cfg->initial_key_retry_delay ||
|
||||
cfg->initial_key_imin != new_cfg->initial_key_retry_delay ||
|
||||
cfg->initial_key_imax != new_cfg->initial_key_retry_delay ||
|
||||
|
@ -1277,7 +1280,7 @@ int8_t ws_cfg_sec_prot_set(protocol_interface_info_entry_t *cur, ws_sec_prot_cfg
|
|||
}
|
||||
|
||||
if (cur && !(cfg_flags & CFG_FLAGS_DISABLE_VAL_SET)) {
|
||||
ws_pae_controller_configure(cur, NULL, new_cfg);
|
||||
ws_pae_controller_configure(cur, NULL, new_cfg, NULL);
|
||||
}
|
||||
|
||||
if (cfg == new_cfg) {
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef struct ws_bbr_cfg_s {
|
|||
uint16_t dag_max_rank_increase;
|
||||
uint16_t min_hop_rank_increase;
|
||||
uint32_t dhcp_address_lifetime; /**< DHCP address lifetime in seconds minimum 2 hours and maximum as days hours*/
|
||||
uint32_t rpl_default_lifetime; /**< RPL default lifetime value minimum from 30 minutes to 16 hours*/
|
||||
} ws_bbr_cfg_t;
|
||||
|
||||
/**
|
||||
|
@ -114,7 +115,8 @@ typedef struct ws_sec_prot_cfg_s {
|
|||
uint16_t sec_prot_trickle_imin; /**< Security protocol trickle parameters Imin; seconds; default 30 */
|
||||
uint16_t sec_prot_trickle_imax; /**< Security protocol trickle parameters Imax; seconds; default 90 */
|
||||
uint8_t sec_prot_trickle_timer_exp; /**< Security protocol trickle timer expirations; default 2 */
|
||||
uint16_t sec_max_ongoing_authentication; /**< Pae authenticator max Accept ongoing authentication count */
|
||||
uint16_t max_simult_sec_neg_tx_queue_min; /**< PAE authenticator max simultaneous security negotiations TX queue minimum */
|
||||
uint16_t max_simult_sec_neg_tx_queue_max; /**< PAE authenticator max simultaneous security negotiations TX queue maximum */
|
||||
uint16_t initial_key_retry_delay; /**< Delay before starting initial key trickle; seconds; default 120 */
|
||||
uint16_t initial_key_imin; /**< Initial key trickle Imin; seconds; default 360 */
|
||||
uint16_t initial_key_imax; /**< Initial key trickle Imax; seconds; default 720 */
|
||||
|
|
|
@ -690,4 +690,14 @@ void ws_common_secondary_parent_update(protocol_interface_info_entry_t *interfac
|
|||
ws_bootstrap_secondary_parent_update(interface);
|
||||
}
|
||||
|
||||
void ws_common_border_router_alive_update(protocol_interface_info_entry_t *interface)
|
||||
{
|
||||
if (interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// After successful DAO ACK connection to border router is verified
|
||||
interface->ws_info->pan_timeout_timer = interface->ws_info->cfg->timing.pan_timeout;
|
||||
}
|
||||
|
||||
#endif // HAVE_WS
|
||||
|
|
|
@ -173,6 +173,8 @@ void ws_common_primary_parent_update(protocol_interface_info_entry_t *interface,
|
|||
void ws_common_secondary_parent_update(protocol_interface_info_entry_t *interface);
|
||||
|
||||
uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size);
|
||||
void ws_common_border_router_alive_update(protocol_interface_info_entry_t *interface);
|
||||
|
||||
#define ws_info(cur) ((cur)->ws_info)
|
||||
#else
|
||||
#define ws_info(cur) ((ws_info_t *) NULL)
|
||||
|
@ -189,6 +191,7 @@ uint8_t ws_common_temporary_entry_size(uint8_t mac_table_size);
|
|||
#define ws_common_network_size_estimate_get(cur) 0
|
||||
#define ws_common_primary_parent_update(interface, neighbor)
|
||||
#define ws_common_secondary_parent_update(interface)
|
||||
#define ws_common_border_router_alive_update(interface) ((void) 0)
|
||||
|
||||
|
||||
#endif //HAVE_WS
|
||||
|
|
|
@ -239,6 +239,13 @@ typedef struct ws_bs_ie {
|
|||
#define MPX_KEY_MANAGEMENT_ENC_USER_ID 0x0001 /**< MPX Key management user ID */
|
||||
#define MPX_LOWPAN_ENC_USER_ID 0xA0ED /**< MPX Lowpan User Id */
|
||||
|
||||
/*
|
||||
* Wi-SUN MPX MTU size
|
||||
*
|
||||
*/
|
||||
|
||||
#define WS_MPX_MAX_MTU 1576
|
||||
|
||||
#define WS_FAN_VERSION_1_0 1
|
||||
|
||||
#define WS_NEIGHBOR_LINK_TIMEOUT 2200
|
||||
|
@ -373,4 +380,5 @@ typedef struct ws_bs_ie {
|
|||
#define BR_EAPOL_RELAY_SOCKET_PORT 10255
|
||||
#define PAE_AUTH_SOCKET_PORT 10254
|
||||
|
||||
|
||||
#endif /* WS_COMMON_DEFINES_H_ */
|
||||
|
|
|
@ -50,6 +50,11 @@
|
|||
#define WS_RPL_MIN_HOP_RANK_INCREASE 196
|
||||
#define WS_RPL_MAX_HOP_RANK_INCREASE 2048
|
||||
|
||||
#define WS_RPL_DEFAULT_LIFETIME (3600*2) // 2 hours
|
||||
#define WS_RPL_DEFAULT_LIFETIME_MEDIUM (3600*4) // 4 hours
|
||||
#define WS_RPL_DEFAULT_LIFETIME_LARGE (3600*8) // 8 hours
|
||||
#define WS_RPL_DEFAULT_LIFETIME_XLARGE (3600*12) // 12 hours
|
||||
|
||||
#define WS_DHCP_ADDRESS_LIFETIME_SMALL 2*3600 // small networks less than devices 100
|
||||
#define WS_DHCP_ADDRESS_LIFETIME_MEDIUM 12*3600 // Medium size networks from 100 - 1000 device networks
|
||||
#define WS_DHCP_ADDRESS_LIFETIME_LARGE 24*3600 // Large size networks 1000 + device networks
|
||||
|
@ -60,7 +65,7 @@
|
|||
/*
|
||||
* RPL DAO timeout maximum value. This will force DAO timeout to happen before this time
|
||||
*/
|
||||
#define WS_RPL_DAO_MAX_TIMOUT (3600*2)
|
||||
#define WS_RPL_DAO_MAX_TIMOUT (3600*12)
|
||||
|
||||
/* Border router version change interval
|
||||
*
|
||||
|
@ -249,9 +254,8 @@ extern uint8_t DEVICE_MIN_SENS;
|
|||
#define SEC_PROT_TIMER_EXPIRATIONS 2 // Number of retries
|
||||
|
||||
// Maximum number of simultaneous security negotiations
|
||||
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_SMALL 20
|
||||
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_MEDIUM 20
|
||||
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_LARGE 50
|
||||
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MIN 64
|
||||
#define MAX_SIMULTANEOUS_SECURITY_NEGOTIATIONS_TX_QUEUE_MAX 192
|
||||
|
||||
/*
|
||||
* Security protocol timer configuration parameters
|
||||
|
|
|
@ -68,20 +68,41 @@ int ws_management_network_name_validate(
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ws_management_phy_mode_id_set(
|
||||
int ws_management_domain_configuration_set(
|
||||
int8_t interface_id,
|
||||
uint8_t phy_mode_id)
|
||||
uint8_t regulatory_domain,
|
||||
uint8_t phy_mode_id,
|
||||
uint8_t channel_plan_id)
|
||||
{
|
||||
(void)regulatory_domain;
|
||||
(void)interface_id;
|
||||
(void)phy_mode_id;
|
||||
(void)channel_plan_id;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ws_management_channel_plan_id_set(
|
||||
int ws_management_domain_configuration_get(
|
||||
int8_t interface_id,
|
||||
uint8_t *regulatory_domain,
|
||||
uint8_t *phy_mode_id,
|
||||
uint8_t *channel_plan_id)
|
||||
{
|
||||
(void)regulatory_domain;
|
||||
(void)interface_id;
|
||||
(void)phy_mode_id;
|
||||
(void)channel_plan_id;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ws_management_domain_configuration_validate(
|
||||
int8_t interface_id,
|
||||
uint8_t regulatory_domain,
|
||||
uint8_t phy_mode_id,
|
||||
uint8_t channel_plan_id)
|
||||
{
|
||||
(void)regulatory_domain;
|
||||
(void)interface_id;
|
||||
(void)phy_mode_id;
|
||||
(void)channel_plan_id;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -156,12 +156,13 @@ int ws_management_network_name_validate(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ws_management_phy_mode_id_set(
|
||||
int ws_management_domain_configuration_set(
|
||||
int8_t interface_id,
|
||||
uint8_t phy_mode_id)
|
||||
uint8_t regulatory_domain,
|
||||
uint8_t phy_mode_id,
|
||||
uint8_t channel_plan_id)
|
||||
{
|
||||
protocol_interface_info_entry_t *cur;
|
||||
|
||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
|
||||
return -1;
|
||||
|
@ -177,10 +178,22 @@ int ws_management_phy_mode_id_set(
|
|||
return -3;
|
||||
}
|
||||
|
||||
if (phy_mode_id != 255) {
|
||||
cfg.phy_mode_id = phy_mode_id;
|
||||
} else {
|
||||
if (regulatory_domain == 255) {
|
||||
cfg.regulatory_domain = cfg_default.regulatory_domain;
|
||||
} else if (regulatory_domain != 0) {
|
||||
cfg.regulatory_domain = regulatory_domain;
|
||||
}
|
||||
|
||||
if (phy_mode_id == 255) {
|
||||
cfg.phy_mode_id = cfg_default.phy_mode_id;
|
||||
} else if (phy_mode_id != 0) {
|
||||
cfg.phy_mode_id = phy_mode_id;
|
||||
}
|
||||
|
||||
if (channel_plan_id == 255) {
|
||||
cfg.channel_plan_id = cfg_default.channel_plan_id;
|
||||
} else if (channel_plan_id != 0) {
|
||||
cfg.channel_plan_id = channel_plan_id;
|
||||
}
|
||||
|
||||
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
|
||||
|
@ -190,34 +203,58 @@ int ws_management_phy_mode_id_set(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ws_management_channel_plan_id_set(
|
||||
int ws_management_domain_configuration_get(
|
||||
int8_t interface_id,
|
||||
uint8_t channel_plan_id)
|
||||
uint8_t *regulatory_domain,
|
||||
uint8_t *phy_mode_id,
|
||||
uint8_t *channel_plan_id)
|
||||
{
|
||||
protocol_interface_info_entry_t *cur;
|
||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_phy_cfg_t cfg;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (regulatory_domain) {
|
||||
*regulatory_domain = cfg.regulatory_domain;
|
||||
}
|
||||
if (phy_mode_id) {
|
||||
*phy_mode_id = cfg.phy_mode_id;
|
||||
}
|
||||
if (channel_plan_id) {
|
||||
*channel_plan_id = cfg.channel_plan_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ws_management_domain_configuration_validate(
|
||||
int8_t interface_id,
|
||||
uint8_t regulatory_domain,
|
||||
uint8_t phy_mode_id,
|
||||
uint8_t channel_plan_id)
|
||||
{
|
||||
protocol_interface_info_entry_t *cur;
|
||||
|
||||
cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (interface_id >= 0 && (!cur || !ws_info(cur))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ws_phy_cfg_t cfg;
|
||||
ws_phy_cfg_t cfg_default;
|
||||
if (ws_cfg_phy_get(&cfg, NULL) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (ws_cfg_phy_default_set(&cfg_default) < 0) {
|
||||
return -3;
|
||||
}
|
||||
cfg.regulatory_domain = regulatory_domain;
|
||||
cfg.phy_mode_id = phy_mode_id;
|
||||
cfg.channel_plan_id = channel_plan_id;
|
||||
|
||||
if (channel_plan_id != 255) {
|
||||
cfg.channel_plan_id = channel_plan_id;
|
||||
} else {
|
||||
cfg.channel_plan_id = cfg_default.channel_plan_id;
|
||||
}
|
||||
|
||||
if (ws_cfg_phy_set(cur, NULL, &cfg, 0) < 0) {
|
||||
if (ws_cfg_phy_validate(NULL, &cfg) < 0) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,10 +66,8 @@
|
|||
#define WAIT_FOR_AUTHENTICATION_TICKS 2 * 60 * 10 // 2 minutes
|
||||
// Wait after authentication has completed before supplicant entry goes inactive
|
||||
#define WAIT_AFTER_AUTHENTICATION_TICKS 15 * 10 // 15 seconds
|
||||
|
||||
/* If EAP-TLS is delayed due to simultaneous negotiations limit, defines how
|
||||
long to wait for previous negotiation to complete */
|
||||
#define EAP_TLS_NEGOTIATION_TRIGGER_TIMEOUT 60 * 10 // 60 seconds
|
||||
// Waiting for authentication supplicant list maximum size
|
||||
#define WAITING_SUPPLICANT_LIST_MAX_SIZE 50
|
||||
|
||||
// Default for maximum number of supplicants
|
||||
#define SUPPLICANT_MAX_NUMBER 5000
|
||||
|
@ -93,7 +91,9 @@ typedef struct {
|
|||
ws_pae_auth_nw_key_index_set *nw_key_index_set; /**< Key index set callback */
|
||||
ws_pae_auth_nw_info_updated *nw_info_updated; /**< Security keys network info updated callback */
|
||||
ws_pae_auth_ip_addr_get *ip_addr_get; /**< IP address get callback */
|
||||
ws_pae_auth_congestion_get *congestion_get; /**< Congestion get callback */
|
||||
supp_list_t active_supp_list; /**< List of active supplicants */
|
||||
supp_list_t waiting_supp_list; /**< List of waiting supplicants */
|
||||
shared_comp_list_t shared_comp_list; /**< Shared component list */
|
||||
arm_event_storage_t *timer; /**< Timer */
|
||||
sec_prot_gtk_keys_t *next_gtks; /**< Next GTKs */
|
||||
|
@ -101,6 +101,7 @@ typedef struct {
|
|||
sec_prot_keys_nw_info_t *sec_keys_nw_info; /**< Security keys network information */
|
||||
sec_cfg_t *sec_cfg; /**< Security configuration */
|
||||
uint16_t supp_max_number; /**< Max number of stored supplicants */
|
||||
uint16_t waiting_supp_list_size; /**< Waiting supplicants list size */
|
||||
uint8_t relay_socked_msg_if_instance_id; /**< Relay socket message interface instance identifier */
|
||||
uint8_t radius_socked_msg_if_instance_id; /**< Radius socket message interface instance identifier */
|
||||
bool timer_running : 1; /**< Timer is running */
|
||||
|
@ -128,6 +129,7 @@ static bool ws_pae_auth_timer_running(pae_auth_t *pae_auth);
|
|||
static void ws_pae_auth_kmp_service_addr_get(kmp_service_t *service, kmp_api_t *kmp, kmp_addr_t *local_addr, kmp_addr_t *remote_addr);
|
||||
static void ws_pae_auth_kmp_service_ip_addr_get(kmp_service_t *service, kmp_api_t *kmp, uint8_t *address);
|
||||
static kmp_api_t *ws_pae_auth_kmp_service_api_get(kmp_service_t *service, kmp_api_t *kmp, kmp_type_e type);
|
||||
static bool ws_pae_auth_active_limit_reached(uint16_t active_supp, pae_auth_t *pae_auth);
|
||||
static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, uint8_t msg_if_instance_id, kmp_type_e type, const kmp_addr_t *addr, const void *pdu, uint16_t size);
|
||||
static void ws_pae_auth_kmp_api_create_confirm(kmp_api_t *kmp, kmp_result_e result);
|
||||
static void ws_pae_auth_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e type, kmp_addr_t *addr);
|
||||
|
@ -136,6 +138,8 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup
|
|||
static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry_t *supp_entry);
|
||||
static kmp_api_t *ws_pae_auth_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, uint8_t socked_msg_if_instance_id, supp_entry_t *supp_entry, sec_cfg_t *sec_cfg);
|
||||
static void ws_pae_auth_kmp_api_finished(kmp_api_t *kmp);
|
||||
static void ws_pae_auth_active_supp_deleted(void *pae_auth);
|
||||
static void ws_pae_auth_waiting_supp_deleted(void *pae_auth);
|
||||
|
||||
static int8_t tasklet_id = -1;
|
||||
static NS_LIST_DEFINE(pae_auth_list, pae_auth_t, link);
|
||||
|
@ -159,6 +163,7 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
|
|||
pae_auth->pan_id = 0xffff;
|
||||
pae_auth->interface_ptr = interface_ptr;
|
||||
ws_pae_lib_supp_list_init(&pae_auth->active_supp_list);
|
||||
ws_pae_lib_supp_list_init(&pae_auth->waiting_supp_list);
|
||||
ws_pae_lib_shared_comp_list_init(&pae_auth->shared_comp_list);
|
||||
pae_auth->timer = NULL;
|
||||
|
||||
|
@ -166,12 +171,16 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
|
|||
pae_auth->nw_key_insert = NULL;
|
||||
pae_auth->nw_keys_remove = NULL;
|
||||
pae_auth->nw_key_index_set = NULL;
|
||||
pae_auth->nw_info_updated = NULL;
|
||||
pae_auth->ip_addr_get = NULL;
|
||||
pae_auth->congestion_get = NULL;
|
||||
|
||||
pae_auth->next_gtks = next_gtks;
|
||||
pae_auth->certs = certs;
|
||||
pae_auth->sec_keys_nw_info = sec_keys_nw_info;
|
||||
pae_auth->sec_cfg = sec_cfg;
|
||||
pae_auth->supp_max_number = SUPPLICANT_MAX_NUMBER;
|
||||
pae_auth->waiting_supp_list_size = 0;
|
||||
|
||||
pae_auth->gtk_new_inst_req_exp = false;
|
||||
pae_auth->gtk_new_act_time_exp = false;
|
||||
|
@ -302,7 +311,7 @@ int8_t ws_pae_auth_delete(protocol_interface_info_entry_t *interface_ptr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get)
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get, ws_pae_auth_congestion_get *congestion_get)
|
||||
{
|
||||
if (!interface_ptr) {
|
||||
return;
|
||||
|
@ -318,6 +327,7 @@ void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
|
|||
pae_auth->nw_key_index_set = nw_key_index_set;
|
||||
pae_auth->nw_info_updated = nw_info_updated;
|
||||
pae_auth->ip_addr_get = ip_addr_get;
|
||||
pae_auth->congestion_get = congestion_get;
|
||||
}
|
||||
|
||||
void ws_pae_auth_start(protocol_interface_info_entry_t *interface_ptr)
|
||||
|
@ -394,8 +404,11 @@ int8_t ws_pae_auth_node_keys_remove(protocol_interface_info_entry_t *interface_p
|
|||
return ret_value;
|
||||
}
|
||||
|
||||
// Checks if supplicant is active
|
||||
// Checks if supplicant is active or waiting
|
||||
supp_entry_t *supp = ws_pae_lib_supp_list_entry_eui_64_get(&pae_auth->active_supp_list, eui_64);
|
||||
if (!supp) {
|
||||
supp = ws_pae_lib_supp_list_entry_eui_64_get(&pae_auth->waiting_supp_list, eui_64);
|
||||
}
|
||||
|
||||
if (supp) {
|
||||
// Deletes keys and marks as revoked
|
||||
|
@ -507,7 +520,8 @@ void ws_pae_auth_forced_gc(protocol_interface_info_entry_t *interface_ptr)
|
|||
|
||||
/* 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, 0, SUPPLICANT_NUMBER_TO_PURGE);
|
||||
ws_pae_lib_supp_list_purge(pae_auth, &pae_auth->active_supp_list, 0, SUPPLICANT_NUMBER_TO_PURGE, NULL);
|
||||
ws_pae_lib_supp_list_purge(pae_auth, &pae_auth->waiting_supp_list, 0, SUPPLICANT_NUMBER_TO_PURGE, ws_pae_auth_waiting_supp_deleted);
|
||||
}
|
||||
|
||||
int8_t ws_pae_auth_nw_info_set(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, bool updated)
|
||||
|
@ -608,6 +622,7 @@ static void ws_pae_auth_free(pae_auth_t *pae_auth)
|
|||
ws_pae_lib_shared_comp_list_free(&pae_auth->shared_comp_list);
|
||||
|
||||
ws_pae_lib_supp_list_delete(&pae_auth->active_supp_list);
|
||||
ws_pae_lib_supp_list_delete(&pae_auth->waiting_supp_list);
|
||||
|
||||
kmp_socket_if_unregister(pae_auth->kmp_service);
|
||||
|
||||
|
@ -690,8 +705,9 @@ void ws_pae_auth_fast_timer(uint16_t ticks)
|
|||
}
|
||||
|
||||
// Updates KMP timers
|
||||
bool running = ws_pae_lib_supp_list_timer_update(pae_auth, &pae_auth->active_supp_list, ticks, kmp_service_timer_if_timeout);
|
||||
if (!running) {
|
||||
bool active_running = ws_pae_lib_supp_list_timer_update(pae_auth, &pae_auth->active_supp_list, ticks, kmp_service_timer_if_timeout, ws_pae_auth_active_supp_deleted);
|
||||
bool wait_running = ws_pae_lib_supp_list_timer_update(pae_auth, &pae_auth->waiting_supp_list, ticks, kmp_service_timer_if_timeout, ws_pae_auth_waiting_supp_deleted);
|
||||
if (!active_running && !wait_running) {
|
||||
ws_pae_auth_timer_stop(pae_auth);
|
||||
}
|
||||
}
|
||||
|
@ -936,6 +952,40 @@ static kmp_api_t *ws_pae_auth_kmp_service_api_get(kmp_service_t *service, kmp_ap
|
|||
return ws_pae_lib_kmp_list_type_get(&supp_entry->kmp_list, type);
|
||||
}
|
||||
|
||||
static bool ws_pae_auth_active_limit_reached(uint16_t active_supp, pae_auth_t *pae_auth)
|
||||
{
|
||||
return pae_auth->congestion_get(pae_auth->interface_ptr, active_supp);
|
||||
}
|
||||
|
||||
static supp_entry_t *ws_pae_auth_waiting_supp_list_add(pae_auth_t *pae_auth, supp_entry_t *supp_entry, const kmp_addr_t *addr)
|
||||
{
|
||||
// Entry is already allocated
|
||||
if (supp_entry) {
|
||||
ns_list_add_to_start(&pae_auth->waiting_supp_list, supp_entry);
|
||||
pae_auth->waiting_supp_list_size++;
|
||||
} else {
|
||||
// Create a new supplicant entry if not at limit
|
||||
if (pae_auth->waiting_supp_list_size > WAITING_SUPPLICANT_LIST_MAX_SIZE) {
|
||||
tr_info("PAE: waiting list full, eui-64: %s", trace_array(addr->eui_64, 8));
|
||||
return NULL;
|
||||
}
|
||||
supp_entry = ws_pae_lib_supp_list_add(&pae_auth->waiting_supp_list, addr);
|
||||
if (!supp_entry) {
|
||||
tr_info("PAE: waiting list no memory, eui-64: %s", trace_array(addr->eui_64, 8));
|
||||
return NULL;
|
||||
}
|
||||
pae_auth->waiting_supp_list_size++;
|
||||
sec_prot_keys_init(&supp_entry->sec_keys, pae_auth->sec_keys_nw_info->gtks, pae_auth->certs);
|
||||
}
|
||||
|
||||
// 90 percent of the EAPOL temporary entry lifetime (10 ticks per second)
|
||||
supp_entry->waiting_ticks = pae_auth->sec_cfg->timing_cfg.temp_eapol_min_timeout * 900 / 100;
|
||||
|
||||
tr_debug("PAE: to waiting, list size %i, retry %i, eui-64: %s", pae_auth->waiting_supp_list_size, supp_entry->waiting_ticks, trace_array(supp_entry->addr.eui_64, 8));
|
||||
|
||||
return supp_entry;
|
||||
}
|
||||
|
||||
static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, uint8_t msg_if_instance_id, kmp_type_e type, const kmp_addr_t *addr, const void *pdu, uint16_t size)
|
||||
{
|
||||
pae_auth_t *pae_auth = ws_pae_auth_by_kmp_service_get(service);
|
||||
|
@ -954,21 +1004,43 @@ static kmp_api_t *ws_pae_auth_kmp_incoming_ind(kmp_service_t *service, uint8_t m
|
|||
supp_entry_t *supp_entry = ws_pae_lib_supp_list_entry_eui_64_get(&pae_auth->active_supp_list, kmp_address_eui_64_get(addr));
|
||||
|
||||
if (!supp_entry) {
|
||||
// Checks if active supplicant list has space for new supplicants
|
||||
if (ws_pae_lib_supp_list_active_limit_reached(&pae_auth->active_supp_list, pae_auth->sec_cfg->prot_cfg.sec_max_ongoing_authentication)) {
|
||||
tr_debug("PAE: active limit reached, eui-64: %s", trace_array(kmp_address_eui_64_get(addr), 8));
|
||||
return NULL;
|
||||
}
|
||||
// Find supplicant from key storage
|
||||
supp_entry = ws_pae_key_storage_supp_read(pae_auth, kmp_address_eui_64_get(addr), pae_auth->sec_keys_nw_info->gtks, pae_auth->certs);
|
||||
uint16_t active_supp = ns_list_count(&pae_auth->active_supp_list);
|
||||
|
||||
// Check if supplicant is already on the the waiting supplicant list
|
||||
supp_entry = ws_pae_lib_supp_list_entry_eui_64_get(&pae_auth->waiting_supp_list, kmp_address_eui_64_get(addr));
|
||||
if (supp_entry) {
|
||||
// Move supplicant to active list
|
||||
tr_debug("PAE: to active, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
ns_list_add_to_start(&pae_auth->active_supp_list, supp_entry);
|
||||
/* Remove from waiting list (supplicant is later added to active list, or if no room back to the start of the
|
||||
* waiting list with updated timer)
|
||||
*/
|
||||
ns_list_remove(&pae_auth->waiting_supp_list, supp_entry);
|
||||
pae_auth->waiting_supp_list_size--;
|
||||
supp_entry->waiting_ticks = 0;
|
||||
} else {
|
||||
// Find supplicant from key storage
|
||||
supp_entry = ws_pae_key_storage_supp_read(pae_auth, kmp_address_eui_64_get(addr), pae_auth->sec_keys_nw_info->gtks, pae_auth->certs);
|
||||
}
|
||||
|
||||
// Checks if active supplicant list has space for new supplicants
|
||||
if (ws_pae_auth_active_limit_reached(active_supp, pae_auth)) {
|
||||
tr_debug("PAE: active limit reached, eui-64: %s", trace_array(kmp_address_eui_64_get(addr), 8));
|
||||
// If there is no space, add supplicant entry to the start of the waiting supplicant list
|
||||
supp_entry = ws_pae_auth_waiting_supp_list_add(pae_auth, supp_entry, addr);
|
||||
if (!supp_entry) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (supp_entry) {
|
||||
/*
|
||||
* If there is space and there is already an allocated supplicant, add it to active list and
|
||||
* start/continue authentication
|
||||
*/
|
||||
tr_debug("PAE: to active, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
ns_list_add_to_start(&pae_auth->active_supp_list, supp_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If does not exists add it to list
|
||||
// If supplicant does not exists create a new supplicant entry to the active list
|
||||
if (!supp_entry) {
|
||||
supp_entry = ws_pae_lib_supp_list_add(&pae_auth->active_supp_list, addr);
|
||||
if (!supp_entry) {
|
||||
|
@ -1065,14 +1137,16 @@ static void ws_pae_auth_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e
|
|||
return;
|
||||
}
|
||||
|
||||
// Ensures that supplicant is in active supplicant list before initiating next KMP
|
||||
if (!ws_pae_lib_supp_list_entry_is_in_list(&pae_auth->active_supp_list, supp_entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ws_pae_auth_next_kmp_trigger(pae_auth, supp_entry);
|
||||
}
|
||||
|
||||
static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *supp_entry)
|
||||
{
|
||||
// Disables KMP retry timer
|
||||
supp_entry->retry_ticks = 0;
|
||||
|
||||
// Get next protocol based on what keys supplicant has
|
||||
kmp_type_e next_type = ws_pae_auth_next_protocol_get(pae_auth, supp_entry);
|
||||
|
||||
|
@ -1096,21 +1170,6 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup
|
|||
// Increases waiting time for supplicant authentication
|
||||
ws_pae_lib_supp_timer_ticks_set(supp_entry, WAIT_FOR_AUTHENTICATION_TICKS);
|
||||
|
||||
if (next_type == IEEE_802_1X_MKA || next_type == RADIUS_IEEE_802_1X_MKA) {
|
||||
/* For EAP-TLS, limits the number of ongoing negotiations. If limit
|
||||
is reached, authenticator does not initiate EAP-TLS right away.
|
||||
If previous EAP-TLS negotiation completes before negotiation
|
||||
trigger timeout, authenticator initiates EAP-TLS towards
|
||||
supplicant. Otherwise supplicant must re-send initial EAPOL-Key
|
||||
to try again using its trickle schedule */
|
||||
uint16_t ongoing_eap_tls_cnt = ws_pae_lib_supp_list_kmp_count(&pae_auth->active_supp_list, next_type);
|
||||
if (ongoing_eap_tls_cnt >= pae_auth->sec_cfg->prot_cfg.sec_max_ongoing_authentication) {
|
||||
supp_entry->retry_ticks = EAP_TLS_NEGOTIATION_TRIGGER_TIMEOUT;
|
||||
tr_info("EAP-TLS max ongoing reached, count %i, delayed: eui-64: %s", ongoing_eap_tls_cnt, trace_array(supp_entry->addr.eui_64, 8));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new instance
|
||||
kmp_api_t *new_kmp = ws_pae_auth_kmp_create_and_start(pae_auth->kmp_service, next_type, pae_auth->relay_socked_msg_if_instance_id, supp_entry, pae_auth->sec_cfg);
|
||||
if (!new_kmp) {
|
||||
|
@ -1161,11 +1220,11 @@ static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry
|
|||
} else {
|
||||
next_type = IEEE_802_1X_MKA;
|
||||
}
|
||||
tr_info("PAE start EAP-TLS, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
tr_info("PAE: start EAP-TLS, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
} else if (sec_keys->ptk_mismatch) {
|
||||
// start 4WH towards supplicant
|
||||
next_type = IEEE_802_11_4WH;
|
||||
tr_info("PAE start 4WH, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
tr_info("PAE: start 4WH, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
}
|
||||
|
||||
int8_t gtk_index = -1;
|
||||
|
@ -1191,19 +1250,19 @@ static kmp_type_e ws_pae_auth_next_protocol_get(pae_auth_t *pae_auth, supp_entry
|
|||
// start 4WH towards supplicant
|
||||
next_type = IEEE_802_11_4WH;
|
||||
sec_keys->ptk_mismatch = true;
|
||||
tr_info("PAE start 4WH due to GTK index re-use, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
tr_info("PAE: start 4WH due to GTK index re-use, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
} else {
|
||||
// Update just GTK
|
||||
next_type = IEEE_802_11_GKH;
|
||||
tr_info("PAE start GKH, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
tr_info("PAE: start GKH, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
}
|
||||
}
|
||||
|
||||
tr_info("PAE update GTK index: %i, eui-64: %s", gtk_index, trace_array(supp_entry->addr.eui_64, 8));
|
||||
tr_info("PAE: update GTK index: %i, eui-64: %s", gtk_index, trace_array(supp_entry->addr.eui_64, 8));
|
||||
}
|
||||
|
||||
if (next_type == KMP_TYPE_NONE) {
|
||||
tr_info("PAE authenticated, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
tr_info("PAE: authenticated, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
}
|
||||
|
||||
return next_type;
|
||||
|
@ -1254,26 +1313,38 @@ static void ws_pae_auth_kmp_api_finished(kmp_api_t *kmp)
|
|||
return;
|
||||
}
|
||||
|
||||
pae_auth_t *pae_auth = NULL;
|
||||
supp_entry_t *retry_supp = NULL;
|
||||
// When EAP-TLS completes check if there are other supplicants that have requested it lately
|
||||
if (kmp_api_type_get(kmp) == IEEE_802_1X_MKA || kmp_api_type_get(kmp) == RADIUS_IEEE_802_1X_MKA) {
|
||||
kmp_service_t *service = kmp_api_service_get(kmp);
|
||||
pae_auth = ws_pae_auth_by_kmp_service_get(service);
|
||||
if (pae_auth) {
|
||||
retry_supp = ws_pae_lib_supp_list_entry_retry_timer_get(&pae_auth->active_supp_list);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete KMP
|
||||
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, kmp);
|
||||
}
|
||||
|
||||
if (retry_supp) {
|
||||
tr_info("PAE next KMP trigger, eui-64: %s", trace_array(retry_supp->addr.eui_64, 8));
|
||||
static void ws_pae_auth_active_supp_deleted(void *pae_auth_ptr)
|
||||
{
|
||||
pae_auth_t *pae_auth = pae_auth_ptr;
|
||||
|
||||
tr_info("Supplicant deleted");
|
||||
|
||||
uint16_t active_supp = ns_list_count(&pae_auth->active_supp_list);
|
||||
if (ws_pae_auth_active_limit_reached(active_supp, pae_auth)) {
|
||||
return;
|
||||
}
|
||||
|
||||
supp_entry_t *retry_supp = ns_list_get_first(&pae_auth->waiting_supp_list);
|
||||
if (retry_supp != NULL) {
|
||||
ns_list_remove(&pae_auth->waiting_supp_list, retry_supp);
|
||||
pae_auth->waiting_supp_list_size--;
|
||||
ns_list_add_to_start(&pae_auth->active_supp_list, retry_supp);
|
||||
tr_info("PAE: waiting supplicant to active, eui-64: %s", trace_array(retry_supp->addr.eui_64, 8));
|
||||
retry_supp->waiting_ticks = 0;
|
||||
ws_pae_auth_next_kmp_trigger(pae_auth, retry_supp);
|
||||
}
|
||||
}
|
||||
|
||||
static void ws_pae_auth_waiting_supp_deleted(void *pae_auth_ptr)
|
||||
{
|
||||
pae_auth_t *pae_auth = pae_auth_ptr;
|
||||
pae_auth->waiting_supp_list_size--;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PAE_AUTH */
|
||||
#endif /* HAVE_WS */
|
||||
|
||||
|
|
|
@ -249,6 +249,17 @@ typedef void ws_pae_auth_nw_info_updated(protocol_interface_info_entry_t *interf
|
|||
*/
|
||||
typedef void ws_pae_auth_ip_addr_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *address);
|
||||
|
||||
/**
|
||||
* ws_pae_auth_congestion_get get congestion information
|
||||
*
|
||||
* \param interface_ptr interface
|
||||
* \param active_supp active supplicants
|
||||
*
|
||||
* \return TRUE reject, FALSE accept
|
||||
*
|
||||
*/
|
||||
typedef bool ws_pae_auth_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp);
|
||||
|
||||
/**
|
||||
* ws_pae_auth_cb_register register PAE authenticator callbacks
|
||||
*
|
||||
|
@ -258,9 +269,10 @@ typedef void ws_pae_auth_ip_addr_get(protocol_interface_info_entry_t *interface_
|
|||
* \param nw_key_index_set network send key index callback
|
||||
* \param nw_info_updated network keys updated callback
|
||||
* \param ip_addr_get IP addressing information callback
|
||||
* \param congestion_get congestion get callback
|
||||
*
|
||||
*/
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get);
|
||||
void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_auth_gtk_hash_set *hash_set, ws_pae_auth_nw_key_insert *nw_key_insert, ws_pae_auth_nw_key_index_set *nw_key_index_set, ws_pae_auth_nw_info_updated *nw_info_updated, ws_pae_auth_ip_addr_get *ip_addr_get, ws_pae_auth_congestion_get *congestion_get);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -268,7 +280,7 @@ void ws_pae_auth_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_
|
|||
#define ws_pae_auth_timing_adjust(timing)
|
||||
#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, nw_info_updated, ip_addr_get) {(void) hash_set;}
|
||||
#define ws_pae_auth_cb_register(interface_ptr, hash_set, nw_key_insert, nw_key_index_set, nw_info_updated, ip_addr_get, congestion_get) {(void) hash_set;}
|
||||
#define ws_pae_auth_start(interface_ptr)
|
||||
#define ws_pae_auth_gtks_updated NULL
|
||||
#define ws_pae_auth_nw_key_index_update NULL
|
||||
|
|
|
@ -88,6 +88,7 @@ typedef struct {
|
|||
ws_pae_controller_pan_ver_increment *pan_ver_increment; /**< PAN version increment callback */
|
||||
ws_pae_controller_nw_info_updated *nw_info_updated; /**< Network information updated callback */
|
||||
ws_pae_controller_auth_next_target *auth_next_target; /**< Authentication next target callback */
|
||||
ws_pae_controller_congestion_get *congestion_get; /**< Congestion get callback */
|
||||
ws_pae_controller_ip_addr_get *ip_addr_get; /**< IP address get callback */
|
||||
ws_pae_delete *pae_delete; /**< PAE delete callback */
|
||||
ws_pae_timer *pae_fast_timer; /**< PAE fast timer callback */
|
||||
|
@ -117,6 +118,7 @@ static void ws_pae_controller_keys_nw_info_init(sec_prot_keys_nw_info_t *sec_key
|
|||
static void ws_pae_controller_nw_info_updated_check(protocol_interface_info_entry_t *interface_ptr);
|
||||
#ifdef HAVE_PAE_AUTH
|
||||
static void ws_pae_controller_auth_ip_addr_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *address);
|
||||
static bool ws_pae_controller_auth_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp);
|
||||
#endif
|
||||
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);
|
||||
|
@ -238,7 +240,7 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
|
|||
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_controller_nw_info_updated_check, ws_pae_controller_auth_ip_addr_get);
|
||||
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_controller_nw_info_updated_check, ws_pae_controller_auth_ip_addr_get, ws_pae_controller_auth_congestion_get);
|
||||
|
||||
controller->auth_started = true;
|
||||
|
||||
|
@ -247,7 +249,7 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_auth_next_target *auth_next_target, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated)
|
||||
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_auth_next_target *auth_next_target, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated, ws_pae_controller_congestion_get *congestion_get)
|
||||
{
|
||||
if (!interface_ptr) {
|
||||
return -1;
|
||||
|
@ -267,6 +269,7 @@ int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_
|
|||
controller->pan_ver_increment = pan_ver_increment;
|
||||
controller->nw_info_updated = nw_info_updated;
|
||||
controller->auth_next_target = auth_next_target;
|
||||
controller->congestion_get = congestion_get;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -388,6 +391,20 @@ static void ws_pae_controller_auth_ip_addr_get(protocol_interface_info_entry_t *
|
|||
|
||||
controller->ip_addr_get(interface_ptr, address);
|
||||
}
|
||||
|
||||
static bool ws_pae_controller_auth_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp)
|
||||
{
|
||||
if (!interface_ptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
|
||||
if (!controller) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return controller->congestion_get(interface_ptr, active_supp);
|
||||
}
|
||||
#endif
|
||||
|
||||
int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid)
|
||||
|
@ -472,7 +489,6 @@ static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_
|
|||
tr_info("GTK: %s", trace_array(gtk, 16));
|
||||
tr_info("GAK: %s", trace_array(gak, 16));
|
||||
#endif
|
||||
|
||||
} else {
|
||||
tr_error("GAK generation failed network name: %s", controller->sec_keys_nw_info.network_name);
|
||||
continue;
|
||||
|
@ -675,6 +691,7 @@ int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr)
|
|||
controller->pan_ver_increment = NULL;
|
||||
controller->nw_info_updated = NULL;
|
||||
controller->auth_next_target = NULL;
|
||||
controller->congestion_get = NULL;
|
||||
|
||||
memset(&controller->sec_cfg, 0, sizeof(sec_cfg_t));
|
||||
|
||||
|
@ -685,7 +702,7 @@ int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_ptr, struct ws_sec_timer_cfg_s *sec_timer_cfg, struct ws_sec_prot_cfg_s *sec_prot_cfg)
|
||||
int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_ptr, struct ws_sec_timer_cfg_s *sec_timer_cfg, struct ws_sec_prot_cfg_s *sec_prot_cfg, struct ws_timing_cfg_s *timing_cfg)
|
||||
{
|
||||
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
|
||||
if (controller == NULL) {
|
||||
|
@ -698,9 +715,6 @@ int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_pt
|
|||
controller->sec_cfg.prot_cfg.sec_prot_trickle_params.k = 0;
|
||||
controller->sec_cfg.prot_cfg.sec_prot_trickle_params.TimerExpirations = sec_prot_cfg->sec_prot_trickle_timer_exp;
|
||||
controller->sec_cfg.prot_cfg.sec_prot_retry_timeout = sec_prot_cfg->sec_prot_retry_timeout * 10;
|
||||
|
||||
controller->sec_cfg.prot_cfg.sec_max_ongoing_authentication = sec_prot_cfg->sec_max_ongoing_authentication;
|
||||
|
||||
controller->sec_cfg.prot_cfg.initial_key_retry_delay = sec_prot_cfg->initial_key_retry_delay;
|
||||
controller->sec_cfg.prot_cfg.initial_key_trickle_params.Imin = sec_prot_cfg->initial_key_imin;
|
||||
controller->sec_cfg.prot_cfg.initial_key_trickle_params.Imax = sec_prot_cfg->initial_key_imax;
|
||||
|
@ -715,6 +729,10 @@ int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_pt
|
|||
|
||||
controller->sec_cfg.radius_cfg = pae_controller_config.radius_cfg;
|
||||
|
||||
if (timing_cfg) {
|
||||
controller->sec_cfg.timing_cfg.temp_eapol_min_timeout = timing_cfg->temp_eapol_min_timeout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1250,7 @@ int8_t ws_pae_controller_radius_address_set(int8_t interface_id, const uint8_t *
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ws_pae_controller_configure(controller->interface_ptr, NULL, NULL) < 0) {
|
||||
if (ws_pae_controller_configure(controller->interface_ptr, NULL, NULL, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1282,7 +1300,7 @@ int8_t ws_pae_controller_radius_shared_secret_set(int8_t interface_id, const uin
|
|||
|
||||
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
|
||||
if (controller) {
|
||||
ws_pae_controller_configure(controller->interface_ptr, NULL, NULL);
|
||||
ws_pae_controller_configure(controller->interface_ptr, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1335,7 +1353,7 @@ int8_t ws_pae_controller_radius_timing_set(int8_t interface_id, bbr_radius_timin
|
|||
|
||||
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
|
||||
if (controller) {
|
||||
ws_pae_controller_configure(controller->interface_ptr, NULL, NULL);
|
||||
ws_pae_controller_configure(controller->interface_ptr, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
typedef enum {
|
||||
AUTH_RESULT_OK = 0, // Successful
|
||||
AUTH_RESULT_ERR_NO_MEM = -1, // No memory
|
||||
AUTH_RESULT_ERR_TX_NO_ACK = -2, // No acknowledge was received
|
||||
AUTH_RESULT_ERR_TX_ERR = -2, // TX error (e.g. no acknowledge was received)
|
||||
AUTH_RESULT_ERR_UNSPEC = -3 // Other reason
|
||||
} auth_result_e;
|
||||
|
||||
|
@ -31,6 +31,7 @@ struct nvm_tlv_entry;
|
|||
struct ws_sec_timer_cfg_s;
|
||||
struct ws_sec_prot_cfg_s;
|
||||
struct bbr_radius_timing;
|
||||
struct ws_timing_cfg_s;
|
||||
|
||||
/**
|
||||
* ws_pae_controller_set_target sets EAPOL target for PAE supplicant
|
||||
|
@ -98,12 +99,13 @@ int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr);
|
|||
* \param interface_ptr interface
|
||||
* \param sec_timer_cfg timer configuration or NULL if not set
|
||||
* \param sec_prot_cfg protocol configuration or NULL if not set
|
||||
* \param timing_cfg timing configuration or NULL if not set
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_ptr, struct ws_sec_timer_cfg_s *sec_timer_cfg, struct ws_sec_prot_cfg_s *sec_prot_cfg);
|
||||
int8_t ws_pae_controller_configure(protocol_interface_info_entry_t *interface_ptr, struct ws_sec_timer_cfg_s *sec_timer_cfg, struct ws_sec_prot_cfg_s *sec_prot_cfg, struct ws_timing_cfg_s *timing_cfg);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_init initializes PAE supplicant
|
||||
|
@ -612,6 +614,17 @@ typedef void ws_pae_controller_pan_ver_increment(protocol_interface_info_entry_t
|
|||
*/
|
||||
typedef void ws_pae_controller_nw_info_updated(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, uint16_t pan_version, char *network_name);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_congestion_get get congestion information
|
||||
*
|
||||
* \param interface_ptr interface
|
||||
* \param active_supp active supplicants
|
||||
*
|
||||
* \return TRUE reject, FALSE accept
|
||||
*
|
||||
*/
|
||||
typedef bool ws_pae_controller_congestion_get(protocol_interface_info_entry_t *interface_ptr, uint16_t active_supp);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_cb_register register controller callbacks
|
||||
*
|
||||
|
@ -625,12 +638,13 @@ typedef void ws_pae_controller_nw_info_updated(protocol_interface_info_entry_t *
|
|||
* \param nw_frame_counter_read network frame counter read callback
|
||||
* \param pan_ver_increment PAN version increment callback
|
||||
* \param nw_info_updated network information updated callback
|
||||
* \param congestion_get congestion get callback
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_auth_next_target *auth_next_target, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated);
|
||||
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_auth_next_target *auth_next_target, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment, ws_pae_controller_nw_info_updated *nw_info_updated, ws_pae_controller_congestion_get *congestion_get);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_ip_addr_get gets IP addressing information
|
||||
|
@ -701,7 +715,7 @@ void ws_pae_controller_forced_gc(bool full_gc);
|
|||
|
||||
#define ws_pae_controller_stop(interface_ptr)
|
||||
#define ws_pae_controller_delete(interface_ptr)
|
||||
#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_cb_register(interface_ptr, completed, nw_key_set, nw_key_clear, nw_send_key_index_set, pan_ver_increment, congestion_get) 1
|
||||
#define ws_pae_controller_nvm_tlv_get(interface_ptr) NULL
|
||||
|
||||
#define ws_pae_controller_forced_gc NULL
|
||||
|
|
|
@ -193,18 +193,23 @@ supp_entry_t *ws_pae_lib_supp_list_add(supp_list_t *supp_list, const kmp_addr_t
|
|||
entry->addr.type = KMP_ADDR_EUI_64_AND_IP;
|
||||
kmp_address_copy(&entry->addr, addr);
|
||||
|
||||
ns_list_add_to_end(supp_list, entry);
|
||||
ns_list_add_to_start(supp_list, entry);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
int8_t ws_pae_lib_supp_list_remove(supp_list_t *supp_list, supp_entry_t *supp)
|
||||
int8_t ws_pae_lib_supp_list_remove(void *instance, supp_list_t *supp_list, supp_entry_t *supp, ws_pae_lib_supp_deleted supp_deleted)
|
||||
{
|
||||
ns_list_remove(supp_list, supp);
|
||||
|
||||
ws_pae_lib_supp_delete(supp);
|
||||
|
||||
ns_dyn_mem_free(supp);
|
||||
|
||||
if (supp_deleted != NULL) {
|
||||
supp_deleted(instance);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -222,11 +227,11 @@ supp_entry_t *ws_pae_lib_supp_list_entry_eui_64_get(const supp_list_t *supp_list
|
|||
void ws_pae_lib_supp_list_delete(supp_list_t *supp_list)
|
||||
{
|
||||
ns_list_foreach_safe(supp_entry_t, entry, supp_list) {
|
||||
ws_pae_lib_supp_list_remove(supp_list, entry);
|
||||
ws_pae_lib_supp_list_remove(NULL, supp_list, entry, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_list, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout)
|
||||
bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_list, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout, ws_pae_lib_supp_deleted supp_deleted)
|
||||
{
|
||||
bool timer_running = false;
|
||||
|
||||
|
@ -235,7 +240,7 @@ bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_
|
|||
if (running) {
|
||||
timer_running = true;
|
||||
} else {
|
||||
ws_pae_lib_supp_list_to_inactive(instance, active_supp_list, entry);
|
||||
ws_pae_lib_supp_list_to_inactive(instance, active_supp_list, entry, supp_deleted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +265,7 @@ void ws_pae_lib_supp_init(supp_entry_t *entry)
|
|||
memset(&entry->addr, 0, sizeof(kmp_addr_t));
|
||||
memset(&entry->sec_keys, 0, sizeof(sec_prot_keys_t));
|
||||
entry->ticks = 0;
|
||||
entry->retry_ticks = 0;
|
||||
entry->waiting_ticks = 0;
|
||||
entry->store_ticks = ws_pae_key_storage_storing_interval_get() * 1000;
|
||||
entry->active = true;
|
||||
entry->access_revoked = false;
|
||||
|
@ -283,18 +288,18 @@ bool ws_pae_lib_supp_timer_update(void *instance, supp_entry_t *entry, uint16_t
|
|||
entry->ticks -= ticks;
|
||||
} else {
|
||||
entry->ticks = 0;
|
||||
entry->retry_ticks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates retry timer
|
||||
if (entry->retry_ticks > ticks) {
|
||||
entry->retry_ticks -= ticks;
|
||||
if (entry->waiting_ticks > ticks) {
|
||||
keep_timer_running = true;
|
||||
entry->waiting_ticks -= ticks;
|
||||
} else {
|
||||
if (entry->retry_ticks > 0) {
|
||||
tr_info("EAP-TLS max ongoing delay timeout eui-64: %s", trace_array(entry->addr.eui_64, 8));
|
||||
if (entry->waiting_ticks > 0) {
|
||||
tr_info("Waiting supplicant timeout eui-64: %s", trace_array(entry->addr.eui_64, 8));
|
||||
}
|
||||
entry->retry_ticks = 0;
|
||||
entry->waiting_ticks = 0;
|
||||
}
|
||||
|
||||
if (!instance) {
|
||||
|
@ -350,7 +355,7 @@ void ws_pae_lib_supp_list_to_active(supp_list_t *active_supp_list, supp_list_t *
|
|||
entry->addr.type = KMP_ADDR_EUI_64_AND_IP;
|
||||
}
|
||||
|
||||
void ws_pae_lib_supp_list_to_inactive(void *instance, supp_list_t *active_supp_list, supp_entry_t *entry)
|
||||
void ws_pae_lib_supp_list_to_inactive(void *instance, supp_list_t *active_supp_list, supp_entry_t *entry, ws_pae_lib_supp_deleted supp_deleted)
|
||||
{
|
||||
if (!entry->active) {
|
||||
return;
|
||||
|
@ -360,7 +365,7 @@ void ws_pae_lib_supp_list_to_inactive(void *instance, supp_list_t *active_supp_l
|
|||
|
||||
if (entry->access_revoked) {
|
||||
tr_info("Access revoked; deleted, eui-64: %s", trace_array(entry->addr.eui_64, 8));
|
||||
ws_pae_lib_supp_list_remove(active_supp_list, entry);
|
||||
ws_pae_lib_supp_list_remove(instance, active_supp_list, entry, supp_deleted);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,10 +373,13 @@ void ws_pae_lib_supp_list_to_inactive(void *instance, supp_list_t *active_supp_l
|
|||
ws_pae_key_storage_supp_write(instance, entry);
|
||||
|
||||
// Remove supplicant entry
|
||||
ws_pae_lib_supp_list_remove(active_supp_list, entry);
|
||||
ws_pae_lib_supp_list_remove(instance, active_supp_list, entry, supp_deleted);
|
||||
if (supp_deleted) {
|
||||
supp_deleted(instance);
|
||||
}
|
||||
}
|
||||
|
||||
void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, uint16_t max_number, uint8_t max_purge)
|
||||
void ws_pae_lib_supp_list_purge(void *instance, supp_list_t *active_supp_list, uint16_t max_number, uint8_t max_purge, ws_pae_lib_supp_deleted supp_deleted)
|
||||
{
|
||||
uint16_t active_supp = ns_list_count(active_supp_list);
|
||||
|
||||
|
@ -385,7 +393,7 @@ void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, uint16_t max_numb
|
|||
ns_list_foreach_safe(supp_entry_t, entry, active_supp_list) {
|
||||
if (remove_count > 0 && ws_pae_lib_kmp_list_empty(&entry->kmp_list)) {
|
||||
tr_info("Active supplicant removed, eui-64: %s", trace_array(kmp_address_eui_64_get(&entry->addr), 8));
|
||||
ws_pae_lib_supp_list_remove(active_supp_list, entry);
|
||||
ws_pae_lib_supp_list_remove(instance, active_supp_list, entry, supp_deleted);
|
||||
remove_count--;
|
||||
} else {
|
||||
break;
|
||||
|
@ -394,16 +402,6 @@ void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, uint16_t max_numb
|
|||
}
|
||||
}
|
||||
|
||||
bool ws_pae_lib_supp_list_active_limit_reached(supp_list_t *active_supp_list, uint16_t max_number)
|
||||
{
|
||||
uint16_t active_supp = ns_list_count(active_supp_list);
|
||||
if (active_supp > max_number) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type)
|
||||
{
|
||||
uint16_t kmp_count = 0;
|
||||
|
@ -419,6 +417,17 @@ uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type)
|
|||
return kmp_count;
|
||||
}
|
||||
|
||||
bool ws_pae_lib_supp_list_entry_is_in_list(supp_list_t *supp_list, supp_entry_t *searched_entry)
|
||||
{
|
||||
ns_list_foreach(supp_entry_t, entry, supp_list) {
|
||||
if (entry == searched_entry) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
kmp_api_t *ws_pae_lib_supp_list_kmp_receive_check(supp_list_t *supp_list, const void *pdu, uint16_t size)
|
||||
{
|
||||
ns_list_foreach(supp_entry_t, entry, supp_list) {
|
||||
|
@ -432,22 +441,6 @@ kmp_api_t *ws_pae_lib_supp_list_kmp_receive_check(supp_list_t *supp_list, const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
supp_entry_t *ws_pae_lib_supp_list_entry_retry_timer_get(supp_list_t *supp_list)
|
||||
{
|
||||
supp_entry_t *retry_supp = NULL;
|
||||
|
||||
ns_list_foreach(supp_entry_t, entry, supp_list) {
|
||||
// Finds entry with shortest timeout i.e. oldest one
|
||||
if (entry->retry_ticks > 0) {
|
||||
if (!retry_supp || retry_supp->retry_ticks > entry->retry_ticks) {
|
||||
retry_supp = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retry_supp;
|
||||
}
|
||||
|
||||
int8_t ws_pae_lib_shared_comp_list_init(shared_comp_list_t *comp_list)
|
||||
{
|
||||
ns_list_init(comp_list);
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct supp_entry_s {
|
|||
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 */
|
||||
uint16_t waiting_ticks; /**< Waiting ticks */
|
||||
uint16_t store_ticks; /**< NVM store ticks */
|
||||
bool active : 1; /**< Is active */
|
||||
bool access_revoked : 1; /**< Nodes access is revoked */
|
||||
|
@ -211,16 +211,26 @@ void ws_pae_lib_supp_list_init(supp_list_t *supp_list);
|
|||
*/
|
||||
supp_entry_t *ws_pae_lib_supp_list_add(supp_list_t *supp_list, const kmp_addr_t *addr);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_deleted supplicant delete callback
|
||||
*
|
||||
* \param instance Instance
|
||||
*
|
||||
*/
|
||||
typedef void ws_pae_lib_supp_deleted(void *instance);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_add removes entry from supplicant list
|
||||
*
|
||||
* \param instance Instance
|
||||
* \param supp_list supplicant list
|
||||
* \param entry entry
|
||||
* \param supp_deleted callback to call on supplicant delete
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*/
|
||||
int8_t ws_pae_lib_supp_list_remove(supp_list_t *supp_list, supp_entry_t *entry);
|
||||
int8_t ws_pae_lib_supp_list_remove(void *instance, supp_list_t *supp_list, supp_entry_t *supp, ws_pae_lib_supp_deleted supp_deleted);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_entry_eui_64_get gets entry from supplicant list based on EUI-64
|
||||
|
@ -249,11 +259,12 @@ void ws_pae_lib_supp_list_delete(supp_list_t *supp_list);
|
|||
* \param inactive_supp_list list of inactive supplicants
|
||||
* \param ticks timer ticks
|
||||
* \param timeout callback to call on timeout
|
||||
* \param supp_deleted callback to call on supplicant delete
|
||||
*
|
||||
* \return true timer needs still to be running
|
||||
* \return false timer can be stopped
|
||||
*/
|
||||
bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_list, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout);
|
||||
bool ws_pae_lib_supp_list_timer_update(void *instance, supp_list_t *active_supp_list, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout, ws_pae_lib_supp_deleted supp_deleted);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_slow_timer_update updates slow timer on supplicant list
|
||||
|
@ -336,31 +347,23 @@ void ws_pae_lib_supp_list_to_active(supp_list_t *active_supp_list, supp_list_t *
|
|||
* \param instance Instance
|
||||
* \param active_supp_list list of active supplicants
|
||||
* \param entry supplicant entry
|
||||
* \param supp_deleted callback to call on supplicant delete
|
||||
*
|
||||
*/
|
||||
void ws_pae_lib_supp_list_to_inactive(void *instance, supp_list_t *active_supp_list, supp_entry_t *entry);
|
||||
void ws_pae_lib_supp_list_to_inactive(void *instance, supp_list_t *active_supp_list, supp_entry_t *entry, ws_pae_lib_supp_deleted supp_deleted);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_purge purge inactive supplicants list
|
||||
*
|
||||
* \param instance Instance
|
||||
* \param active_supp_list list of active 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
|
||||
* \param supp_deleted callback to call on supplicant delete
|
||||
*
|
||||
*/
|
||||
void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, uint16_t max_number, uint8_t max_purge);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_limit_reached_check check if active supplicant list limit has been reached
|
||||
*
|
||||
* \param active_supp_list list of active supplicants
|
||||
* \param max_number maximum number of supplicant entries
|
||||
*
|
||||
* \return true limit has been reached
|
||||
* \return false limit has not been reached
|
||||
*/
|
||||
bool ws_pae_lib_supp_list_active_limit_reached(supp_list_t *active_supp_list, uint16_t max_number);
|
||||
void ws_pae_lib_supp_list_purge(void *instance, supp_list_t *active_supp_list, uint16_t max_number, uint8_t max_purge, ws_pae_lib_supp_deleted supp_deleted);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_kmp_count counts the number of KMPs of a certain type in a list of supplicants
|
||||
|
@ -373,6 +376,17 @@ bool ws_pae_lib_supp_list_active_limit_reached(supp_list_t *active_supp_list, ui
|
|||
*/
|
||||
uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_entry_is_in_list checks if the entry is in the list
|
||||
*
|
||||
* \param supp_list list of supplicants
|
||||
* \param searched_entry entry that is searched
|
||||
*
|
||||
* \return TRUE entry is in list, FALSE otherwise
|
||||
*
|
||||
*/
|
||||
bool ws_pae_lib_supp_list_entry_is_in_list(supp_list_t *supp_list, supp_entry_t *searched_entry);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_kmp_receive_check check if received message is for this KMP in a list of supplicants
|
||||
*
|
||||
|
@ -385,16 +399,6 @@ uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type)
|
|||
*/
|
||||
kmp_api_t *ws_pae_lib_supp_list_kmp_receive_check(supp_list_t *supp_list, const void *pdu, uint16_t size);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_supp_list_entry_retry_timer_get checks if some supplicant has retry timer running
|
||||
*
|
||||
* \param supp_list list of supplicants
|
||||
*
|
||||
* \return supplicant with retry timer running or NULL if no supplicants with timer running
|
||||
*
|
||||
*/
|
||||
supp_entry_t *ws_pae_lib_supp_list_entry_retry_timer_get(supp_list_t *supp_list);
|
||||
|
||||
/**
|
||||
* ws_pae_lib_shared_comp_list_init init shared component list
|
||||
*
|
||||
|
|
|
@ -841,7 +841,7 @@ void ws_pae_supp_slow_timer(uint16_t seconds)
|
|||
}
|
||||
auth_result_e result = AUTH_RESULT_ERR_UNSPEC;
|
||||
if (pae_supp->tx_failure_on_initial_key) {
|
||||
result = AUTH_RESULT_ERR_TX_NO_ACK;
|
||||
result = AUTH_RESULT_ERR_TX_ERR;
|
||||
pae_supp->tx_failure_on_initial_key = false;
|
||||
}
|
||||
ws_pae_supp_authenticate_response(pae_supp, result);
|
||||
|
@ -1254,7 +1254,7 @@ static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e
|
|||
|
||||
/* If initial EAPOL-key message sending fails to tx no acknowledge, indicates failure so
|
||||
that bootstrap can decide if EAPOL target should be changed */
|
||||
else if (type > IEEE_802_1X_INITIAL_KEY && result == KMP_RESULT_ERR_TX_NO_ACK) {
|
||||
else if (type > IEEE_802_1X_INITIAL_KEY && (result == KMP_RESULT_ERR_TX_NO_ACK || result == KMP_RESULT_ERR_TX_UNSPEC)) {
|
||||
tr_info("Initial EAPOL-Key TX failure, target: %s", trace_array(kmp_address_eui_64_get(&pae_supp->entry.addr), 8));
|
||||
/* Fails authentication only if other authentication protocols are not yet
|
||||
started by authenticator */
|
||||
|
|
|
@ -613,6 +613,16 @@ buffer_t *ipv6_forwarding_down(buffer_t *buf)
|
|||
|
||||
/* Routing code may say it needs to tunnel to add headers - loop back to IP layer if requested */
|
||||
if (exthdr_result == IPV6_EXTHDR_MODIFY_TUNNEL) {
|
||||
|
||||
if (buffer_data_length(buf) > IPV6_MIN_LINK_MTU) {
|
||||
/* recover IP addresses that icmpv6_error needs, which routing code will have overwritten */
|
||||
buf->src_sa.addr_type = ADDR_IPV6;
|
||||
memcpy(buf->src_sa.address, buffer_data_pointer(buf) + IPV6_HDROFF_SRC_ADDR, 16);
|
||||
buf->dst_sa.addr_type = ADDR_IPV6;
|
||||
memcpy(buf->dst_sa.address, buffer_data_pointer(buf) + IPV6_HDROFF_DST_ADDR, 16);
|
||||
return icmpv6_error(buf, NULL, ICMPV6_TYPE_ERROR_PACKET_TOO_BIG, 0, IPV6_MIN_LINK_MTU);
|
||||
}
|
||||
|
||||
/* Avoid an infinite loop in the event of routing code failure - never
|
||||
* let them ask for tunnelling more than once.
|
||||
*/
|
||||
|
@ -623,6 +633,7 @@ buffer_t *ipv6_forwarding_down(buffer_t *buf)
|
|||
buf->options.tunnelled = true;
|
||||
|
||||
buf->options.ip_extflags = 0;
|
||||
buf->options.ipv6_use_min_mtu = -1;
|
||||
|
||||
/* Provide tunnel source, unless already set */
|
||||
if (buf->src_sa.addr_type == ADDR_NONE) {
|
||||
|
@ -1003,7 +1014,7 @@ static buffer_t *ipv6_consider_forwarding_unicast_packet(buffer_t *buf, protocol
|
|||
|
||||
/* route_info.pmtu will cover limits from both the interface and the
|
||||
* route. As a bonus, it will also cover any PMTUD we happen to have done
|
||||
* to that destination ourselves, as well as mop up any tunnelling issues.
|
||||
* to that destination ourselves. Extra limits due to tunnelling are checked on tunnel entry in ipv6_down.
|
||||
*/
|
||||
if (routing->route_info.pmtu < buffer_data_length(buf)) {
|
||||
buf->interface = cur;
|
||||
|
|
|
@ -57,7 +57,7 @@ typedef enum ipv6_exthdr_stage {
|
|||
* If it needs to insert headers that are not present, it can force insertion
|
||||
* into a tunnel, by:
|
||||
* setting dst_sa and src_sa appropriate for the tunnel endpoints
|
||||
* XXX does this work out okay with dest cache and PMTU?
|
||||
* src_sa.addr_type can be set to ADDR_NONE to auto-select tunnel source address
|
||||
* updating route info like next hop if necessary (probably not)
|
||||
* returning IPV6_EXTHDR_MODIFY_TUNNEL
|
||||
* During new header formation for the tunnel, IPV6_EXTHDR_INSERT will be
|
||||
|
|
|
@ -33,9 +33,9 @@ int ns_monitor_clear(void);
|
|||
|
||||
void ns_monitor_timer(uint16_t seconds);
|
||||
|
||||
int ns_monitor_heap_gc_threshold_set(uint8_t percentage_high, uint8_t percentage_critical);
|
||||
int ns_monitor_heap_gc_threshold_set(uint32_t high_min, uint32_t high_max, uint8_t high_percentage, uint32_t critical_min, uint32_t critical_max, uint8_t critical_percentage);
|
||||
|
||||
int ns_monitor_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage);
|
||||
int ns_monitor_packet_ingress_rate_limit_by_memory(uint32_t minimum_required, uint32_t Maximum_allowed, uint8_t free_heap_percentage);
|
||||
|
||||
bool ns_monitor_packet_allocation_allowed(void);
|
||||
|
||||
|
|
|
@ -52,6 +52,10 @@
|
|||
#define SOCKET_DEFAULT_STREAM_SNDLOWAT 512
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_DEFAULT_REFERENCE_LIMIT
|
||||
#define SOCKET_DEFAULT_REFERENCE_LIMIT 512
|
||||
#endif
|
||||
|
||||
typedef enum socket_family_e {
|
||||
SOCKET_FAMILY_NONE,
|
||||
SOCKET_FAMILY_IPV6,
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef struct ns_monitor__s {
|
|||
|
||||
static ns_monitor_t *ns_monitor_ptr = NULL;
|
||||
|
||||
static uint8_t ns_dyn_mem_rate_limiting_threshold_percentage = 0; // Percentage of free memory required to allow routing
|
||||
static ns_mem_heap_size_t ns_dyn_mem_rate_limiting_threshold = 0; // amount of free memory required to allow routing 0 = disabled
|
||||
|
||||
typedef void (ns_maintenance_gc_cb)(bool full_gc);
|
||||
|
||||
|
@ -176,32 +176,75 @@ int ns_monitor_clear(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ns_monitor_heap_gc_threshold_set(uint8_t percentage_high, uint8_t percentage_critical)
|
||||
int ns_monitor_heap_gc_threshold_set(uint32_t high_min, uint32_t high_max, uint8_t high_percentage, uint32_t critical_min, uint32_t critical_max, uint8_t critical_percentage)
|
||||
{
|
||||
if (ns_monitor_ptr && (percentage_critical <= 100) && (percentage_high < percentage_critical)) {
|
||||
if (ns_monitor_ptr && (critical_percentage <= 100) && (high_percentage < critical_percentage)) {
|
||||
ns_monitor_ptr->heap_high_watermark = SET_WATERMARK(
|
||||
ns_monitor_ptr->mem_stats->heap_sector_size,
|
||||
percentage_high
|
||||
high_percentage
|
||||
);
|
||||
if (ns_monitor_ptr->mem_stats->heap_sector_size - ns_monitor_ptr->heap_high_watermark < high_min) {
|
||||
ns_monitor_ptr->heap_high_watermark = ns_monitor_ptr->mem_stats->heap_sector_size - high_min;
|
||||
}
|
||||
|
||||
if (high_max && ns_monitor_ptr->mem_stats->heap_sector_size - ns_monitor_ptr->heap_high_watermark > high_max) {
|
||||
ns_monitor_ptr->heap_high_watermark = ns_monitor_ptr->mem_stats->heap_sector_size - high_max;
|
||||
}
|
||||
|
||||
ns_monitor_ptr->heap_critical_watermark = SET_WATERMARK(
|
||||
ns_monitor_ptr->mem_stats->heap_sector_size,
|
||||
percentage_critical
|
||||
critical_percentage
|
||||
);
|
||||
tr_debug("Monitor set high:%lu, critical:%lu total:%lu", (unsigned long)ns_monitor_ptr->heap_high_watermark, (unsigned long)ns_monitor_ptr->heap_critical_watermark, (unsigned long)ns_monitor_ptr->mem_stats->heap_sector_size);
|
||||
if (ns_monitor_ptr->mem_stats->heap_sector_size - ns_monitor_ptr->heap_critical_watermark < critical_min) {
|
||||
ns_monitor_ptr->heap_critical_watermark = ns_monitor_ptr->mem_stats->heap_sector_size - critical_min;
|
||||
}
|
||||
|
||||
if (critical_max && ns_monitor_ptr->mem_stats->heap_sector_size - ns_monitor_ptr->heap_critical_watermark > critical_max) {
|
||||
ns_monitor_ptr->heap_critical_watermark = ns_monitor_ptr->mem_stats->heap_sector_size - critical_max;
|
||||
}
|
||||
|
||||
tr_info("Monitor set high:%lu, critical:%lu total:%lu", (unsigned long)ns_monitor_ptr->heap_high_watermark, (unsigned long)ns_monitor_ptr->heap_critical_watermark, (unsigned long)ns_monitor_ptr->mem_stats->heap_sector_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ns_monitor_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage)
|
||||
int ns_monitor_packet_ingress_rate_limit_by_memory(uint32_t minimum_required, uint32_t Maximum_allowed, uint8_t free_heap_percentage)
|
||||
{
|
||||
if (free_heap_percentage < 100) {
|
||||
ns_dyn_mem_rate_limiting_threshold_percentage = free_heap_percentage;
|
||||
/* To make this function dynamic and useful in larger range of memories the minimum value can be given
|
||||
*
|
||||
* example limit(1024, 1)
|
||||
* 32k RAM Limit = 1024
|
||||
* 64k RAM Limit = 1024
|
||||
* 128k RAM Limit = 1280
|
||||
* 320k RAM Limit = 3200
|
||||
*/
|
||||
if (free_heap_percentage == 0 && minimum_required == 0) {
|
||||
// Disable rate limiting
|
||||
ns_dyn_mem_rate_limiting_threshold = 0;
|
||||
return 0;
|
||||
}
|
||||
if (free_heap_percentage > 100) {
|
||||
// Sanity check this should not be high at all, but dont want to limit without any good reason
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
const mem_stat_t *ns_dyn_mem_stat = ns_dyn_mem_get_mem_stat();
|
||||
if (ns_dyn_mem_stat && free_heap_percentage) {
|
||||
ns_dyn_mem_rate_limiting_threshold = ns_dyn_mem_stat->heap_sector_size / 100 * free_heap_percentage;
|
||||
}
|
||||
|
||||
if (ns_dyn_mem_rate_limiting_threshold < minimum_required) {
|
||||
ns_dyn_mem_rate_limiting_threshold = minimum_required;
|
||||
}
|
||||
|
||||
if (Maximum_allowed && ns_dyn_mem_rate_limiting_threshold > Maximum_allowed) {
|
||||
ns_dyn_mem_rate_limiting_threshold = Maximum_allowed;
|
||||
}
|
||||
tr_info("Monitor rate limit incoming packets at:%lu", (unsigned long)ns_dyn_mem_rate_limiting_threshold);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ns_monitor_packet_allocation_allowed(void)
|
||||
|
@ -212,8 +255,8 @@ bool ns_monitor_packet_allocation_allowed(void)
|
|||
|
||||
const mem_stat_t *ns_dyn_mem_stat = ns_dyn_mem_get_mem_stat();
|
||||
|
||||
if (ns_dyn_mem_stat && ns_dyn_mem_rate_limiting_threshold_percentage) {
|
||||
if (ns_dyn_mem_stat->heap_sector_allocated_bytes > ns_dyn_mem_stat->heap_sector_size / 100 * (100 - ns_dyn_mem_rate_limiting_threshold_percentage)) {
|
||||
if (ns_dyn_mem_stat && ns_dyn_mem_rate_limiting_threshold) {
|
||||
if (ns_dyn_mem_stat->heap_sector_size - ns_dyn_mem_stat->heap_sector_allocated_bytes < ns_dyn_mem_rate_limiting_threshold) {
|
||||
// Packet allocation not allowed as memory is running low.
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#define RANDOM_PORT_NUMBER_COUNT (RANDOM_PORT_NUMBER_END - RANDOM_PORT_NUMBER_START + 1)
|
||||
#define RANDOM_PORT_NUMBER_MAX_STEP 500
|
||||
|
||||
static bool socket_reference_limit(socket_t *socket_ptr);
|
||||
|
||||
static uint16_t port_counter;
|
||||
|
||||
static socket_t *socket_instance[SOCKETS_MAX];
|
||||
|
@ -113,6 +115,7 @@ socket_t *socket_pointer_get(int8_t socket)
|
|||
|
||||
static void socket_data_event_push(buffer_t *buf)
|
||||
{
|
||||
buf->socket = socket_reference(buf->socket);
|
||||
arm_event_s event = {
|
||||
.receiver = socket_event_handler,
|
||||
.sender = 0,
|
||||
|
@ -137,6 +140,7 @@ bool socket_data_queued_event_push(socket_t *socket)
|
|||
};
|
||||
|
||||
if (eventOS_event_send(&event) != 0) {
|
||||
socket_dereference(socket);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -167,12 +171,8 @@ static void socket_cb_event_run(const socket_cb_event_t *event)
|
|||
}
|
||||
}
|
||||
|
||||
void socket_buffer_cb_run(socket_t *socket, buffer_t *buffer)
|
||||
static void socket_buffer_cb_run(socket_t *socket, buffer_t *buffer)
|
||||
{
|
||||
if (socket->id == -1 || !socket->u.live.fptr) {
|
||||
buffer_free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
eventOS_scheduler_set_active_tasklet(socket->tasklet);
|
||||
|
||||
|
@ -222,9 +222,19 @@ void socket_tasklet_event_handler(arm_event_s *event)
|
|||
}
|
||||
case ARM_SOCKET_DATA_CB: {
|
||||
buffer_t *buf = event->data_ptr;
|
||||
/* Reference the socket here*/
|
||||
socket_t *socket = socket_reference(buf->socket);
|
||||
if (socket->flags & SOCKET_BUFFER_CB) {
|
||||
|
||||
if (!buf || !buf->socket) {
|
||||
tr_error("Socket CB: Buf or Socket pointer NULL");
|
||||
buffer_free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
socket_t *socket = buf->socket;
|
||||
|
||||
if (socket->id == -1 || !socket->u.live.fptr) {
|
||||
//Socket is released Free just Buffer
|
||||
buffer_free(buf);
|
||||
} else if (socket->flags & SOCKET_BUFFER_CB) {
|
||||
// They just take ownership of the buffer. No read calls.
|
||||
socket_buffer_cb_run(socket, buf);
|
||||
} else {
|
||||
|
@ -243,7 +253,9 @@ void socket_tasklet_event_handler(arm_event_s *event)
|
|||
}
|
||||
case ARM_SOCKET_DATA_QUEUED_CB: {
|
||||
socket_t *socket = event->data_ptr;
|
||||
socket_cb_run(socket);
|
||||
if (socket) {
|
||||
socket_cb_run(socket);
|
||||
}
|
||||
socket_dereference(socket);
|
||||
break;
|
||||
}
|
||||
|
@ -454,6 +466,14 @@ socket_t *socket_allocate(socket_type_t type)
|
|||
return socket;
|
||||
}
|
||||
|
||||
static bool socket_reference_limit(socket_t *socket_ptr)
|
||||
{
|
||||
if (socket_ptr && socket_ptr->refcount < SOCKET_DEFAULT_REFERENCE_LIMIT) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increase reference counter on socket, returning now-owned pointer */
|
||||
socket_t *socket_reference(socket_t *socket_ptr)
|
||||
{
|
||||
|
@ -479,7 +499,7 @@ socket_t *socket_dereference(socket_t *socket_ptr)
|
|||
}
|
||||
|
||||
if (socket_ptr->refcount == 0) {
|
||||
tr_error("ref underflow");
|
||||
tr_error("Socket %d ref underflow", socket_ptr->id);
|
||||
return NULL;
|
||||
}
|
||||
if (--socket_ptr->refcount == 0) {
|
||||
|
@ -870,6 +890,13 @@ socket_error_t socket_up(buffer_t *buf)
|
|||
goto drop;
|
||||
}
|
||||
|
||||
//Limit here
|
||||
if (socket_reference_limit(socket)) {
|
||||
tr_error("Socket reference limit drop RX %u", socket->refcount);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
|
||||
if (socket->rcvq.data_byte_limit == 0) {
|
||||
// Old-style one event per buffer
|
||||
socket_data_event_push(buf);
|
||||
|
@ -1113,6 +1140,12 @@ int16_t socket_buffer_sendmsg(int8_t sid, buffer_t *buf, const struct ns_msghdr
|
|||
// Everything below this point is non-TCP
|
||||
#endif //NO_TCP
|
||||
|
||||
if (socket_reference_limit(socket_ptr)) {
|
||||
tr_error("Socket reference limit drop TX %u", socket_ptr->refcount);
|
||||
ret_val = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark Socket id to buffer meta data
|
||||
*/
|
||||
|
|
|
@ -93,7 +93,7 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
|
|||
//Validate Client DUID
|
||||
dhcp_link_options_params_t clientDUID;
|
||||
if (libdhcpv6_get_link_address_from_duid(replyPacket->clientDUID.duid, replyPacket->clientDUID.duid_length, replyPacket->clientDUID.type, &clientDUID) == 0) {
|
||||
dhcp_allocated_address = libdhcpv6_address_allocated_list_scan(serverBase, clientDUID.link_id, clientDUID.link_type, dhcp_ia_non_temporal_params->iaId, dhcp_ia_non_temporal_params->T0, dhcp_ia_non_temporal_params->T1, allocateNew);
|
||||
dhcp_allocated_address = libdhcpv6_address_allocate(serverBase, clientDUID.link_id, clientDUID.link_type, dhcp_ia_non_temporal_params->iaId, dhcp_ia_non_temporal_params->T0, dhcp_ia_non_temporal_params->T1, allocateNew);
|
||||
}
|
||||
if (dhcp_allocated_address) {
|
||||
address_allocated = true;
|
||||
|
@ -109,7 +109,7 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
|
|||
|
||||
if (!serverBase->addCb(serverBase->interfaceId, &update_info, serverBase->guaPrefix)) {
|
||||
address_allocated = false;
|
||||
libdhcpv6_address_rm_from_allocated_list(serverBase, dhcp_allocated_address->nonTemporalAddress);
|
||||
libdhcpv6_address_delete(serverBase, dhcp_allocated_address->nonTemporalAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,9 +299,9 @@ void DHCPv6_server_service_delete(int8_t interface, uint8_t guaPrefix[static 8],
|
|||
ns_list_foreach_safe(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
//Delete Server data base
|
||||
if (serverInfo->removeCb) {
|
||||
uint8_t allocated_address[16];
|
||||
libdhcpv6_allocated_address_write(allocated_address, cur, serverInfo);
|
||||
serverInfo->removeCb(interface, allocated_address, NULL);
|
||||
uint8_t ipAddress[16];
|
||||
libdhcpv6_allocated_address_write(ipAddress, cur, serverInfo);
|
||||
serverInfo->removeCb(interface, ipAddress, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,12 +327,19 @@ void DHCPv6_server_service_delete(int8_t interface, uint8_t guaPrefix[static 8],
|
|||
|
||||
/* Control GUA address for client by DUI.Default value is true
|
||||
*
|
||||
* Anonymous and disable address list can optimize either
|
||||
* Using 16 bit suffix to optimize data amount in network
|
||||
* and having list of assigned addresses meaning larger RAM usage at border router
|
||||
*
|
||||
* or Using SLAAC type address generation and not have a list of addresses at Border router
|
||||
* -> Less RAM usage, but more bandwidth used
|
||||
*
|
||||
* /param interface interface id of this thread instance.
|
||||
* /param guaPrefix Prefix which will be removed
|
||||
* /param mode true trig autonous mode, false define address by default suffics + client id
|
||||
* /param mode true assign addresses anonymously. false define address by Prefix + client id
|
||||
* /param disable_address_list Dont keep track of assigned Addresses (Can't be used if anonymous)
|
||||
*/
|
||||
int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t guaPrefix[static 16], bool mode, bool autonomous_skip_list)
|
||||
int DHCPv6_server_service_set_address_generation_anonymous(int8_t interface, uint8_t guaPrefix[static 16], bool mode, bool disable_address_list)
|
||||
{
|
||||
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
||||
if (!serverInfo) {
|
||||
|
@ -340,12 +347,13 @@ int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t gu
|
|||
|
||||
}
|
||||
|
||||
serverInfo->enableAddressAutonous = mode;
|
||||
serverInfo->anonymousAddress = mode;
|
||||
if (mode) {
|
||||
serverInfo->disableAddressListAllocation = autonomous_skip_list;
|
||||
serverInfo->disableAddressList = disable_address_list;
|
||||
} else {
|
||||
serverInfo->disableAddressListAllocation = false;
|
||||
serverInfo->disableAddressList = false;
|
||||
}
|
||||
tr_info("DHCPv6 %s, address list %s", mode ? "anonymous address" : "address mode SLAAC", disable_address_list ? "Not Stored" : "Stored");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -375,6 +383,7 @@ int DHCPv6_server_service_duid_update(int8_t interface, uint8_t guaPrefix[static
|
|||
if (!serverInfo) {
|
||||
return -1;
|
||||
}
|
||||
tr_info("DHCPv6 duid %s", trace_array(duid_ptr, duid_length));
|
||||
|
||||
return libdhcpv6_server_duid_set(serverInfo, duid_ptr, duid_type, duid_length);
|
||||
}
|
||||
|
@ -399,6 +408,7 @@ int DHCPv6_server_service_set_max_clients_accepts_count(int8_t interface, uint8_
|
|||
}
|
||||
|
||||
serverInfo->maxSupportedClients = maxClientCount;
|
||||
tr_info("DHCPv6 maximum clients %"PRIu32, serverInfo->maxSupportedClients);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -421,6 +431,7 @@ int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t gu
|
|||
return -1;
|
||||
}
|
||||
serverInfo->validLifetime = validLifeTimne;
|
||||
tr_info("DHCPv6 Valid lifetime %"PRIu32, serverInfo->validLifetime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -510,7 +521,7 @@ void DHCPv6_server_service_timeout_cb(uint32_t timeUpdateInSeconds)
|
|||
{
|
||||
(void) timeUpdateInSeconds;
|
||||
}
|
||||
int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t guaPrefix[static 16], bool mode, bool autonomous_skip_list)
|
||||
int DHCPv6_server_service_set_address_generation_anonymous(int8_t interface, uint8_t guaPrefix[static 16], bool mode, bool autonomous_skip_list)
|
||||
{
|
||||
(void) interface;
|
||||
(void) guaPrefix;
|
||||
|
|
|
@ -62,13 +62,19 @@ void DHCPv6_server_service_timeout_cb(uint32_t timeUpdateInSeconds);
|
|||
|
||||
/* Control GUA address for client by DUI.Default value is true
|
||||
*
|
||||
* Anonymous and disable address list can optimize either
|
||||
* Using 16 bit suffix to optimize data amount in network
|
||||
* and having list of assigned addresses meaning larger RAM usage at border router
|
||||
*
|
||||
* or Using SLAAC type address generation and not have a list of addresses at Border router
|
||||
* -> Less RAM usage, but more bandwidth used
|
||||
*
|
||||
* /param interface interface id of this thread instance.
|
||||
* /param guaPrefix Prefix which will be removed
|
||||
* /param mode true trig autonous mode, false define address by default suffics + client id
|
||||
* /param autonomous_skip_list true skip address list allocation when autonous mode is selected
|
||||
* /param mode true assign addresses anonymously. false define address by Prefix + client id
|
||||
* /param disable_address_list Dont keep track of assigned Addresses (Can't be used if anonymous)
|
||||
*/
|
||||
int DHCPv6_server_service_set_address_autonous_flag(int8_t interface, uint8_t guaPrefix[static 16], bool mode, bool autonomous_skip_list);
|
||||
int DHCPv6_server_service_set_address_generation_anonymous(int8_t interface, uint8_t guaPrefix[static 16], bool mode, bool autonomous_skip_list);
|
||||
|
||||
|
||||
/* SET max accepted clients to server, Default is 200
|
||||
|
|
|
@ -91,6 +91,8 @@ typedef struct mac_pre_build_frame {
|
|||
uint8_t csma_periods_left;
|
||||
uint8_t fhss_retry_count;
|
||||
uint8_t fhss_cca_retry_count;
|
||||
uint8_t stored_retry_cnt;
|
||||
uint8_t stored_cca_cnt;
|
||||
uint16_t initial_tx_channel;
|
||||
uint32_t tx_time;
|
||||
bool upper_layer_request: 1;
|
||||
|
@ -102,6 +104,7 @@ typedef struct mac_pre_build_frame {
|
|||
bool WaitResponse: 1;
|
||||
unsigned security_mic_len: 5; //Max possible lengths 0, 4, 8, 16 bytes
|
||||
unsigned priority: 2;
|
||||
unsigned stored_priority: 2;
|
||||
struct mac_pre_build_frame *next; //Pointer for queue purpose
|
||||
} mac_pre_build_frame_t;
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ typedef enum mac_event_t {
|
|||
MAC_TX_TIMEOUT,
|
||||
MAC_ACK_SECURITY_FAIL,
|
||||
MAC_UNKNOWN_DESTINATION,
|
||||
MAC_TX_PRECOND_FAIL
|
||||
MAC_TX_PRECOND_FAIL,
|
||||
MAC_RETURN_TO_QUEUE
|
||||
} mac_event_t;
|
||||
|
||||
typedef enum mac_tx_status_type_t {
|
||||
|
|
|
@ -1507,11 +1507,16 @@ static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr,
|
|||
mcps_data_conf_t confirm;
|
||||
if (rf_ptr->fhss_api && !buffer->asynch_request) {
|
||||
// FHSS checks if this failed buffer needs to be pushed back to TX queue and retransmitted
|
||||
if (!mcps_buffer_edfe_data_failure(rf_ptr, buffer) && ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL))) {
|
||||
if (rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), rf_ptr->mac_tx_start_channel) == true) {
|
||||
|
||||
if (!mcps_buffer_edfe_data_failure(rf_ptr, buffer) && ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL) || (rf_ptr->mac_tx_result == MAC_RETURN_TO_QUEUE))) {
|
||||
if ((rf_ptr->mac_tx_result == MAC_RETURN_TO_QUEUE) || rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), rf_ptr->mac_tx_start_channel) == true) {
|
||||
if (rf_ptr->mac_tx_result == MAC_TX_FAIL) {
|
||||
buffer->fhss_retry_count += 1 + rf_ptr->mac_tx_status.retry;
|
||||
} else if (rf_ptr->mac_tx_result == MAC_RETURN_TO_QUEUE) {
|
||||
buffer->stored_retry_cnt = rf_ptr->mac_tx_retry;
|
||||
buffer->stored_cca_cnt = rf_ptr->mac_cca_retry;
|
||||
buffer->stored_priority = buffer->priority;
|
||||
// Use priority to transmit it first when proper channel is available
|
||||
buffer->priority = MAC_PD_DATA_TX_IMMEDIATELY;
|
||||
} else {
|
||||
buffer->fhss_retry_count += rf_ptr->mac_tx_status.retry;
|
||||
}
|
||||
|
@ -2135,8 +2140,16 @@ static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, ma
|
|||
rf_ptr->macTxRequestAck = false;
|
||||
|
||||
memset(&(rf_ptr->mac_tx_status), 0, sizeof(mac_tx_status_t));
|
||||
rf_ptr->mac_cca_retry = 0;
|
||||
rf_ptr->mac_tx_retry = 0;
|
||||
if (buffer->priority == MAC_PD_DATA_TX_IMMEDIATELY) {
|
||||
// Return original priority and retry/CCA counts
|
||||
buffer->priority = buffer->stored_priority;
|
||||
rf_ptr->mac_tx_retry = rf_ptr->mac_tx_status.retry = buffer->stored_retry_cnt;
|
||||
rf_ptr->mac_cca_retry = rf_ptr->mac_tx_status.cca_cnt = buffer->stored_cca_cnt;
|
||||
buffer->stored_retry_cnt = buffer->stored_cca_cnt = 0;
|
||||
} else {
|
||||
rf_ptr->mac_tx_retry = 0;
|
||||
rf_ptr->mac_cca_retry = 0;
|
||||
}
|
||||
rf_ptr->mac_tx_start_channel = rf_ptr->mac_channel;
|
||||
mac_csma_param_init(rf_ptr);
|
||||
if (mcps_generic_packet_build(rf_ptr, buffer) != 0) {
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef enum {
|
|||
#define MAC_PD_DATA_NORMAL_PRIORITY 0 //Normal MCPS DATA REQ
|
||||
#define MAC_PD_DATA_MEDIUM_PRIORITY 1 //Indirect Data which is polled
|
||||
#define MAC_PD_DATA_HIGH_PRIOTITY 2 //Beacon request Beacon response
|
||||
#define MAC_PD_DATA_TX_IMMEDIATELY 3 //Only for packets whose transmission was interrupted by wrong channel type. E.g. unicast on broadcast channel.
|
||||
|
||||
#define MCPS_SAP_DATA_IND_EVENT 1
|
||||
#define MCPS_SAP_DATA_CNF_EVENT 2
|
||||
|
|
|
@ -189,6 +189,9 @@ int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|||
length = tx_buf->len;
|
||||
}
|
||||
if (dev_driver->tx(buffer, length, 1, PHY_LAYER_PAYLOAD) == 0) {
|
||||
#ifdef TIMING_TOOL_TRACES
|
||||
tr_info("%u CSMA_start", mac_mcps_sap_get_phy_timestamp(rf_mac_setup));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -451,9 +454,13 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef TIMING_TOOL_TRACES
|
||||
if ((status == PHY_LINK_CCA_FAIL) || (status == PHY_LINK_CCA_PREPARE)) {
|
||||
tr_info("%u CSMA_done", mac_mcps_sap_get_phy_timestamp(rf_ptr));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (status == PHY_LINK_CCA_PREPARE) {
|
||||
|
||||
|
||||
if (rf_ptr->mac_ack_tx_active || rf_ptr->mac_edfe_tx_active) {
|
||||
goto VALIDATE_TX_TIME;
|
||||
}
|
||||
|
@ -485,10 +492,12 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
|||
mac_sap_cca_fail_cb(rf_ptr, 0xffff);
|
||||
return PHY_TX_NOT_ALLOWED;
|
||||
}
|
||||
// When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back
|
||||
// to queue by using CCA fail event
|
||||
// When FHSS TX handle returns -3, we are trying to:
|
||||
// - transmit broadcast packet on unicast channel
|
||||
// - transmit unicast packet on broadcast channel
|
||||
// Push back to queue to allow sending applicable packet
|
||||
if (tx_handle_retval == -3) {
|
||||
mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL);
|
||||
mac_tx_done_state_set(rf_ptr, MAC_RETURN_TO_QUEUE);
|
||||
return PHY_TX_NOT_ALLOWED;
|
||||
} else if (tx_handle_retval == -2) {
|
||||
mac_tx_done_state_set(rf_ptr, MAC_UNKNOWN_DESTINATION);
|
||||
|
@ -505,6 +514,9 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
|
|||
active_buf->csma_periods_left--;
|
||||
active_buf->tx_time += rf_ptr->multi_cca_interval;
|
||||
mac_pd_sap_set_phy_tx_time(rf_ptr, active_buf->tx_time, true);
|
||||
#ifdef TIMING_TOOL_TRACES
|
||||
tr_info("%u CSMA_start", mac_mcps_sap_get_phy_timestamp(rf_ptr));
|
||||
#endif
|
||||
return PHY_RESTART_CSMA;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1065,6 +1065,7 @@ static buffer_t *mpl_exthdr_provider(buffer_t *buf, ipv6_exthdr_stage_t stage, i
|
|||
if (!domain) {
|
||||
// We will need to tunnel - do nothing on the inner packet
|
||||
*result = 0;
|
||||
buf->options.ipv6_use_min_mtu = 1;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -452,6 +452,9 @@ rpl_domain_t *rpl_control_create_domain(void)
|
|||
ns_list_init(&domain->instances);
|
||||
domain->non_storing_downstream_interface = -1;
|
||||
domain->callback = NULL;
|
||||
domain->new_parent_add = NULL;
|
||||
domain->parent_dis = NULL;
|
||||
domain->prefix_cb = NULL;
|
||||
domain->cb_handle = NULL;
|
||||
domain->force_leaf = false;
|
||||
domain->process_routes = true;
|
||||
|
@ -528,12 +531,13 @@ void rpl_control_free_domain_instances_from_interface(protocol_interface_info_en
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
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, rpl_parent_dis_callback_t parent_dis, void *cb_handle)
|
||||
{
|
||||
domain->callback = callback;
|
||||
domain->prefix_cb = prefix_learn_cb;
|
||||
domain->cb_handle = cb_handle;
|
||||
domain->new_parent_add = new_parent_add;
|
||||
domain->parent_dis = parent_dis;
|
||||
}
|
||||
|
||||
/* To do - this should live somewhere nicer. Basically a bootstrap
|
||||
|
@ -562,6 +566,11 @@ bool rpl_control_have_dodag(rpl_domain_t *domain)
|
|||
|
||||
typedef void rpl_control_predicate_loop_fn_t(rpl_instance_t *instance, rpl_dodag_version_t *version, void *arg);
|
||||
|
||||
typedef struct rpl_loopfn_trigger_unicast_dio_arg {
|
||||
struct protocol_interface_info_entry *interface;
|
||||
const uint8_t *dst;
|
||||
} rpl_loopfn_trigger_unicast_dio_arg_t;
|
||||
|
||||
/* Callbacks for rpl_control_predicate_loop */
|
||||
|
||||
static void rpl_loopfn_reset_dio_timer(rpl_instance_t *instance, rpl_dodag_version_t *dodag_version, void *handle)
|
||||
|
@ -570,12 +579,19 @@ static void rpl_loopfn_reset_dio_timer(rpl_instance_t *instance, rpl_dodag_versi
|
|||
(void)handle;
|
||||
|
||||
rpl_instance_inconsistency(instance);
|
||||
}
|
||||
//Check was Multicast DIS from parent
|
||||
rpl_loopfn_trigger_unicast_dio_arg_t *arg = handle;
|
||||
rpl_domain_t *domain = arg->interface->rpl_domain;
|
||||
if (domain && domain->parent_dis) {
|
||||
|
||||
typedef struct rpl_loopfn_trigger_unicast_dio_arg {
|
||||
struct protocol_interface_info_entry *interface;
|
||||
const uint8_t *dst;
|
||||
} rpl_loopfn_trigger_unicast_dio_arg_t;
|
||||
if (rpl_instance_address_is_parent(instance, arg->dst)) {
|
||||
// Call Multicast DIS parent Callback
|
||||
domain->parent_dis(arg->dst, arg->interface, instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void rpl_loopfn_trigger_unicast_dio(rpl_instance_t *instance, rpl_dodag_version_t *dodag_version, void *handle)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef void rpl_prefix_callback_t(struct prefix_entry_t *prefix, void *handle,
|
|||
|
||||
typedef bool rpl_new_parent_callback_t(uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance, uint16_t candidate_rank);
|
||||
|
||||
typedef void rpl_parent_dis_callback_t(const uint8_t *ll_parent_address, void *handle, struct rpl_instance *instance);
|
||||
|
||||
typedef struct rpl_route_info {
|
||||
uint8_t node[8]; /* IID of parent in parent child relation table */
|
||||
uint8_t parent[8]; /* IID of child in parent child relation table */
|
||||
|
@ -65,6 +67,7 @@ typedef struct rpl_domain {
|
|||
rpl_domain_callback_t *callback;
|
||||
rpl_prefix_callback_t *prefix_cb;
|
||||
rpl_new_parent_callback_t *new_parent_add;
|
||||
rpl_parent_dis_callback_t *parent_dis;
|
||||
void *cb_handle;
|
||||
} rpl_domain_t;
|
||||
|
||||
|
@ -159,7 +162,7 @@ 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_free_domain_instances_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, rpl_new_parent_callback_t new_parent_add, 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, rpl_parent_dis_callback_t parent_dis, void *cb_handle);
|
||||
|
||||
/* Target publishing */
|
||||
void rpl_control_publish_host_address(rpl_domain_t *domain, const uint8_t addr[16], uint32_t lifetime);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "RPL/rpl_structures.h"
|
||||
#include "RPL/rpl_policy.h"
|
||||
#include "RPL/rpl_data.h"
|
||||
#include "6LoWPAN/ws/ws_common.h"
|
||||
|
||||
#define TRACE_GROUP "RPLa"
|
||||
|
||||
|
@ -373,6 +374,7 @@ static buffer_t *rpl_data_exthdr_provider_hbh_2(buffer_t *buf, rpl_instance_t *i
|
|||
case IPV6_EXTHDR_INSERT: {
|
||||
if (!destination_in_instance) {
|
||||
/* We don't add a header - we'll do it on the tunnel */
|
||||
buf->options.ipv6_use_min_mtu = 1;
|
||||
*result = 0;
|
||||
return buf;
|
||||
}
|
||||
|
@ -964,6 +966,7 @@ static buffer_t *rpl_data_exthdr_provider_srh(buffer_t *buf, ipv6_exthdr_stage_t
|
|||
if (!buf->options.tunnelled) {
|
||||
if (stage == IPV6_EXTHDR_SIZE || stage == IPV6_EXTHDR_INSERT) {
|
||||
*result = 0;
|
||||
buf->options.ipv6_use_min_mtu = 1;
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
@ -1054,6 +1057,11 @@ drop:
|
|||
|
||||
buf->options.ip_extflags |= IPEXT_SRH_RPL;
|
||||
|
||||
if (ws_info(cur)) {
|
||||
//Call SRC route header handler hook to Wi-SUN refresh border router alive
|
||||
ws_common_border_router_alive_update(cur);
|
||||
}
|
||||
|
||||
uint16_t hlen = (ptr[1] + 1) * 8;
|
||||
uint8_t segs_left = ptr[3];
|
||||
|
||||
|
|
|
@ -1602,6 +1602,45 @@ void rpl_instance_remove_interface(rpl_instance_t *instance, int8_t if_id)
|
|||
}
|
||||
}
|
||||
|
||||
static bool rpl_instance_parent_selected(rpl_instance_t *instance)
|
||||
{
|
||||
if (rpl_instance_am_root(instance)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We don't have DAO target generated
|
||||
if (ns_list_count(&instance->dao_targets) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't have any valid parent selected
|
||||
if (!rpl_instance_parent_selection_ready(instance)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rpl_instance_dao_route_registered(rpl_instance_t *instance)
|
||||
{
|
||||
if (rpl_instance_am_root(instance)) {
|
||||
//Border router is allways at stable state
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Address registrations for parent ongoing*/
|
||||
if (rpl_policy_parent_confirmation_requested() && instance->pending_neighbour_confirmation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If we are waiting for DAO or DAO registration is needed we dont send periodic DIOs */
|
||||
if (instance->dao_in_transit || instance->delay_dao_timer > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Trigger DIO transmission - all interfaces multicast if addr+cur are NULL, else unicast */
|
||||
void rpl_instance_dio_trigger(rpl_instance_t *instance, protocol_interface_info_entry_t *cur, const uint8_t *addr)
|
||||
{
|
||||
|
@ -1638,6 +1677,13 @@ void rpl_instance_dio_trigger(rpl_instance_t *instance, protocol_interface_info_
|
|||
rpl_dodag_conf_t *conf;
|
||||
if (addr) {
|
||||
conf = &dodag->config;
|
||||
//Unicast
|
||||
if (rank != RPL_RANK_INFINITE) {
|
||||
if (!rpl_instance_parent_selected(instance)) {
|
||||
tr_debug("parent selection not ready. DIO rank INFINITE");
|
||||
rank = RPL_RANK_INFINITE;
|
||||
}
|
||||
}
|
||||
} else if (dodag->new_config_advertisment_count < rpl_policy_dio_multicast_config_advertisment_min_count()) {
|
||||
conf = &dodag->config;
|
||||
if (dodag->new_config_advertisment_count < 0xfe) {
|
||||
|
@ -1649,6 +1695,10 @@ void rpl_instance_dio_trigger(rpl_instance_t *instance, protocol_interface_info_
|
|||
|
||||
rpl_control_transmit_dio(instance->domain, cur, instance->id, dodag_version->number, rank, dodag->g_mop_prf, instance->dtsn, dodag, dodag->id, conf, addr);
|
||||
|
||||
if (addr) {
|
||||
return;
|
||||
}
|
||||
|
||||
dodag_version->last_advertised_rank = rank;
|
||||
|
||||
/* When we advertise a new lowest rank, need to re-evaluate our rank limits */
|
||||
|
@ -1728,8 +1778,10 @@ void rpl_instance_set_local_repair(rpl_instance_t *instance, bool repair)
|
|||
instance->repair_dis_count = 0;
|
||||
} else {
|
||||
instance->repair_dis_timer = 0;
|
||||
instance->advertised_dodag_membership_since_last_repair = false;
|
||||
|
||||
}
|
||||
//SET False allways for guarantee reboot possibility
|
||||
instance->advertised_dodag_membership_since_last_repair = false;
|
||||
|
||||
/* When repair ends, eliminate all higher-rank neighbours (potential sub-DODAG) from table */
|
||||
if (!repair && instance->current_dodag_version) {
|
||||
|
@ -1855,21 +1907,12 @@ void rpl_upward_dio_timer(rpl_instance_t *instance, uint16_t ticks)
|
|||
/* Important to always send DIOs if we ever have sent any, so we can indicate problems to others */
|
||||
if (!rpl_instance_am_root(instance) && !instance->poison_count && !instance->advertised_dodag_membership_since_last_repair && rpl_policy_parent_confirmation_requested()) {
|
||||
|
||||
// We don't have DAO target generated
|
||||
if (ns_list_count(&instance->dao_targets) == 0) {
|
||||
//Validate Parent is selected and registered
|
||||
if (!rpl_instance_parent_selected(instance)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't have any valid parent selected
|
||||
if (!rpl_instance_parent_selection_ready(instance)) {
|
||||
return;
|
||||
}
|
||||
/* Address registrations for parent ongoing*/
|
||||
if (instance->pending_neighbour_confirmation) {
|
||||
return;
|
||||
}
|
||||
/* If we are waiting for DAO or DAO registration is needed we dont send periodic DIOs */
|
||||
if (instance->dao_in_transit || instance->delay_dao_timer > 0) {
|
||||
//Verify that DAO is registered
|
||||
if (!rpl_instance_dao_route_registered(instance)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ typedef enum {
|
|||
typedef enum {
|
||||
KMP_RESULT_OK = 0, // Successful
|
||||
KMP_RESULT_ERR_NO_MEM = -1, // No memory
|
||||
KMP_RESULT_ERR_TX_NO_ACK = -2, // No acknowledge was received
|
||||
KMP_RESULT_ERR_UNSPEC = -3 // Other reason
|
||||
KMP_RESULT_ERR_TX_NO_ACK = -2, // No TX acknowledge was received
|
||||
KMP_RESULT_ERR_TX_UNSPEC = -3 // Other TX reason
|
||||
} kmp_result_e;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -324,7 +324,7 @@ static int8_t key_sec_prot_tx_status_ind(sec_prot_t *prot, sec_prot_tx_status_e
|
|||
sec_prot_result_set(&data->common, SEC_RESULT_ERR_TX_NO_ACK);
|
||||
} else if (tx_status != SEC_PROT_TX_OK) {
|
||||
// Indicates other failure
|
||||
sec_prot_result_set(&data->common, SEC_RESULT_ERR_UNSPEC);
|
||||
sec_prot_result_set(&data->common, SEC_RESULT_ERR_TX_UNSPEC);
|
||||
}
|
||||
prot->state_machine_call(prot);
|
||||
return 0;
|
||||
|
|
|
@ -31,7 +31,7 @@ typedef enum {
|
|||
SEC_RESULT_OK = 0,
|
||||
SEC_RESULT_ERR_NO_MEM = -1,
|
||||
SEC_RESULT_ERR_TX_NO_ACK = -2,
|
||||
SEC_RESULT_ERR_UNSPEC = -3,
|
||||
SEC_RESULT_ERR_TX_UNSPEC = -3,
|
||||
SEC_RESULT_TIMEOUT = -4,
|
||||
SEC_RESULT_ERROR = -5,
|
||||
SEC_RESULT_CONF_ERROR = -6,
|
||||
|
|
|
@ -23,10 +23,11 @@
|
|||
typedef struct sec_prot_cfg_s {
|
||||
trickle_params_t sec_prot_trickle_params;
|
||||
uint16_t sec_prot_retry_timeout;
|
||||
uint16_t sec_max_ongoing_authentication;
|
||||
uint16_t initial_key_retry_delay;
|
||||
trickle_params_t initial_key_trickle_params;
|
||||
uint8_t initial_key_retry_cnt;
|
||||
uint8_t max_ongoing_auth_constant;
|
||||
uint16_t max_ongoing_auth_size_scaler;
|
||||
} sec_prot_cfg_t;
|
||||
|
||||
/* Security timer configuration settings */
|
||||
|
@ -53,9 +54,14 @@ typedef struct sec_radius_cfg_s {
|
|||
bool radius_addr_set : 1; /**< Radius server address is set */
|
||||
} sec_radius_cfg_t;
|
||||
|
||||
typedef struct sec_timing_cfg_s {
|
||||
uint16_t temp_eapol_min_timeout; /**< Temporary neighbor link minimum timeout; seconds; default 330 */
|
||||
} sec_timing_cfg_t;
|
||||
|
||||
typedef struct sec_cfg_s {
|
||||
sec_prot_cfg_t prot_cfg;
|
||||
sec_timer_cfg_t timer_cfg;
|
||||
sec_timing_cfg_t timing_cfg;
|
||||
sec_radius_cfg_t *radius_cfg;
|
||||
} sec_cfg_t;
|
||||
|
||||
|
|
|
@ -348,7 +348,7 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
|
|||
}
|
||||
|
||||
if (fhss_structure->ws->is_on_bc_channel == false) {
|
||||
fhss_ws_start_timer(fhss_structure, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (delay_us * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
|
||||
fhss_ws_start_timer(fhss_structure, MS_TO_US(fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - ((int64_t) delay_us * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
|
||||
fhss_structure->ws->is_on_bc_channel = true;
|
||||
next_channel = fhss_structure->ws->bc_channel = fhss_ws_calc_bc_channel(fhss_structure);
|
||||
|
||||
|
@ -621,7 +621,7 @@ static int fhss_ws_tx_handle_callback(const fhss_api_t *api, bool is_broadcast_a
|
|||
}
|
||||
// Do not allow unicast destination on broadcast channel
|
||||
if (!is_broadcast_addr && (fhss_structure->ws->is_on_bc_channel == true)) {
|
||||
return -1;
|
||||
return -3;
|
||||
}
|
||||
// Check TX/RX slot
|
||||
if (!fhss_ws_check_tx_allowed(fhss_structure)) {
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
|
||||
int ns_conf_gc_threshold_set(uint8_t percentage_high, uint8_t percentage_critical)
|
||||
{
|
||||
return ns_monitor_heap_gc_threshold_set(percentage_high, percentage_critical);
|
||||
return ns_monitor_heap_gc_threshold_set(0, 0, percentage_high, 0, 0, percentage_critical);
|
||||
}
|
||||
|
||||
int ns_conf_packet_ingress_rate_limit_by_mem(uint8_t free_heap_percentage)
|
||||
{
|
||||
return ns_monitor_packet_ingress_rate_limit_by_memory(free_heap_percentage);
|
||||
return ns_monitor_packet_ingress_rate_limit_by_memory(0, 0, free_heap_percentage);
|
||||
}
|
||||
|
|
|
@ -1195,17 +1195,6 @@ static const bool ipv6_route_probing[ROUTE_MAX] = {
|
|||
[ROUTE_RPL_INSTANCE] = true,
|
||||
};
|
||||
|
||||
/* Which route types get minimum link MTU by default */
|
||||
/* Makes life easier for tunnel-based systems like RPL */
|
||||
static const bool ipv6_route_min_mtu[ROUTE_MAX] = {
|
||||
[ROUTE_RPL_DAO] = true,
|
||||
[ROUTE_RPL_DAO_SR] = true,
|
||||
[ROUTE_RPL_DIO] = true,
|
||||
[ROUTE_RPL_ROOT] = true,
|
||||
[ROUTE_RPL_INSTANCE] = true,
|
||||
[ROUTE_MPL] = true,
|
||||
};
|
||||
|
||||
// Remember when a route source has deleted an entry - allows buffers still in
|
||||
// event queue to have their route info invalidated.
|
||||
static bool ipv6_route_source_invalidated[ROUTE_MAX];
|
||||
|
@ -1647,7 +1636,7 @@ ipv6_route_t *ipv6_route_add_metric(const uint8_t *prefix, uint8_t prefix_len, i
|
|||
route->info.info = info;
|
||||
route->info.source_id = source_id;
|
||||
route->info.interface_id = interface_id;
|
||||
route->info.pmtu = ipv6_route_min_mtu[source] ? IPV6_MIN_LINK_MTU : 0xFFFF;
|
||||
route->info.pmtu = 0xFFFF;
|
||||
if (next_hop) {
|
||||
route->on_link = false;
|
||||
memcpy(route->info.next_hop_addr, next_hop, 16);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#ifdef HAVE_DHCPV6_SERVER
|
||||
|
||||
#define TRACE_GROUP "dhcp"
|
||||
|
||||
static NS_LARGE NS_LIST_DEFINE(dhcpv6_gua_server_list, dhcpv6_gua_server_entry_s, link);
|
||||
|
||||
bool libdhcpv6_gua_server_list_empty(void)
|
||||
|
@ -49,10 +51,9 @@ static dhcpv6_gua_server_entry_s *libdhcpv6_server_entry_allocate(void)
|
|||
}
|
||||
entry->serverDynamic_DUID = server_duid_ptr;
|
||||
entry->serverDynamic_DUID_length = 16;
|
||||
entry->firstFreedId = 0;
|
||||
entry->firstUnusedId = DHCP_ADDRESS_ID_START;
|
||||
entry->enableAddressAutonous = true;
|
||||
entry->disableAddressListAllocation = false;
|
||||
entry->anonymousAddress = false;
|
||||
entry->disableAddressList = false;
|
||||
entry->maxSupportedClients = 200;
|
||||
entry->validLifetime = 7200;
|
||||
entry->removeCb = NULL;
|
||||
|
@ -63,47 +64,34 @@ static dhcpv6_gua_server_entry_s *libdhcpv6_server_entry_allocate(void)
|
|||
return entry;
|
||||
}
|
||||
|
||||
static uint16_t libdhcpv6_get_next_freed_id(dhcpv6_gua_server_entry_s *serverInfo)
|
||||
static uint16_t libdhcpv6_get_unique_id(dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
uint16_t last_allocated_id = DHCP_ADDRESS_ID_START - 1;
|
||||
ns_list_foreach(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
uint8_t suggested_id = serverInfo->firstUnusedId;
|
||||
|
||||
if (last_allocated_id + 1 == cur->allocatedID) {
|
||||
//Last and current plus 1 so normal order
|
||||
last_allocated_id = cur->allocatedID;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cur->allocatedID - last_allocated_id) == 2) {
|
||||
//one missing sequence between last and current
|
||||
if (last_allocated_id + 1 == serverInfo->firstFreedId) {
|
||||
//Skip Current freedID this will update after this call to new one
|
||||
last_allocated_id = cur->allocatedID;
|
||||
continue;
|
||||
do {
|
||||
ns_list_foreach(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
if (serverInfo->firstUnusedId == cur->allocatedID) {
|
||||
serverInfo->firstUnusedId++;
|
||||
if (serverInfo->firstUnusedId == 0) {
|
||||
serverInfo->firstUnusedId++;
|
||||
}
|
||||
//Start from beginning
|
||||
break;
|
||||
}
|
||||
} else if (last_allocated_id + 1 == serverInfo->firstFreedId) {
|
||||
//Skip first if it is last freedId
|
||||
return last_allocated_id + 2;
|
||||
}
|
||||
|
||||
return last_allocated_id + 1;
|
||||
}
|
||||
//No more freed ID so return 0
|
||||
return 0;
|
||||
} while (suggested_id != serverInfo->firstUnusedId);
|
||||
//return the first free and increase the value for the next time.
|
||||
serverInfo->firstUnusedId = suggested_id + 1;
|
||||
return suggested_id;
|
||||
}
|
||||
|
||||
static uint16_t libdhcpv6_address_id_allocate(dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
uint16_t address_id;
|
||||
if (serverInfo->firstFreedId) {
|
||||
address_id = serverInfo->firstFreedId;
|
||||
//Discover next free freed possible value
|
||||
serverInfo->firstFreedId = libdhcpv6_get_next_freed_id(serverInfo);
|
||||
} else {
|
||||
//Allocated new ID
|
||||
address_id = serverInfo->firstUnusedId++;
|
||||
}
|
||||
return address_id;
|
||||
// Unique IDs start to generate from 1 and continue to go up every new address
|
||||
// if we go around 65535 we start from 1 and search for free id
|
||||
|
||||
return libdhcpv6_get_unique_id(serverInfo);
|
||||
}
|
||||
|
||||
static void libdhcpv6_gen_suffics_from_eui48(uint8_t *ptr, uint8_t *eui48)
|
||||
|
@ -124,93 +112,12 @@ static void libdhcpv6_gen_suffics_from_allocated_id(uint8_t *ptr, uint8_t *serve
|
|||
common_write_16_bit(allocated_id, ptr + 6);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t libdhcpv6_address_generate(dhcpv6_gua_server_entry_s *serverInfo, dhcpv6_allocated_address_t *entry)
|
||||
{
|
||||
//GENERATE ADDRESS
|
||||
uint8_t *ptr = entry->nonTemporalAddress;
|
||||
memcpy(ptr, serverInfo->guaPrefix, 8);
|
||||
ptr += 8;
|
||||
if (serverInfo->enableAddressAutonous) {
|
||||
if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE ||
|
||||
entry->linkType == DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE) {
|
||||
memcpy(ptr, entry->linkId, 8);
|
||||
*ptr ^= 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI48_TYPE) {
|
||||
libdhcpv6_gen_suffics_from_eui48(ptr, entry->linkId);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t allocated_id = libdhcpv6_address_id_allocate(serverInfo);
|
||||
libdhcpv6_gen_suffics_from_allocated_id(ptr, serverInfo->clientIdDefaultSuffics, allocated_id);
|
||||
return allocated_id;
|
||||
}
|
||||
|
||||
static void libdhcpv6_address_free(dhcpv6_gua_server_entry_s *server_info, dhcpv6_allocated_address_entry_t *entry)
|
||||
static void libdhcpv6_address_list_entry_free(dhcpv6_gua_server_entry_s *server_info, dhcpv6_allocated_address_entry_t *entry)
|
||||
{
|
||||
ns_list_remove(&server_info->allocatedAddressList, entry);
|
||||
if (!server_info->enableAddressAutonous) {
|
||||
if (entry->allocatedID + 1 == server_info->firstUnusedId) {
|
||||
server_info->firstUnusedId--;
|
||||
} else if (server_info->firstFreedId == 0 || server_info->firstFreedId > entry->allocatedID) {
|
||||
server_info->firstFreedId = entry->allocatedID;
|
||||
}
|
||||
}
|
||||
ns_dyn_mem_free(entry);
|
||||
}
|
||||
|
||||
void libdhcpv6_allocated_address_write(uint8_t *ptr, dhcpv6_allocated_address_entry_t *address, dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
memcpy(ptr, serverInfo->guaPrefix, 8);
|
||||
ptr += 8;
|
||||
if (serverInfo->enableAddressAutonous) {
|
||||
//Generate address from link layer address
|
||||
if (address->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE ||
|
||||
address->linkType == DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE) {
|
||||
memcpy(ptr, address->linkId, 8);
|
||||
*ptr ^= 2;
|
||||
return;
|
||||
} else if (address->linkType == DHCPV6_DUID_HARDWARE_EUI48_TYPE) {
|
||||
libdhcpv6_gen_suffics_from_eui48(ptr, address->linkId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//Generate from 16-bit allocate and default suffic's
|
||||
libdhcpv6_gen_suffics_from_allocated_id(ptr, serverInfo->clientIdDefaultSuffics, address->allocatedID);
|
||||
}
|
||||
|
||||
static bool libdhcpv6_address_suffics_compare(const uint8_t *suffics, dhcpv6_allocated_address_entry_t *address, dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
uint8_t allocated_suffics[8];
|
||||
if (serverInfo->enableAddressAutonous) {
|
||||
//Generate address from link layer address
|
||||
if (address->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE ||
|
||||
address->linkType == DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE) {
|
||||
memcpy(allocated_suffics, address->linkId, 8);
|
||||
allocated_suffics[0] ^= 2;
|
||||
goto compare_suffics;
|
||||
} else if (address->linkType == DHCPV6_DUID_HARDWARE_EUI48_TYPE) {
|
||||
libdhcpv6_gen_suffics_from_eui48(allocated_suffics, address->linkId);
|
||||
goto compare_suffics;
|
||||
}
|
||||
}
|
||||
//Generate from 16-bit allocate and default suffic's
|
||||
libdhcpv6_gen_suffics_from_allocated_id(allocated_suffics, serverInfo->clientIdDefaultSuffics, address->allocatedID);
|
||||
|
||||
compare_suffics:
|
||||
if (memcmp(allocated_suffics, suffics, 8)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds)
|
||||
{
|
||||
//Check All allocated server inside this loop
|
||||
|
@ -223,9 +130,9 @@ void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds)
|
|||
//Stop use this address for leasequery and delete Route or address map
|
||||
address->preferredLifetime = 0;
|
||||
if (cur->removeCb) {
|
||||
uint8_t allocated_address[16];
|
||||
libdhcpv6_allocated_address_write(allocated_address, address, cur);
|
||||
cur->removeCb(cur->interfaceId, allocated_address, cur->guaPrefix);
|
||||
uint8_t ipAddress[16];
|
||||
libdhcpv6_allocated_address_write(ipAddress, address, cur);
|
||||
cur->removeCb(cur->interfaceId, ipAddress, cur->guaPrefix);
|
||||
}
|
||||
} else {
|
||||
address->preferredLifetime -= timeUpdateInSeconds;
|
||||
|
@ -233,7 +140,7 @@ void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds)
|
|||
}
|
||||
|
||||
if (address->lifetime <= timeUpdateInSeconds) {
|
||||
libdhcpv6_address_free(cur, address);
|
||||
libdhcpv6_address_list_entry_free(cur, address);
|
||||
} else {
|
||||
address->lifetime -= timeUpdateInSeconds;
|
||||
}
|
||||
|
@ -337,8 +244,7 @@ void libdhcpv6_gua_server_free_by_prefix_and_interfaceid(uint8_t *prefix, int8_t
|
|||
if (serverInfo) {
|
||||
if ((serverInfo->interfaceId == interfaceId) && (memcmp(serverInfo->guaPrefix, prefix, 8) == 0)) {
|
||||
ns_list_foreach_safe(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
ns_list_remove(&serverInfo->allocatedAddressList, cur);
|
||||
ns_dyn_mem_free(cur);
|
||||
libdhcpv6_address_list_entry_free(serverInfo, cur);
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(dhcpv6_dns_server_data_t, cur, &serverInfo->dnsServerList) {
|
||||
|
@ -372,7 +278,28 @@ static void libdhcpv6_address_entry_lifetime_set(dhcpv6_allocated_address_entry_
|
|||
}
|
||||
}
|
||||
|
||||
static void libdhcpv6_copy_allocated_entry_to_temp(dhcpv6_allocated_address_entry_t *cur, dhcpv6_allocated_address_t *address, dhcpv6_gua_server_entry_s *serverInfo)
|
||||
void libdhcpv6_allocated_address_write(uint8_t *ptr, dhcpv6_allocated_address_entry_t *address, dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
memcpy(ptr, serverInfo->guaPrefix, 8);
|
||||
ptr += 8;
|
||||
if (serverInfo->anonymousAddress) {
|
||||
//Generate from 16-bit allocate and default suffic's
|
||||
libdhcpv6_gen_suffics_from_allocated_id(ptr, serverInfo->clientIdDefaultSuffics, address->allocatedID);
|
||||
return;
|
||||
}
|
||||
//Generate address from link layer address
|
||||
if (address->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE ||
|
||||
address->linkType == DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE) {
|
||||
memcpy(ptr, address->linkId, 8);
|
||||
*ptr ^= 2;
|
||||
return;
|
||||
} else if (address->linkType == DHCPV6_DUID_HARDWARE_EUI48_TYPE) {
|
||||
libdhcpv6_gen_suffics_from_eui48(ptr, address->linkId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void libdhcpv6_generate_address_entry(dhcpv6_allocated_address_t *address, dhcpv6_allocated_address_entry_t *cur, dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
libdhcpv6_allocated_address_write(address->nonTemporalAddress, cur, serverInfo);
|
||||
memcpy(address->linkId, cur->linkId, 8);
|
||||
|
@ -384,61 +311,14 @@ static void libdhcpv6_copy_allocated_entry_to_temp(dhcpv6_allocated_address_entr
|
|||
address->linkType = cur->linkType;
|
||||
}
|
||||
|
||||
|
||||
static void libdhcpv6_copy_temp_to_allocated_entry(dhcpv6_allocated_address_entry_t *cur, dhcpv6_allocated_address_t *address, uint16_t allocated_id)
|
||||
static void libdhcpv6_address_list_entry_add_to_list(dhcpv6_gua_server_entry_s *serverInfo, dhcpv6_allocated_address_entry_t *allocated)
|
||||
{
|
||||
memcpy(cur->linkId, address->linkId, 8);
|
||||
cur->allocatedID = allocated_id;
|
||||
cur->T0 = address->T0;
|
||||
cur->T1 = address->T1;
|
||||
cur->iaID = address->iaID;
|
||||
cur->lifetime = address->lifetime;
|
||||
cur->preferredLifetime = address->preferredLifetime;
|
||||
cur->linkType = address->linkType;
|
||||
}
|
||||
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_get_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address)
|
||||
{
|
||||
if (memcmp(serverInfo->guaPrefix, address, 8)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ns_list_foreach(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
if (libdhcpv6_address_suffics_compare(address + 8, cur, serverInfo) == 0) {
|
||||
libdhcpv6_copy_allocated_entry_to_temp(cur, &serverInfo->tempAddressEntry, serverInfo);
|
||||
return &serverInfo->tempAddressEntry;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void libdhcpv6_address_rm_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address)
|
||||
{
|
||||
if (memcmp(serverInfo->guaPrefix, address, 8)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
if (libdhcpv6_address_suffics_compare(address + 8, cur, serverInfo) == 0) {
|
||||
libdhcpv6_address_free(serverInfo, cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void libdhcpv6_address_id_add_to_list(dhcpv6_gua_server_entry_s *serverInfo, dhcpv6_allocated_address_entry_t *allocated)
|
||||
{
|
||||
if (serverInfo->firstUnusedId != allocated->allocatedID + 1) {
|
||||
if (allocated->allocatedID != 0) {
|
||||
// If we have allocated ID we sort by it if it is 0 we dont do any sorting
|
||||
ns_list_foreach_safe(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
if (cur->allocatedID > allocated->allocatedID) {
|
||||
//Add before new allocated
|
||||
if (cur->link.prev) {
|
||||
ns_list_add_before(&serverInfo->allocatedAddressList, cur, allocated);
|
||||
} else {
|
||||
//New first
|
||||
ns_list_add_to_start(&serverInfo->allocatedAddressList, allocated);
|
||||
}
|
||||
ns_list_add_before(&serverInfo->allocatedAddressList, cur, allocated);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -446,68 +326,87 @@ static void libdhcpv6_address_id_add_to_list(dhcpv6_gua_server_entry_s *serverIn
|
|||
ns_list_add_to_end(&serverInfo->allocatedAddressList, allocated);
|
||||
}
|
||||
|
||||
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_allocated_list_scan(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *linkId, uint16_t linkType, uint32_t iaID, uint32_t T0, uint32_t T1, bool allocateNew)
|
||||
void libdhcpv6_address_delete(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address)
|
||||
{
|
||||
dhcpv6_allocated_address_t *newEntry = NULL;
|
||||
dhcpv6_allocated_address_entry_t *allocatedEntry = NULL;
|
||||
uint8_t device_address[16];
|
||||
if (memcmp(serverInfo->guaPrefix, address, 8)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
libdhcpv6_allocated_address_write(device_address, cur, serverInfo);
|
||||
if (memcmp(address, device_address, 16) == 0) {
|
||||
libdhcpv6_address_list_entry_free(serverInfo, cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static dhcpv6_allocated_address_entry_t *libdhcpv6_address_list_entry_create(dhcpv6_gua_server_entry_s *serverInfo, dhcpv6_allocated_address_entry_t *source)
|
||||
{
|
||||
dhcpv6_allocated_address_entry_t *entry;
|
||||
|
||||
entry = ns_dyn_mem_alloc(sizeof(dhcpv6_allocated_address_entry_t));
|
||||
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*entry = *source;
|
||||
libdhcpv6_address_list_entry_add_to_list(serverInfo, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_allocate(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *linkId, uint16_t linkType, uint32_t iaID, uint32_t T0, uint32_t T1, bool allocateNew)
|
||||
{
|
||||
dhcpv6_allocated_address_entry_t newEntry;
|
||||
uint16_t duiLength = 6;
|
||||
if (linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE ||
|
||||
linkType == DHCPV6_DUID_HARDWARE_IEEE_802_NETWORKS_TYPE) {
|
||||
duiLength = 8;
|
||||
}
|
||||
|
||||
if (serverInfo->enableAddressAutonous && serverInfo->disableAddressListAllocation) {
|
||||
//Accept allways when autonous
|
||||
newEntry = &serverInfo->tempAddressEntry;
|
||||
allocateNew = false;
|
||||
}
|
||||
|
||||
// Search if we have old address in list
|
||||
ns_list_foreach(dhcpv6_allocated_address_entry_t, cur, &serverInfo->allocatedAddressList) {
|
||||
if (cur->linkType == linkType) {
|
||||
if (memcmp(cur->linkId, linkId, duiLength) == 0) {
|
||||
cur->iaID = iaID;
|
||||
libdhcpv6_address_entry_lifetime_set(cur, serverInfo->validLifetime);
|
||||
libdhcpv6_copy_allocated_entry_to_temp(cur, &serverInfo->tempAddressEntry, serverInfo);
|
||||
return &serverInfo->tempAddressEntry;
|
||||
}
|
||||
if (cur->linkType == linkType && memcmp(cur->linkId, linkId, duiLength) == 0) {
|
||||
cur->iaID = iaID;
|
||||
cur->T0 = T0;
|
||||
cur->T1 = T1;
|
||||
libdhcpv6_address_entry_lifetime_set(cur, serverInfo->validLifetime);
|
||||
libdhcpv6_generate_address_entry(&serverInfo->tempAddressEntry, cur, serverInfo);
|
||||
return &serverInfo->tempAddressEntry;
|
||||
}
|
||||
}
|
||||
if (allocateNew) {
|
||||
if (ns_list_count(&serverInfo->allocatedAddressList) < serverInfo->maxSupportedClients) {
|
||||
allocatedEntry = ns_dyn_mem_alloc(sizeof(dhcpv6_allocated_address_entry_t));
|
||||
if (allocatedEntry) {
|
||||
newEntry = &serverInfo->tempAddressEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newEntry) {
|
||||
|
||||
if (serverInfo->validLifetime != 0xffffffff) {
|
||||
newEntry->lifetime = serverInfo->validLifetime;
|
||||
newEntry->preferredLifetime = (serverInfo->validLifetime >> 1);
|
||||
} else {
|
||||
newEntry->lifetime = 0xffffffff;
|
||||
newEntry->preferredLifetime = 0xffffffff;
|
||||
}
|
||||
memcpy(newEntry->linkId, linkId, duiLength);
|
||||
newEntry->linkType = linkType;
|
||||
newEntry->iaID = iaID;
|
||||
newEntry->T0 = T0;
|
||||
newEntry->T1 = T1;
|
||||
uint16_t allocated_id = libdhcpv6_address_generate(serverInfo, newEntry);
|
||||
if (!serverInfo->disableAddressListAllocation) {
|
||||
libdhcpv6_copy_temp_to_allocated_entry(allocatedEntry, newEntry, allocated_id);
|
||||
if (serverInfo->enableAddressAutonous) {
|
||||
ns_list_add_to_end(&serverInfo->allocatedAddressList, allocatedEntry);
|
||||
} else {
|
||||
//Add to list to proper order
|
||||
libdhcpv6_address_id_add_to_list(serverInfo, allocatedEntry);
|
||||
}
|
||||
}
|
||||
if (!allocateNew) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newEntry;
|
||||
if (ns_list_count(&serverInfo->allocatedAddressList) >= serverInfo->maxSupportedClients) {
|
||||
// Maximum supported clients reached
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Generate new address
|
||||
memcpy(newEntry.linkId, linkId, duiLength);
|
||||
newEntry.linkType = linkType;
|
||||
newEntry.iaID = iaID;
|
||||
newEntry.T0 = T0;
|
||||
newEntry.T1 = T1;
|
||||
newEntry.allocatedID = 0;
|
||||
libdhcpv6_address_entry_lifetime_set(&newEntry, serverInfo->validLifetime);
|
||||
if (serverInfo->anonymousAddress) {
|
||||
// Generate anonymous address id
|
||||
newEntry.allocatedID = libdhcpv6_address_id_allocate(serverInfo);
|
||||
}
|
||||
|
||||
if (!serverInfo->disableAddressList) {
|
||||
// Create new List item and add to list
|
||||
libdhcpv6_address_list_entry_create(serverInfo, &newEntry);
|
||||
}
|
||||
|
||||
libdhcpv6_generate_address_entry(&serverInfo->tempAddressEntry, &newEntry, serverInfo);
|
||||
return &serverInfo->tempAddressEntry;
|
||||
}
|
||||
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_discover(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address)
|
||||
|
|
|
@ -59,7 +59,6 @@ typedef struct dhcpv6_vendor_data_s {
|
|||
ns_list_link_t link; /*!< List link entry */
|
||||
} dhcpv6_vendor_data_t;
|
||||
|
||||
|
||||
typedef struct dhcpv6_allocated_address_s {
|
||||
uint8_t nonTemporalAddress[16];
|
||||
uint8_t linkId[8]; /*!< Services UL64 */
|
||||
|
@ -71,6 +70,7 @@ typedef struct dhcpv6_allocated_address_s {
|
|||
uint32_t lifetime;
|
||||
} dhcpv6_allocated_address_t;
|
||||
|
||||
|
||||
typedef NS_LIST_HEAD(dhcpv6_allocated_address_entry_t, link) dhcpv6_allocated_address_list_t;
|
||||
typedef NS_LIST_HEAD(dhcpv6_dns_server_data_t, link) dhcpv6_dns_server_list_t;
|
||||
typedef NS_LIST_HEAD(dhcpv6_vendor_data_t, link) dhcpv6_vendor_data_list_t;
|
||||
|
@ -85,14 +85,13 @@ typedef bool (dhcp_address_add_notify_cb)(int8_t interfaceId, dhcp_address_cache
|
|||
|
||||
typedef struct dhcpv6_gua_server_entry_s {
|
||||
int8_t interfaceId;
|
||||
bool enableAddressAutonous: 1;
|
||||
bool disableAddressListAllocation: 1;
|
||||
bool anonymousAddress: 1;
|
||||
bool disableAddressList: 1;
|
||||
uint16_t socketInstance_id;
|
||||
uint8_t guaPrefix[8];
|
||||
uint8_t serverDynamic_DUID_length;
|
||||
uint32_t maxSupportedClients;
|
||||
uint8_t clientIdDefaultSuffics[6];
|
||||
uint16_t firstFreedId;
|
||||
uint16_t firstUnusedId; /*!< This is first unused Id */
|
||||
uint32_t validLifetime;
|
||||
dhcp_duid_options_params_t serverDUID;
|
||||
|
@ -111,12 +110,11 @@ dhcpv6_gua_server_entry_s *libdhcpv6_gua_server_allocate(uint8_t *prefix, int8_t
|
|||
int libdhcpv6_server_duid_set(dhcpv6_gua_server_entry_s *server_info, uint8_t *duid_ptr, uint16_t duid_type, uint8_t duid_length);
|
||||
void libdhcpv6_gua_server_free_by_prefix_and_interfaceid(uint8_t *prefix, int8_t interfaceId);
|
||||
void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds);
|
||||
void libdhcpv6_address_rm_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_get_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
void libdhcpv6_allocated_address_write(uint8_t *ptr, dhcpv6_allocated_address_entry_t *address, dhcpv6_gua_server_entry_s *serverInfo);
|
||||
void libdhcpv6_address_delete(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_interfaceid(int8_t interfaceId, const uint8_t *prefixPtr);
|
||||
dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_socketinstance(uint16_t socketInstance, uint8_t *prefixPtr);
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_allocated_list_scan(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *euid64, uint16_t linkType, uint32_t iaID, uint32_t T0, uint32_t T1, bool allocateNew);
|
||||
void libdhcpv6_allocated_address_write(uint8_t *ptr, dhcpv6_allocated_address_entry_t *address, dhcpv6_gua_server_entry_s *serverInfo);
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_allocate(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *euid64, uint16_t linkType, uint32_t iaID, uint32_t T0, uint32_t T1, bool allocateNew);
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_discover(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_allocate(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
dhcpv6_vendor_data_t *libdhcpv6_vendor_data_discover(dhcpv6_gua_server_entry_s *serverInfo, uint32_t enterprise_number);
|
||||
|
@ -127,15 +125,23 @@ uint8_t *libdhcpv6_dns_server_message_writes(dhcpv6_gua_server_entry_s *serverIn
|
|||
uint8_t *libdhcpv6_vendor_data_message_writes(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *ptr);
|
||||
#else
|
||||
#define libdhcpv6_gua_server_list_empty() true
|
||||
#define libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefixPtr) NULL
|
||||
#define libdhcpv6_server_data_get_by_prefix_and_socketinstance(socketInstance, prefixPtr) NULL
|
||||
#define libdhcpv6_gua_server_allocate(prefix, interfaceId, serverDUID, serverDUIDType) NULL
|
||||
#define libdhcpv6_gua_server_free_by_prefix_and_interfaceid(prefix, interfaceId) ((void)0)
|
||||
#define libdhcpv6_gua_servers_time_update(timeUpdateInSeconds) ((void)0)
|
||||
#define libdhcpv6_gua_server_free_by_interfaceid(interfaceId) ((void)0)
|
||||
#define libdhcpv6_address_get_from_allocated_list(serverInfo, address) NULL
|
||||
#define libdhcpv6_address_rm_from_allocated_list(serverInfo, address) ((void)0)
|
||||
#define libdhcpv6_address_allocated_list_scan( serverInfo, linkId, linkType, iaID, T0, T1, allocateNew) NULL
|
||||
#define libdhcpv6_server_duid_set(server_info, duid_ptr, duid_type, duid_length)
|
||||
#define libdhcpv6_gua_server_free_by_prefix_and_interfaceid(prefix, interfaceId)
|
||||
#define libdhcpv6_gua_servers_time_update(timeUpdateInSeconds)
|
||||
#define libdhcpv6_allocated_address_write(ptr, address, serverInfo)
|
||||
#define libdhcpv6_address_delete(serverInfo, address)
|
||||
#define libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefixPtr) NULL
|
||||
#define libdhcpv6_server_data_get_by_prefix_and_socketinstance(socketInstance,prefixPtr) NULL
|
||||
#define libdhcpv6_address_allocate(serverInfo, euid64, linkType, iaID, T0, T1, allocateNew) NULL
|
||||
#define libdhcpv6_dns_server_discover(serverInfo, address) NULL
|
||||
#define libdhcpv6_dns_server_allocate(serverInfo, address) NULL
|
||||
#define libdhcpv6_vendor_data_discover(serverInfo, enterprise_number) NULL
|
||||
#define libdhcpv6_vendor_data_allocate(serverInfo, enterprise_number) NULL
|
||||
#define libdhcpv6_dns_server_message_sizes(serverInfo) 0
|
||||
#define libdhcpv6_vendor_data_message_sizes(serverInfo) 0
|
||||
#define libdhcpv6_dns_server_message_writes(serverInfo, ptr) NULL
|
||||
#define libdhcpv6_vendor_data_message_writes(serverInfo, ptr) NULL
|
||||
#endif
|
||||
|
||||
#endif /* LIBDHCPV6_SERVER_H_ */
|
||||
|
|
Loading…
Reference in New Issue