forked from ARMmbed/mbed-os
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added new service Random early detection
Random Early detetction is for start dropping packet in high network load when message queue's start growing over configured threshold values.
- Loading branch information
Juha Heiuskanen
committed
Dec 2, 2020
1 parent
f2c358d
commit 11c0763
Showing
15 changed files
with
784 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
source/Service_Libs/random_early_detection/random_early_detection.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* Copyright (c) 2020, Arm Limited and affiliates. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "nsconfig.h" | ||
#include "ns_types.h" | ||
#include "string.h" | ||
#include "ns_trace.h" | ||
#include "nsdynmemLIB.h" | ||
#include "randLIB.h" | ||
#include "Service_Libs/random_early_detection/random_early_detection.h" | ||
#include "Service_Libs/random_early_detection/random_early_detection_api.h" | ||
|
||
|
||
red_info_t *random_early_detection_create(uint16_t threshold_min, uint16_t threshold_max, uint8_t drop_max_p, uint16_t weight) | ||
{ | ||
//Weight must be between 1-256 | ||
if (weight == 0 || weight > 256) { | ||
return NULL; | ||
} | ||
|
||
//Probability must be between 1-100 | ||
if (drop_max_p == 0 || drop_max_p > 100) { | ||
return NULL; | ||
} | ||
|
||
//Max Threshold can't smaller or similar than min | ||
if (threshold_max <= threshold_min) { | ||
return NULL; | ||
} | ||
|
||
red_info_t *red_info = ns_dyn_mem_alloc(sizeof(red_info_t)); | ||
if (red_info) { | ||
red_info->count = 0; | ||
red_info->averageQ = 0; | ||
red_info->parameters.drop_maX_P = drop_max_p; | ||
red_info->parameters.threshold_max = threshold_max; | ||
red_info->parameters.threshold_min = threshold_min; | ||
red_info->parameters.weight = weight; | ||
} | ||
|
||
return red_info; | ||
} | ||
|
||
|
||
void random_early_detection_free(struct red_info_s *red_info) | ||
{ | ||
ns_dyn_mem_free(red_info); | ||
} | ||
|
||
//calculate average and return averaged value back | ||
static uint16_t random_early_detetction_aq_calc(red_info_t *red_info, uint16_t sampleLen) | ||
{ | ||
|
||
if (red_info->parameters.weight == RED_AVERAGE_WEIGHT_DISABLED || red_info->averageQ == 0) { | ||
red_info->averageQ = sampleLen * 256; | ||
return sampleLen; | ||
} | ||
|
||
// AQ = (1-weight) * average_queue + weight*sampleLen | ||
// Now Sample is scaled by 256 which is not loosing so much tail at average | ||
|
||
//Weight Last Average part (1-weight) * average_queue with scaled 256 | ||
uint32_t averageSum = ((256 - red_info->parameters.weight) * red_info->averageQ) / 256; | ||
//Add new weighted sample lenght (weight*sampleLen) | ||
averageSum += (red_info->parameters.weight * sampleLen); | ||
|
||
if (averageSum & 1) { | ||
//If sum is ODD add 1 this will help to not stuck like 1,99 average to -> 2 | ||
averageSum++; | ||
} | ||
//Store new average//If sum is ODD add 1 this will | ||
red_info->averageQ = averageSum; | ||
//Return always same format scaled than inn | ||
return red_info->averageQ / 256; | ||
|
||
} | ||
|
||
|
||
|
||
bool random_early_detection_packet(red_info_t *red_info, uint16_t sampleLen) | ||
{ | ||
//Calulate Average queue size | ||
sampleLen = random_early_detetction_aq_calc(red_info, sampleLen); | ||
|
||
if (sampleLen <= red_info->parameters.threshold_min) { | ||
//Can be added to queue without any RED operation | ||
red_info->count = 0; | ||
return false; | ||
} | ||
|
||
if (sampleLen > red_info->parameters.threshold_max) { | ||
//Always drop over threshold_max | ||
red_info->count = 0; | ||
return true; | ||
} | ||
|
||
// Calculate probability for packet drop | ||
// tempP = drop_maX_P *(AQ - threshold_min) / (threshold_max - threshold_min); | ||
uint32_t tempP = (uint32_t) red_info->parameters.drop_maX_P * PROB_SCALE | ||
* (sampleLen - red_info->parameters.threshold_min) | ||
/ (red_info->parameters.threshold_max - red_info->parameters.threshold_min); | ||
|
||
// Next Prob = tempP / (1 - count*tempP) | ||
// This will increase probability and | ||
|
||
//Calculate first divider part | ||
uint32_t Prob = red_info->count * tempP; | ||
|
||
//Check that divider it is not >= 0 | ||
if (Prob >= PROB_SCALE_MAX) { | ||
|
||
red_info->count = 0; | ||
return true; | ||
} | ||
|
||
//Calculate only when count * tempP is smaller than scaler | ||
Prob = (tempP * PROB_SCALE_MAX) / (PROB_SCALE_MAX - Prob); | ||
if (Prob > randLIB_get_random_in_range(0, PROX_MAX_RANDOM)) { | ||
//Drop packet | ||
red_info->count = 0; | ||
return true; | ||
} | ||
|
||
//Increment count next round check | ||
red_info->count++; | ||
return false; | ||
|
||
} |
47 changes: 47 additions & 0 deletions
47
source/Service_Libs/random_early_detection/random_early_detection.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright (c) 2020, Arm Limited and affiliates. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_H_ | ||
#define SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
//This value cant be bigger than 655 | ||
#define PROB_SCALE 512 | ||
#define PROB_SCALE_MAX PROB_SCALE * 100 | ||
#define PROX_MAX_RANDOM PROB_SCALE_MAX-1 | ||
|
||
typedef struct red_config_s { | ||
uint16_t weight; /*< Weight for new sample len, 256 disabled average */ | ||
uint16_t threshold_min; /*< Threshold Min value which start possibility start drop a packet */ | ||
uint16_t threshold_max; /*< Threshold Max this value give max Probability for configured value over that every new packet will be dropped*/ | ||
uint8_t drop_maX_P; /*< Max probability for drop packet between threshold_min and threshold_max threshold */ | ||
} red_config_t; | ||
|
||
typedef struct red_info_s { | ||
red_config_t parameters; /*< Random Early detetction parameters for queue avarge and packet drop */ | ||
uint32_t averageQ; /*< Average queue size Scaled by 256 1.0 is 256 */ | ||
uint16_t count; /*< Missed Packet drop's. This value is incremented when average queue is over min threshoild and packet is noot dropped */ | ||
} red_info_t; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_H_ */ |
105 changes: 105 additions & 0 deletions
105
source/Service_Libs/random_early_detection/random_early_detection_api.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* Copyright (c) 2020, Arm Limited and affiliates. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_API_H_ | ||
#define SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_API_H_ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
struct red_info_s; | ||
|
||
#define RED_AVERAGE_WEIGHT_DISABLED 256 /*< Average is disabled */ | ||
#define RED_AVERAGE_WEIGHT_HALF 128 /*< Average weight for new sample is 0.5*new + 0.5 to last one */ | ||
#define RED_AVERAGE_WEIGHT_QUARTER 64 /*< Average weight for new sample is 1/4 + 3/4 to last one */ | ||
#define RED_AVERAGE_WEIGHT_EIGHTH 32 /*< Average weight for new sample is 1/8 + 7/8 to last one */ | ||
|
||
/** | ||
* \brief Create Random early detection data | ||
* | ||
* Function will config parameters how wide are Random Early detection drop will work. | ||
* | ||
* How to use parameters: | ||
* | ||
* Weight is definition how message queue Average (AQ) is calculated. Smaller weight will give smoother AQ update. | ||
* | ||
* AQ = (1-weight) * average_queue + weight*sampleLen; | ||
* | ||
* * RED_AVERAGE_WEIGHT_DISABLED disable Average by max weight to new sample length | ||
* * RED_AVERAGE_WEIGHT_HALF last average*0.5 + 0.5*new sample: Smooth Average light packet filter | ||
* * RED_AVERAGE_WEIGHT_QUARTER last average*0.75 + 0.25*new sample: Medium packet burst filtering | ||
* * RED_AVERAGE_WEIGHT_EIGHTH last average*7/8 + 1/8*new sample: Good for filtering packet burst and big networks | ||
* | ||
* How to configure packet drop possibility: | ||
* | ||
* Define base Probability based current AQ, average length | ||
* | ||
* tempP = drop_maX_P *(AQ - threshold_min) / (threshold_max - threshold_min); | ||
* | ||
* Prob = tempP / (1 - count*tempP) | ||
* | ||
* threshold_min and threshold_max threshold define area for random early detection drop. When Average queue size go over Min threshold packet may drop by given maxProbability. | ||
* System will work smoother if min -max threshold range is wide. Then random drop is may cover small data burst until Max threshold Avarage is reached. | ||
* After Max every new packet will be dropped. | ||
* | ||
* Config Examples. | ||
* | ||
* Threshold values must be set how much device can buffer data. | ||
* | ||
* Small size data buffering: | ||
* random_early_detection_create(32, 96, 10, RED_AVERAGE_WEIGHT_QUARTER) | ||
* | ||
* Medium size data buffering: | ||
* random_early_detection_create(96, 256, 10, RED_AVERAGE_WEIGHT_EIGHTH) | ||
* | ||
* High size buffering: | ||
* random_early_detection_create(256, 600, 10, RED_AVERAGE_WEIGHT_EIGHTH) | ||
* | ||
* \param threshold_min min average queue size which enable packet drop | ||
* \param threshold_max average queue size when all new packets start drop | ||
* \param drop_maX_P is percent probability to drop packet 100-1 are possible values | ||
* \param weight accepted values 256-1, 256 is 1.0 weight which mean that new queue size overwrite old. 128 is 0.5 which gives 0.5 from old + 0.5 from new. | ||
* \return Pointer for allocated structure, NULL if memory allocation fail | ||
*/ | ||
struct red_info_s *random_early_detection_create(uint16_t threshold_min, uint16_t threshold_max, uint8_t drop_maX_P, uint16_t weight); | ||
|
||
|
||
/** | ||
* \brief Free Random early detection data | ||
* | ||
* | ||
* \param red_info pointer to data | ||
*/ | ||
void random_early_detection_free(struct red_info_s *red_info); | ||
|
||
|
||
/** | ||
* \brief Random early detection drop function | ||
* | ||
* \param red_info pointer, which is created user include all configurations | ||
* \param sampleLen Current queue length | ||
* \return true Drop packet | ||
* \return false Packet can be added to queue | ||
*/ | ||
bool random_early_detection_packet(struct red_info_s *red_info, uint16_t sampleLen); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* SERVICE_LIBS_RANDOM_EARLY_DETECTION_RANDOM_EARLY_DETECTION_API_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
test/nanostack/unittest/service_libs/random_early_detetction/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
include ../../makefile_defines.txt | ||
|
||
COMPONENT_NAME = random_early_detection_unit | ||
|
||
#This must be changed manually | ||
SRC_FILES = \ | ||
../../../../../source/Service_Libs/random_early_detection/random_early_detection.c \ | ||
|
||
TEST_SRC_FILES = \ | ||
main.cpp \ | ||
randomEarlyDetection_test.cpp \ | ||
../../stub/mbed_trace_stub.c \ | ||
../../stub/nsdynmemLIB_stub.c \ | ||
../../stub/rand_lib2_stub.c \ | ||
|
||
include ../../MakefileWorker.mk | ||
|
||
CPPUTESTFLAGS += -DFEA_TRACE_SUPPORT -DEXTRA_CONSISTENCY_CHECKS |
Oops, something went wrong.