diff options
author | Luca Muscariello <lumuscar@cisco.com> | 2022-03-30 22:29:28 +0200 |
---|---|---|
committer | Mauro Sardara <msardara@cisco.com> | 2022-03-31 19:51:47 +0200 |
commit | c46e5df56b67bb8ea7a068d39324c640084ead2b (patch) | |
tree | eddeb17785938e09bc42eec98ee09b8a28846de6 /hicn-light/src/hicn/strategies/nexthopStateLowLatency.c | |
parent | 18fa668f25d3cc5463417ce7df6637e31578e898 (diff) |
feat: boostrap hicn 22.02
The current patch provides several new features, improvements,
bug fixes and also complete rewrite of entire components.
- lib
The hicn packet parser has been improved with a new packet
format fully based on UDP. The TCP header is still temporarily
supported but the UDP header will replace completely the new hicn
packet format. Improvements have been made to make sure every
packet parsing operation is made via this library. The current
new header can be used as header between the payload and the
UDP header or as trailer in the UDP surplus area to be tested
when UDP options will start to be used.
- hicn-light
The portable packet forwarder has been completely rewritten from
scratch with the twofold objective to improve performance and
code size but also to drop dependencies such as libparc which is
now removed by the current implementation.
- hicn control
the control library is the agent that is used to program the
packet forwarders via their binary API. This component has
benefited from significant improvements in terms of interaction
model which is now event driven and more robust to failures.
- VPP plugin has been updated to support VPP 22.02
- transport
Major improvement have been made to the RTC protocol, to the
support of IO modules and to the security sub system. Signed
manifests are the default data authenticity and integrity framework.
Confidentiality can be enabled by sharing the encryption key to the
prod/cons layer. The library has been tested with group key based
applications such as broadcast/multicast and real-time on-line
meetings with trusted server keys or MLS.
- testing
Unit testing has been introduced using GoogleTest. One third of
the code base is covered by unit testing with priority on
critical features. Functional testing has also been introduce
using Docker, linux bridging and Robot Framework to define
test with Less Code techniques to facilitate the extension
of the coverage.
Co-authored-by: Mauro Sardara <msardara@cisco.com>
Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Co-authored-by: Michele Papalini <micpapal@cisco.com>
Co-authored-by: Angelo Mantellini <manangel@cisco.com>
Co-authored-by: Jacques Samain <jsamain@cisco.com>
Co-authored-by: Olivier Roques <oroques+fdio@cisco.com>
Co-authored-by: Enrico Loparco <eloparco@cisco.com>
Co-authored-by: Giulio Grassi <gigrassi@cisco.com>
Change-Id: I75d0ef70f86d921e3ef503c99271216ff583c215
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'hicn-light/src/hicn/strategies/nexthopStateLowLatency.c')
-rw-r--r-- | hicn-light/src/hicn/strategies/nexthopStateLowLatency.c | 386 |
1 files changed, 49 insertions, 337 deletions
diff --git a/hicn-light/src/hicn/strategies/nexthopStateLowLatency.c b/hicn-light/src/hicn/strategies/nexthopStateLowLatency.c index a3953987f..3caed8130 100644 --- a/hicn-light/src/hicn/strategies/nexthopStateLowLatency.c +++ b/hicn-light/src/hicn/strategies/nexthopStateLowLatency.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * 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: @@ -24,303 +24,17 @@ #include <parc/assert/parc_Assert.h> #include <hicn/strategies/nexthopStateLowLatency.h> -const unsigned MAX_ROUNS_WITHOUT_PROBES = 4; - //if we do not receives probes for 4 rounds it means - //that we had no responce from any producer for 2 sec - //we can say that this interface is daed -const unsigned MIN_NON_LOSSY_ROUNDS = 10; - //number of rounds in non lossy mode before switch to - //no lossy state -const double MAX_LOSS_RATE = 0.10; //10% - -struct strategy_nexthop_state_ll { - bool in_use; - bool is_allowed; // the policy may not allow the use of this face - unsigned face_id; - unsigned sent_packets; - //switch metrics - unsigned last_try_to_switch_round; - unsigned try_to_switch_counter; - //probes counters - unsigned recevied_probes; - unsigned rounds_without_probes; - unsigned sent_probes; - unsigned lost_probes; - unsigned non_lossy_rounds; - //avgs - double avg_rtt; - double avg_rtt_in_use; - double avg_queue; - double avg_loss_rate; - -}; - -static bool _strategyNexthopStateLL_Destructor( - StrategyNexthopStateLL **instancePtr) { - return true; -} - -parcObject_ImplementAcquire(strategyNexthopStateLL, StrategyNexthopStateLL); - -parcObject_ImplementRelease(strategyNexthopStateLL, StrategyNexthopStateLL); - -parcObject_Override( - StrategyNexthopStateLL, PARCObject, - .destructor = (PARCObjectDestructor *)_strategyNexthopStateLL_Destructor, - .copy = (PARCObjectCopy *)strategyNexthopStateLL_Copy, - .display = (PARCObjectDisplay *)strategyNexthopStateLL_Display, - .toString = (PARCObjectToString *)strategyNexthopStateLL_ToString, - .equals = (PARCObjectEquals *)strategyNexthopStateLL_Equals, - .compare = (PARCObjectCompare *)strategyNexthopStateLL_Compare, - .hashCode = (PARCObjectHashCode *)strategyNexthopStateLL_HashCode, - .display = (PARCObjectDisplay *)strategyNexthopStateLL_Display); - -void strategyNexthopStateLL_AssertValid(const StrategyNexthopStateLL *instance) { - parcAssertTrue(strategyNexthopStateLL_IsValid(instance), - "StrategyNexthopState is not valid."); -} - -StrategyNexthopStateLL *strategyNexthopStateLL_Create(unsigned face_id) { - StrategyNexthopStateLL *result = - parcObject_CreateInstance(StrategyNexthopStateLL); - if (result != NULL) { - result->in_use = false; - result->is_allowed = true; - result->face_id = face_id; - result->sent_packets = 0; - result->last_try_to_switch_round = 0; - result->try_to_switch_counter = 0; - result->recevied_probes = 0; - result->rounds_without_probes = 0; - result->sent_probes = 0; - result->lost_probes = 0; - result->non_lossy_rounds = MIN_NON_LOSSY_ROUNDS; - result->avg_rtt = -1.0; - result->avg_rtt_in_use = -1.0; - result->avg_queue = 0.0001; - result->avg_loss_rate = 0.0; - } - return result; -} - -void strategyNexthopStateLL_Reset(StrategyNexthopStateLL *x) { - x->in_use = false; - x->is_allowed = true; - x->sent_packets = 0; - x->last_try_to_switch_round = 0; - x->try_to_switch_counter = 0; - x->recevied_probes = 0; - x->rounds_without_probes = 0; - x->sent_probes = 0; - x->lost_probes = 0; - x->non_lossy_rounds = MIN_NON_LOSSY_ROUNDS; - x->avg_rtt = -1.0; - x->avg_rtt_in_use = -1.0; - x->avg_queue = 0.0001; - x->avg_loss_rate = 0.0; -} - - -int strategyNexthopStateLL_Compare(const StrategyNexthopStateLL *val, - const StrategyNexthopStateLL *other) { - if (val == NULL) { - if (other != NULL) { - return -1; - } - } else if (other == NULL) { - return 1; - } else { - strategyNexthopStateLL_OptionalAssertValid(val); - strategyNexthopStateLL_OptionalAssertValid(other); - - if (val->in_use < other->in_use){ - return -1; - }else if (val->in_use > other->in_use){ - return 1; - } - - if (val->is_allowed < other->is_allowed){ - return -1; - }else if (val->is_allowed> other->is_allowed){ - return 1; - } - - if (val->face_id < other->face_id) { - return -1; - } else if (val->face_id > other->face_id) { - return 1; - } - - if (val->sent_packets < other->sent_packets){ - return -1; - } else if (val->sent_packets > other->sent_packets){ - return 1; - } - - if (val->last_try_to_switch_round < - other->last_try_to_switch_round) { - return -1; - } else if (val->last_try_to_switch_round > - other->last_try_to_switch_round) { - return 1; - } - - if (val->try_to_switch_counter < - other->try_to_switch_counter) { - return -1; - } else if (val->try_to_switch_counter > - other->try_to_switch_counter) { - return 1; - } - - if (val->recevied_probes < other->recevied_probes) { - return -1; - } else if (val->recevied_probes > other->recevied_probes) { - return 1; - } - - if (val->rounds_without_probes < other->rounds_without_probes) { - return -1; - } else if (val->rounds_without_probes > other->rounds_without_probes) { - return 1; - } - - if (val->sent_probes < other->sent_probes) { - return -1; - } else if (val->sent_probes > other->sent_probes) { - return 1; - } - - if (val->lost_probes < other->lost_probes) { - return -1; - } else if (val->lost_probes > other->lost_probes) { - return 1; - } - - if (val->non_lossy_rounds < other->non_lossy_rounds) { - return -1; - } else if (val->non_lossy_rounds > other->non_lossy_rounds) { - return 1; - } - - if (val->avg_rtt < other->avg_rtt) { - return -1; - } else if (val->avg_rtt > other->avg_rtt) { - return 1; - } - - if (val->avg_rtt_in_use < other->avg_rtt_in_use) { - return -1; - } else if (val->avg_rtt_in_use > other->avg_rtt_in_use) { - return 1; - } - - if (val->avg_queue < other->avg_queue) { - return -1; - } else if (val->avg_queue > other->avg_queue) { - return 1; - } - - if (val->avg_loss_rate < other->avg_loss_rate) { - return -1; - } else if (val->avg_loss_rate > other->avg_loss_rate) { - return 1; - } - } - - return 0; -} - -StrategyNexthopStateLL *strategyNexthopStateLL_Copy( - const StrategyNexthopStateLL *original) { - StrategyNexthopStateLL *result = strategyNexthopStateLL_Create(original->face_id); - result->in_use = original->in_use; - result->is_allowed = original->is_allowed; - result->sent_packets = original->sent_packets; - result->last_try_to_switch_round = original->last_try_to_switch_round; - result->try_to_switch_counter = original->try_to_switch_counter; - result->recevied_probes = original->recevied_probes; - result->rounds_without_probes = original->rounds_without_probes; - result->sent_probes = original->sent_probes; - result->lost_probes = original->lost_probes; - result->non_lossy_rounds = original->non_lossy_rounds; - result->avg_rtt = original->avg_rtt; - result->avg_rtt_in_use = original->avg_rtt_in_use; - result->avg_queue = original->avg_queue; - result->avg_loss_rate = original->avg_loss_rate; - return result; -} - -void strategyNexthopStateLL_Display(const StrategyNexthopStateLL *instance, - int indentation) { - parcDisplayIndented_PrintLine(indentation, "StrategyNexthopStateLL@%p {", - instance); - parcDisplayIndented_PrintLine(indentation + 1, "%d", instance->face_id); - parcDisplayIndented_PrintLine(indentation + 1, "%f", instance->avg_rtt); - parcDisplayIndented_PrintLine(indentation + 1, "%f", instance->avg_rtt_in_use); - parcDisplayIndented_PrintLine(indentation + 1, "%f", instance->avg_queue); - parcDisplayIndented_PrintLine(indentation + 1, "%f", instance->avg_loss_rate); - parcDisplayIndented_PrintLine(indentation, "}"); -} - - -bool strategyNexthopStateLL_Equals(const StrategyNexthopStateLL *x, - const StrategyNexthopStateLL *y) { - bool result = false; - - if (x == y) { - result = true; - } else if (x == NULL || y == NULL) { - result = false; - } else { - strategyNexthopStateLL_OptionalAssertValid(x); - strategyNexthopStateLL_OptionalAssertValid(y); - - if (strategyNexthopStateLL_Compare(x, y) == 0) { - result = true; - } - } - - return result; -} - -PARCHashCode strategyNexthopStateLL_HashCode(const StrategyNexthopStateLL *x) { - PARCHashCode result = 0; - char str[128]; - sprintf(str, "ID:%d: RTT:%f: RTTUSE:%f: Q:%f L:%f", x->face_id, x->avg_rtt, - x->avg_rtt_in_use, x->avg_queue, x->avg_loss_rate); - result = parcHashCode_Hash((uint8_t *)&str, strlen(str)); - return result; -} - -bool strategyNexthopStateLL_IsValid(const StrategyNexthopStateLL *x) { - bool result = false; - - if (x != NULL) { - result = true; - } - - return result; -} - -char *strategyNexthopStateLL_ToString(const StrategyNexthopStateLL *x) { - // this is not implemented - parcTrapNotImplemented("strategyNexthopStateLL_ToString is not implemented"); - return NULL; -} - double strategyNexthopStateLL_GetRTTProbe(StrategyNexthopStateLL *x) { strategyNexthopStateLL_OptionalAssertValid(x); - if(x->rounds_without_probes > MAX_ROUNS_WITHOUT_PROBES) - return DBL_MAX; + if (x->rounds_without_probes > MAX_ROUNS_WITHOUT_PROBES) return DBL_MAX; - if(x->avg_rtt == -1.0){ - if(x->avg_rtt_in_use == -1.0){ + if (x->avg_rtt == -1.0) { + if (x->avg_rtt_in_use == -1.0) { return 0.0; - }else{ - //this happens if the face recevied probes only in in_use mode - //we set the avf_rtt with rtt_in_use + } else { + // this happens if the face recevied probes only in in_use mode + // we set the avf_rtt with rtt_in_use x->avg_rtt = x->avg_rtt_in_use; } } @@ -331,11 +45,9 @@ double strategyNexthopStateLL_GetRTTProbe(StrategyNexthopStateLL *x) { double strategyNexthopStateLL_GetRTTInUse(StrategyNexthopStateLL *x) { strategyNexthopStateLL_OptionalAssertValid(x); - if(x->rounds_without_probes > MAX_ROUNS_WITHOUT_PROBES) - return DBL_MAX; + if (x->rounds_without_probes > MAX_ROUNS_WITHOUT_PROBES) return DBL_MAX; - if(x->avg_rtt_in_use == -1.0) - return strategyNexthopStateLL_GetRTTProbe(x); + if (x->avg_rtt_in_use == -1.0) return strategyNexthopStateLL_GetRTTProbe(x); return x->avg_rtt_in_use; } @@ -343,9 +55,9 @@ double strategyNexthopStateLL_GetRTTInUse(StrategyNexthopStateLL *x) { double strategyNexthopStateLL_GetRTTLive(StrategyNexthopStateLL *x) { strategyNexthopStateLL_OptionalAssertValid(x); - if(x->in_use){ + if (x->in_use) { return strategyNexthopStateLL_GetRTTInUse(x); - }else{ + } else { return strategyNexthopStateLL_GetRTTProbe(x); } } @@ -353,46 +65,45 @@ double strategyNexthopStateLL_GetRTTLive(StrategyNexthopStateLL *x) { double strategyNexthopStateLL_GetQueuing(const StrategyNexthopStateLL *x) { strategyNexthopStateLL_OptionalAssertValid(x); - if(x->rounds_without_probes > MAX_ROUNS_WITHOUT_PROBES) - return 0.0; + if (x->rounds_without_probes > MAX_ROUNS_WITHOUT_PROBES) return 0.0; return x->avg_queue; } void strategyNexthopStateLL_AddRttSample(StrategyNexthopStateLL *x, - unsigned int rtt){ + unsigned int rtt) { strategyNexthopStateLL_OptionalAssertValid(x); x->recevied_probes++; - //form uint to double + // form uint to double double drtt = rtt; - if(x->in_use){ - if(x->avg_rtt_in_use == -1.0){ + if (x->in_use) { + if (x->avg_rtt_in_use == -1.0) { x->avg_rtt_in_use = drtt; - }else{ + } else { x->avg_rtt_in_use = (x->avg_rtt_in_use * 0.9) + (drtt * 0.1); } - }else{ - if(x->avg_rtt == -1.0){ - x->avg_rtt = drtt; - }else{ + } else { + if (x->avg_rtt == -1.0) { + x->avg_rtt = drtt; + } else { x->avg_rtt = (x->avg_rtt * 0.9) + (drtt * 0.1); } } - if(x->avg_rtt_in_use == -1.0 || x->avg_rtt == -1.0){ + if (x->avg_rtt_in_use == -1.0 || x->avg_rtt == -1.0) { x->avg_queue = 0.0001; - }else{ + } else { double queue = x->avg_rtt_in_use - x->avg_rtt; - if(queue < 0){ + if (queue < 0) { queue = 0.0001; } x->avg_queue = (x->avg_queue * 0.95) + (0.05 * queue); } } -void strategyNexthopStateLL_SetUnusedFace(StrategyNexthopStateLL *x){ +void strategyNexthopStateLL_SetUnusedFace(StrategyNexthopStateLL *x) { strategyNexthopStateLL_OptionalAssertValid(x); x->in_use = false; } @@ -403,75 +114,76 @@ unsigned strategyNexthopStateLL_GetFaceId(StrategyNexthopStateLL *x) { } void strategyNexthopStateLL_IncreaseTryToSwitch(StrategyNexthopStateLL *x, - unsigned round){ - if(x->try_to_switch_counter == 0 || - round == (x->last_try_to_switch_round + 1)){ + unsigned round) { + if (x->try_to_switch_counter == 0 || + round == (x->last_try_to_switch_round + 1)) { x->last_try_to_switch_round = round; x->try_to_switch_counter++; - }else{ + } else { x->try_to_switch_counter = 0; } } -unsigned strategyNexthopStateLL_GetTryToSwitch(const StrategyNexthopStateLL *x){ +unsigned strategyNexthopStateLL_GetTryToSwitch( + const StrategyNexthopStateLL *x) { return x->try_to_switch_counter; } -void strategyNexthopStateLL_ResetTryToSwitch(StrategyNexthopStateLL *x){ +void strategyNexthopStateLL_ResetTryToSwitch(StrategyNexthopStateLL *x) { x->try_to_switch_counter = 0; } -void strategyNexthopStateLL_SendPacket(StrategyNexthopStateLL *x){ +void strategyNexthopStateLL_SendPacket(StrategyNexthopStateLL *x) { x->in_use = true; x->sent_packets++; } -void strategyNexthopStateLL_SentProbe(StrategyNexthopStateLL *x){ +void strategyNexthopStateLL_SentProbe(StrategyNexthopStateLL *x) { x->sent_probes++; } -void strategyNexthopStateLL_LostProbe(StrategyNexthopStateLL *x){ +void strategyNexthopStateLL_LostProbe(StrategyNexthopStateLL *x) { x->lost_probes++; } -bool strategyNexthopStateLL_IsLossy(const StrategyNexthopStateLL *x){ - if(x->non_lossy_rounds < 10 || - x->avg_loss_rate > MAX_LOSS_RATE){ +bool strategyNexthopStateLL_IsLossy(const StrategyNexthopStateLL *x) { + if (x->non_lossy_rounds < 10 || x->avg_loss_rate > MAX_LOSS_RATE) { return true; } return false; } -void strategyNexthopStateLL_SetIsAllowed(StrategyNexthopStateLL *x, bool allowed){ +void strategyNexthopStateLL_SetIsAllowed(StrategyNexthopStateLL *x, + bool allowed) { x->is_allowed = allowed; } -bool strategyNexthopStateLL_IsAllowed(const StrategyNexthopStateLL *x){ +bool strategyNexthopStateLL_IsAllowed(const StrategyNexthopStateLL *x) { return x->is_allowed; } -void strategyNexthopStateLL_StartNewRound(StrategyNexthopStateLL *x){ +void strategyNexthopStateLL_StartNewRound(StrategyNexthopStateLL *x) { strategyNexthopStateLL_OptionalAssertValid(x); - if(x->sent_packets == 0) //the face was not used in the last round + if (x->sent_packets == 0) // the face was not used in the last round x->in_use = false; x->sent_packets = 0; - if(x->recevied_probes == 0){ + if (x->recevied_probes == 0) { x->rounds_without_probes++; - }else{ + } else { x->rounds_without_probes = 0; } x->recevied_probes = 0; - //compute losses in this round - if(x->sent_probes != 0){ - double loss_rate = (double) x->lost_probes / (double) x->sent_probes; + // compute losses in this round + if (x->sent_probes != 0) { + double loss_rate = (double)x->lost_probes / (double)x->sent_probes; x->avg_loss_rate = x->avg_loss_rate * 0.7 + loss_rate * 0.3; - if(x->avg_loss_rate > MAX_LOSS_RATE){ + if (x->avg_loss_rate > MAX_LOSS_RATE) { x->non_lossy_rounds = 0; - }else{ + } else { x->non_lossy_rounds++; } } |