From 7210b0c258fb0b4cb9a8e755c87b43ea14041dca Mon Sep 17 00:00:00 2001 From: Ashish Singh Date: Wed, 25 Oct 2023 00:15:59 -0700 Subject: [PATCH 1/2] [Link event damping] Add utility methods. (#1313) - Adding utility methods to calculate: 1) Remaining value of a substance after time t using half-life formula. 2) Time to reach a target value using half-life formula. HLD: sonic-net/SONiC#1071 --- lib/Utils.cpp | 39 +++++++++++++ lib/Utils.h | 11 ++++ unittest/lib/TestUtils.cpp | 110 +++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+) diff --git a/lib/Utils.cpp b/lib/Utils.cpp index 12e757a2c..21c5c8b3f 100644 --- a/lib/Utils.cpp +++ b/lib/Utils.cpp @@ -7,6 +7,8 @@ extern "C" { #include "meta/sai_serialize.h" #include "swss/logger.h" +#include + using namespace sairedis; void Utils::clearOidList( @@ -80,3 +82,40 @@ void Utils::clearOidValues( } } + +uint64_t Utils::timeToReachTargetValueUsingHalfLife( + _In_ uint64_t halfLifeUsec, + _In_ uint32_t initialValue, + _In_ uint32_t targetValue) +{ + SWSS_LOG_ENTER(); + + // Check if all the input fields have positive values and targeted value is + // smaller than initial value. + if ((initialValue == 0) || (targetValue == 0) || + (targetValue >= initialValue) || (halfLifeUsec == 0)) + { + return 0; + } + + // t = -half_life * log2[N(t)/N(0)] from half-life formula "N(t) = N(0) * 2 ^ (-t / half_life)" + return uint64_t(-double(halfLifeUsec) * (log(double(targetValue)/double(initialValue))/log(2.0))); +} + +uint32_t Utils::valueAfterDecay( + _In_ uint64_t timeToDecayUsec, + _In_ uint64_t halfLifeUsec, + _In_ uint32_t initialValue) +{ + SWSS_LOG_ENTER(); + + if ((initialValue == 0) || (timeToDecayUsec == 0) || (halfLifeUsec == 0)) + { + return initialValue; + } + + // Using half-life formula: N(t) = N(0) * 2 ^ (-t / half_life) + double ratio = double(timeToDecayUsec)/double(halfLifeUsec); + + return uint32_t(double(initialValue) * pow(0.5, ratio)); +} diff --git a/lib/Utils.h b/lib/Utils.h index f068a4d4b..34327706b 100644 --- a/lib/Utils.h +++ b/lib/Utils.h @@ -33,5 +33,16 @@ namespace sairedis static void clearOidList( _Out_ sai_object_list_t& list); + + static uint64_t timeToReachTargetValueUsingHalfLife( + _In_ uint64_t halfLifeUsec, + _In_ uint32_t initialValue, + _In_ uint32_t targetValue); + + static uint32_t valueAfterDecay( + _In_ uint64_t timeToDecayUsec, + _In_ uint64_t halfLifeUsec, + _In_ uint32_t initialValue); + }; } diff --git a/unittest/lib/TestUtils.cpp b/unittest/lib/TestUtils.cpp index 3a9e29053..cc91c8505 100644 --- a/unittest/lib/TestUtils.cpp +++ b/unittest/lib/TestUtils.cpp @@ -4,6 +4,8 @@ #include +#include + using namespace sairedis; TEST(Utils, clearOidValues) @@ -59,3 +61,111 @@ TEST(Utils, clearOidValues) EXPECT_EQ(oids[0], 0); } + +struct ExpectedTimeToReachTargetData +{ + uint64_t half_life_usec; + uint32_t initial_value; + uint32_t target_value; + uint64_t expected_time_to_reach_target_usec; +}; + +TEST(Utils, TimeToReachTargetValueUsingHalfLifeWithInvalidInput) +{ + std::vector testData = { + /*Invalid input when initial value is 0.*/ {5, 0, 10, 0}, + /*Invalid input when target value is 0.*/ {5, 10, 0, 0}, + /*Invalid input when target value is more than initial value.*/ + {5, 5, 10, 0}, + /*Invalid input when initial value is same as target value.*/ + {5, 10, 10, 0}, + /*Invalid input when half life duration is 0.*/ {0, 15, 10, 0}}; + + for (const auto &data : testData) + { + SCOPED_TRACE(::testing::Message() + << "Testing half life(usec): " << data.half_life_usec + << ", initial value: " << data.initial_value + << ", final value: " << data.target_value + << ", expected_time_to_reach_target(usec): " + << data.expected_time_to_reach_target_usec); + + EXPECT_EQ(Utils::timeToReachTargetValueUsingHalfLife( + data.half_life_usec, data.initial_value, data.target_value), + data.expected_time_to_reach_target_usec); + } +} + +TEST(Utils, VerifyTimeToReachTargetValueUsingHalfLife) +{ + std::vector testData = { + {30000000, 4500, 500, 95097750}, {30000000, 4500, 1100, 60972644}, + {30000000, 4500, 1700, 42131707}, {8000000, 17000, 1300, 29671609}, + {8000000, 17000, 350, 44816288}, {8000000, 1532, 311, 18403438}, + {8000000, 1532, 1, 84649604}, {5000000, 20000, 2500, 15000000}, + {5000000, 20000, 133, 36162149}, {30000000, 2000, 1500, 12451124}}; + + for (const auto &data : testData) + { + SCOPED_TRACE(::testing::Message() + << "Testing half life(usec): " << data.half_life_usec + << ", initial value: " << data.initial_value + << ", final value: " << data.target_value + << ", expected_time_to_reach_target(usec): " + << data.expected_time_to_reach_target_usec); + + EXPECT_EQ(Utils::timeToReachTargetValueUsingHalfLife( + data.half_life_usec, data.initial_value, data.target_value), + data.expected_time_to_reach_target_usec); + } +} + +struct ValueAFterDecayData +{ + uint64_t time_to_decay_usec; + uint32_t half_life_usec; + uint32_t initial_value; + uint32_t expected_target_value; +}; + +TEST(Utils, ValueAfterDecayWithInvalidInput) +{ + std::vector test_data = { + /*Invalid input when time to decay duration is 0.*/ {0, 5, 10, 10}, + /*Invalid input when half life is 0.*/ {5, 0, 10, 10}, + /*Invalid input when initial value is 0.*/ {5, 5, 0, 0}}; + + for (const auto &data : test_data) + { + SCOPED_TRACE(::testing::Message() + << "Testing time to decay(usec): " << data.time_to_decay_usec + << ", half life(usec): " << data.half_life_usec + << ", initial value: " << data.initial_value + << ", expected target value: " << data.expected_target_value); + + EXPECT_EQ(Utils::valueAfterDecay( + data.time_to_decay_usec, data.half_life_usec, data.initial_value), + data.expected_target_value); + } +} + +TEST(Utils, VerifyValueAfterDecay) +{ + std::vector test_data = { + {15345678, 5000000, 20000, 2383}, + {3000000, 5000000, 20000, 13195}, + {37256870, 5000000, 15, 0}}; + + for (const auto &data : test_data) + { + SCOPED_TRACE(::testing::Message() + << "Testing time to decay(usec): " << data.time_to_decay_usec + << ", half life(usec): " << data.half_life_usec + << ", initial value: " << data.initial_value + << ", expected target value: " << data.expected_target_value); + + EXPECT_EQ(Utils::valueAfterDecay( + data.time_to_decay_usec, data.half_life_usec, data.initial_value), + data.expected_target_value); + } +} From 15fa9075bba1b0b5ebc727eae666921b9c46792a Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Sat, 28 Oct 2023 14:42:02 +0200 Subject: [PATCH 2/2] [syncd] Add pre match logic for pfc storm (#1309) Special case where priority is the same for all acl --- syncd/ComparisonLogic.cpp | 20 +++++++++++++++++++- tests/BCM56850.pl | 10 ++++++++++ tests/BCM56850/acl_pre_match_999.rec | 22 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/BCM56850/acl_pre_match_999.rec diff --git a/syncd/ComparisonLogic.cpp b/syncd/ComparisonLogic.cpp index adb24930a..674153e3d 100644 --- a/syncd/ComparisonLogic.cpp +++ b/syncd/ComparisonLogic.cpp @@ -2806,6 +2806,8 @@ void ComparisonLogic::cretePreMatchForLagMembers( } } +#define PFC_ACL_RULE_PRIORITY "999" + void ComparisonLogic::cretePreMatchForAclEntries( _In_ const AsicView& cur, _Inout_ AsicView& tmp, @@ -2836,8 +2838,24 @@ void ComparisonLogic::cretePreMatchForAclEntries( continue; } + if (cPrio->getStrAttrValue() == PFC_ACL_RULE_PRIORITY) + { + // this is special case, all pfc rules to prevent packet storm + // will have same priority, we will need to check SAI_ACL_ENTRY_ATTR_FIELD_TC + + auto cTc = cAclEntry->tryGetSaiAttr(SAI_ACL_ENTRY_ATTR_FIELD_TC); + auto tTc = tAclEntry->tryGetSaiAttr(SAI_ACL_ENTRY_ATTR_FIELD_TC); + + if (!cTc || !tTc || cTc->getStrAttrValue() != tTc->getStrAttrValue()) + { + // TC attribute is different, not looking for this one + continue; + } + } + // at this point current and temporary acl entry share the same - // priority, then we can assume that those objects are the same + // priority and in case of pfc priority, also the same TC field, + // then we can assume that those objects are the same SWSS_LOG_NOTICE("pre match Acl Entry: cur: %s, tmp: %s, using prio: %s", cAclEntry->m_str_object_id.c_str(), diff --git a/tests/BCM56850.pl b/tests/BCM56850.pl index 7e5eab90c..5127757c7 100755 --- a/tests/BCM56850.pl +++ b/tests/BCM56850.pl @@ -819,8 +819,18 @@ sub test_relaxed play "relaxed.rec", 0; } +sub test_acl_pre_match_999 +{ + fresh_start; + + play "acl_pre_match_999.rec"; + + for (1..8) { play "acl_pre_match_999.rec", 0; } +} + # RUN TESTS +test_acl_pre_match_999; test_relaxed; test_acl_counter_match; test_neighbor_lag; diff --git a/tests/BCM56850/acl_pre_match_999.rec b/tests/BCM56850/acl_pre_match_999.rec new file mode 100644 index 000000000..bcec378e9 --- /dev/null +++ b/tests/BCM56850/acl_pre_match_999.rec @@ -0,0 +1,22 @@ +2023-04-09.06:05:51.758572|a|INIT_VIEW +2023-04-09.06:05:54.894996|A|SAI_STATUS_SUCCESS +2023-04-09.06:05:54.898126|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY=0x55e3e3d2db30|SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY=0x55e3e3d2db40|SAI_SWITCH_ATTR_SWITCH_SHUTDOWN_REQUEST_NOTIFY=0x55e3e3d2db60|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=94:8E:D3:B8:D1:48 +2023-04-09.06:06:01.316781|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2023-04-09.06:06:01.320955|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000002,oid:0x1000000000003,oid:0x1000000000004,oid:0x1000000000005,oid:0x1000000000006,oid:0x1000000000007,oid:0x1000000000008,oid:0x1000000000009,oid:0x100000000000a,oid:0x100000000000b,oid:0x100000000000c,oid:0x100000000000d,oid:0x100000000000e,oid:0x100000000000f,oid:0x1000000000010,oid:0x1000000000011,oid:0x1000000000012,oid:0x1000000000013,oid:0x1000000000014,oid:0x1000000000015,oid:0x1000000000016,oid:0x1000000000017,oid:0x1000000000018,oid:0x1000000000019,oid:0x100000000001a,oid:0x100000000001b,oid:0x100000000001c,oid:0x100000000001d,oid:0x100000000001e,oid:0x100000000001f,oid:0x1000000000020,oid:0x1000000000021 +2023-04-09.06:06:06.534280|c|SAI_OBJECT_TYPE_ACL_TABLE:oid:0x700000000069f|SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST=2:SAI_ACL_BIND_POINT_TYPE_PORT,SAI_ACL_BIND_POINT_TYPE_LAG|SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_IP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IP=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IP=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL=true|SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IPV6_NEXT_HEADER=true|SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_L4_DST_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE=2:SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE,SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE|SAI_ACL_TABLE_ATTR_ACL_STAGE=SAI_ACL_STAGE_INGRESS|SAI_ACL_TABLE_ATTR_FIELD_DSCP=true +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x700000000069f|SAI_ACL_ENTRY_ATTR_PRIORITY=999|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=3&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION=SAI_PACKET_ACTION_DROP|SAI_ACL_ENTRY_ATTR_FIELD_TC=3&mask:0xff +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x700000000069f|SAI_ACL_ENTRY_ATTR_PRIORITY=999|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=3&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION=SAI_PACKET_ACTION_DROP|SAI_ACL_ENTRY_ATTR_FIELD_TC=4&mask:0xff +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x700000000069f|SAI_ACL_ENTRY_ATTR_PRIORITY=999|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=3&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION=SAI_PACKET_ACTION_DROP|SAI_ACL_ENTRY_ATTR_FIELD_TC=5&mask:0xff +2023-04-09.06:06:01.989510|a|APPLY_VIEW +2023-04-09.06:06:01.990574|A|SAI_STATUS_SUCCESS +2023-04-09.06:16:00.119350|a|INIT_VIEW +2023-04-09.06:16:10.264317|A|SAI_STATUS_SUCCESS +2023-04-09.06:16:10.268256|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY=0x5631fe2d0b30|SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY=0x5631fe2d0b40|SAI_SWITCH_ATTR_SWITCH_SHUTDOWN_REQUEST_NOTIFY=0x5631fe2d0b60|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=94:8E:D3:B8:D1:48 +2023-04-09.06:16:10.314901|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2023-04-09.06:16:10.323831|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000002,oid:0x1000000000003,oid:0x1000000000004,oid:0x1000000000005,oid:0x1000000000006,oid:0x1000000000007,oid:0x1000000000008,oid:0x1000000000009,oid:0x100000000000a,oid:0x100000000000b,oid:0x100000000000c,oid:0x100000000000d,oid:0x100000000000e,oid:0x100000000000f,oid:0x1000000000010,oid:0x1000000000011,oid:0x1000000000012,oid:0x1000000000013,oid:0x1000000000014,oid:0x1000000000015,oid:0x1000000000016,oid:0x1000000000017,oid:0x1000000000018,oid:0x1000000000019,oid:0x100000000001a,oid:0x100000000001b,oid:0x100000000001c,oid:0x100000000001d,oid:0x100000000001e,oid:0x100000000001f,oid:0x1000000000020,oid:0x1000000000021 +2023-04-09.06:16:16.176451|c|SAI_OBJECT_TYPE_ACL_TABLE:oid:0x7000000000ba4|SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST=2:SAI_ACL_BIND_POINT_TYPE_PORT,SAI_ACL_BIND_POINT_TYPE_LAG|SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_IP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IP=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IP=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL=true|SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IPV6_NEXT_HEADER=true|SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_L4_DST_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE=2:SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE,SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE|SAI_ACL_TABLE_ATTR_ACL_STAGE=SAI_ACL_STAGE_INGRESS|SAI_ACL_TABLE_ATTR_FIELD_DSCP=true +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_ENTRY_ATTR_PRIORITY=999|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=3&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION=SAI_PACKET_ACTION_DROP|SAI_ACL_ENTRY_ATTR_FIELD_TC=5&mask:0xff +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_ENTRY_ATTR_PRIORITY=999|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=3&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION=SAI_PACKET_ACTION_DROP|SAI_ACL_ENTRY_ATTR_FIELD_TC=4&mask:0xff +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_ENTRY_ATTR_PRIORITY=999|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=3&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION=SAI_PACKET_ACTION_DROP|SAI_ACL_ENTRY_ATTR_FIELD_TC=3&mask:0xff +2023-04-09.06:16:19.214593|a|APPLY_VIEW +2023-04-09.06:16:21.919159|A|SAI_STATUS_SUCCESS