Skip to content

Commit

Permalink
Merge branch 'master' into rpmarvell_wred_statistics_swss_changes
Browse files Browse the repository at this point in the history
  • Loading branch information
rpmarvell authored May 26, 2023
2 parents 7f47884 + 1b1c10a commit 6343045
Show file tree
Hide file tree
Showing 17 changed files with 754 additions and 56 deletions.
68 changes: 38 additions & 30 deletions cfgmgr/buffer_check_headroom_mellanox.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

local port = KEYS[1]
local input_profile_name = ARGV[1]
local input_profile_size = ARGV[2]
local input_profile_size = tonumber(ARGV[2])
local new_pg = ARGV[3]

local function is_port_with_8lanes(lanes)
Expand Down Expand Up @@ -60,7 +60,8 @@ if is_port_with_8lanes(lanes) then
pipeline_latency = pipeline_latency * 2 - 1
egress_mirror_size = egress_mirror_size * 2
end
accumulative_size = accumulative_size + 2 * pipeline_latency * 1024 + egress_mirror_size
local lossy_pg_size = pipeline_latency * 1024
accumulative_size = accumulative_size + lossy_pg_size + egress_mirror_size

-- Fetch all keys in BUFFER_PG according to the port
redis.call('SELECT', appl_db)
Expand All @@ -81,41 +82,48 @@ local function get_number_of_pgs(keyname)
return size
end

local no_input_pg = true
if new_pg ~= nil then
if get_number_of_pgs(new_pg) ~= 0 then
no_input_pg = false
new_pg = 'BUFFER_PG_TABLE:' .. new_pg
end
-- Fetch all the PGs in APPL_DB, and store them into a hash table
local pg_keys = redis.call('KEYS', 'BUFFER_PG_TABLE:' .. port .. ':*')
local all_pgs = {}
for i = 1, #pg_keys do
local profile = redis.call('HGET', pg_keys[i], 'profile')
all_pgs[pg_keys[i]] = profile
end

-- Fetch all the pending PGs, and store them into the hash table
-- Overwrite any existing entries
local pending_pg_keys = redis.call('KEYS', '_BUFFER_PG_TABLE:' .. port .. ':*')
for i = 1, #pending_pg_keys do
local profile = redis.call('HGET', pending_pg_keys[i], 'profile')
-- Remove the leading underscore when storing it into the hash table
all_pgs[string.sub(pending_pg_keys[i], 2, -1)] = profile
table.insert(debuginfo, 'debug:pending entry: ' .. pending_pg_keys[i] .. ':' .. profile)
end

if new_pg ~= nil and get_number_of_pgs(new_pg) ~= 0 then
all_pgs['BUFFER_PG_TABLE:' .. new_pg] = input_profile_name
end

-- Fetch all the PGs, accumulate the sizes
-- Handle all the PGs, accumulate the sizes
-- Assume there is only one lossless profile configured among all PGs on each port
table.insert(debuginfo, 'debug:other overhead:' .. accumulative_size)
local pg_keys = redis.call('KEYS', 'BUFFER_PG_TABLE:' .. port .. ':*')
for i = 1, #pg_keys do
local profile = redis.call('HGET', pg_keys[i], 'profile')
for pg_key, profile in pairs(all_pgs) do
local current_profile_size
if profile ~= 'ingress_lossy_profile' and (no_input_pg or new_pg ~= pg_keys[i]) then
if profile ~= input_profile_name and not no_input_pg then
local referenced_profile = redis.call('HGETALL', 'BUFFER_PROFILE_TABLE:' .. profile)
for j = 1, #referenced_profile, 2 do
if referenced_profile[j] == 'size' then
current_profile_size = tonumber(referenced_profile[j+1])
end
end
else
current_profile_size = input_profile_size
profile = input_profile_name
if profile ~= input_profile_name then
local referenced_profile_size = redis.call('HGET', 'BUFFER_PROFILE_TABLE:' .. profile, 'size')
if not referenced_profile_size then
referenced_profile_size = redis.call('HGET', '_BUFFER_PROFILE_TABLE:' .. profile, 'size')
table.insert(debuginfo, 'debug:pending profile: ' .. profile)
end
accumulative_size = accumulative_size + current_profile_size * get_number_of_pgs(pg_keys[i])
table.insert(debuginfo, 'debug:' .. pg_keys[i] .. ':' .. profile .. ':' .. current_profile_size .. ':' .. get_number_of_pgs(pg_keys[i]) .. ':accu:' .. accumulative_size)
current_profile_size = tonumber(referenced_profile_size)
else
current_profile_size = input_profile_size
end
end

if not no_input_pg then
accumulative_size = accumulative_size + input_profile_size * get_number_of_pgs(new_pg)
table.insert(debuginfo, 'debug:' .. new_pg .. '*:' .. input_profile_name .. ':' .. input_profile_size .. ':' .. get_number_of_pgs(new_pg) .. ':accu:' .. accumulative_size)
if current_profile_size == 0 then
current_profile_size = lossy_pg_size
end
accumulative_size = accumulative_size + current_profile_size * get_number_of_pgs(pg_key)
table.insert(debuginfo, 'debug:' .. pg_key .. ':' .. profile .. ':' .. current_profile_size .. ':' .. get_number_of_pgs(pg_key) .. ':accu:' .. accumulative_size)
end

if max_headroom_size > accumulative_size then
Expand Down
13 changes: 9 additions & 4 deletions cfgmgr/buffermgrdyn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,10 +1051,10 @@ bool BufferMgrDynamic::isHeadroomResourceValid(const string &port, const buffer_
// profile: the profile referenced by the new_pg (if provided) or all PGs
// new_pg: which pg is newly added?

if (!profile.lossless)
if (!profile.lossless && new_pg.empty())
{
SWSS_LOG_INFO("No need to check headroom for lossy PG port %s profile %s size %s pg %s",
port.c_str(), profile.name.c_str(), profile.size.c_str(), new_pg.c_str());
SWSS_LOG_INFO("No need to check headroom for lossy PG port %s profile %s size %s without a PG specified",
port.c_str(), profile.name.c_str(), profile.size.c_str());
return true;
}

Expand Down Expand Up @@ -1497,7 +1497,7 @@ task_process_status BufferMgrDynamic::refreshPgsForPort(const string &port, cons

// Calculate whether accumulative headroom size exceeds the maximum value
// Abort if it does
if (!isHeadroomResourceValid(port, m_bufferProfileLookup[newProfile], exactly_matched_key))
if (!isHeadroomResourceValid(port, m_bufferProfileLookup[newProfile], key))
{
SWSS_LOG_ERROR("Update speed (%s) and cable length (%s) for port %s failed, accumulative headroom size exceeds the limit",
speed.c_str(), cable_length.c_str(), port.c_str());
Expand Down Expand Up @@ -3005,6 +3005,11 @@ task_process_status BufferMgrDynamic::handleSingleBufferPgEntry(const string &ke
bufferPg.dynamic_calculated = profileRef.dynamic_calculated;
bufferPg.configured_profile_name = profileName;
bufferPg.lossless = profileRef.lossless;
if (!profileRef.lossless && !isHeadroomResourceValid(port, profileRef, key))
{
SWSS_LOG_ERROR("Unable to configure lossy PG %s, accumulative headroom size exceeds the limit", key.c_str());
return task_process_status::task_failed;
}
}
bufferPg.static_configured = true;
bufferPg.configured_profile_name = profileName;
Expand Down
124 changes: 124 additions & 0 deletions orchagent/aclorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extern CrmOrch *gCrmOrch;

#define STATE_DB_ACL_ACTION_FIELD_IS_ACTION_LIST_MANDATORY "is_action_list_mandatory"
#define STATE_DB_ACL_ACTION_FIELD_ACTION_LIST "action_list"
#define STATE_DB_ACL_L3V4V6_SUPPORTED "supported_L3V4V6"
#define COUNTERS_ACL_COUNTER_RULE_MAP "ACL_COUNTER_RULE_MAP"

#define ACL_COUNTER_DEFAULT_POLLING_INTERVAL_MS 10000 // ms
Expand Down Expand Up @@ -202,6 +203,26 @@ static acl_table_action_list_lookup_t defaultAclActionList =
}
}
},
{
// L3V4V6
TABLE_TYPE_L3V4V6,
{
{
ACL_STAGE_INGRESS,
{
SAI_ACL_ACTION_TYPE_PACKET_ACTION,
SAI_ACL_ACTION_TYPE_REDIRECT
}
},
{
ACL_STAGE_EGRESS,
{
SAI_ACL_ACTION_TYPE_PACKET_ACTION,
SAI_ACL_ACTION_TYPE_REDIRECT
}
}
}
},
{
// MIRROR
TABLE_TYPE_MIRROR,
Expand Down Expand Up @@ -2303,6 +2324,19 @@ bool AclTable::validate()
return false;
}

if (type.getName() == TABLE_TYPE_L3V4V6)
{
if (!m_pAclOrch->isAclL3V4V6TableSupported(stage))
{

SWSS_LOG_ERROR("Table %s: table type %s in stage %d not supported on this platform.",
id.c_str(), type.getName().c_str(), stage);
return false;
}
}



if (m_pAclOrch->isAclActionListMandatoryOnTableCreation(stage))
{
if (type.getActions().empty())
Expand Down Expand Up @@ -3060,11 +3094,36 @@ void AclOrch::init(vector<TableConnector>& connectors, PortsOrch *portOrch, Mirr
};
}

if ( platform == MRVL_PLATFORM_SUBSTRING ||
platform == INVM_PLATFORM_SUBSTRING ||
platform == VS_PLATFORM_SUBSTRING)
{
m_L3V4V6Capability =
{
{ACL_STAGE_INGRESS, true},
{ACL_STAGE_EGRESS, true},
};
}
else
{
m_L3V4V6Capability =
{
{ACL_STAGE_INGRESS, false},
{ACL_STAGE_EGRESS, false},
};

}


SWSS_LOG_NOTICE("%s switch capability:", platform.c_str());
SWSS_LOG_NOTICE(" TABLE_TYPE_MIRROR: %s",
m_mirrorTableCapabilities[TABLE_TYPE_MIRROR] ? "yes" : "no");
SWSS_LOG_NOTICE(" TABLE_TYPE_MIRRORV6: %s",
m_mirrorTableCapabilities[TABLE_TYPE_MIRRORV6] ? "yes" : "no");
SWSS_LOG_NOTICE(" TABLE_TYPE_L3V4V6: Ingress [%s], Egress [%s]",
m_L3V4V6Capability[ACL_STAGE_INGRESS] ? "yes" : "no",
m_L3V4V6Capability[ACL_STAGE_EGRESS] ? "yes" : "no");


// In Mellanox platform, V4 and V6 rules are stored in different tables
// In Broadcom DNX platform also, V4 and V6 rules are stored in different tables
Expand Down Expand Up @@ -3179,6 +3238,31 @@ void AclOrch::initDefaultTableTypes()
.build()
);


addAclTableType(
builder.withName(TABLE_TYPE_L3V4V6)
.withBindPointType(SAI_ACL_BIND_POINT_TYPE_PORT)
.withBindPointType(SAI_ACL_BIND_POINT_TYPE_LAG)
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_ACL_IP_TYPE))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_SRC_IP))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_DST_IP))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_ICMP_TYPE))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_ICMP_CODE))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_SRC_IPV6))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_DST_IPV6))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_CODE))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_TYPE))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_IPV6_NEXT_HEADER))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_L4_DST_PORT))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS))
.withMatch(make_shared<AclTableMatch>(SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS))
.build()
);

addAclTableType(
builder.withName(TABLE_TYPE_MCLAG)
.withBindPointType(SAI_ACL_BIND_POINT_TYPE_PORT)
Expand Down Expand Up @@ -3420,10 +3504,21 @@ void AclOrch::putAclActionCapabilityInDB(acl_stage_type_t stage)
}
}


is_action_list_mandatory_stream << boolalpha << capabilities.isActionListMandatoryOnTableCreation;

fvVector.emplace_back(STATE_DB_ACL_ACTION_FIELD_IS_ACTION_LIST_MANDATORY, is_action_list_mandatory_stream.str());
fvVector.emplace_back(STATE_DB_ACL_ACTION_FIELD_ACTION_LIST, acl_action_value_stream.str());

for (auto const& it : m_L3V4V6Capability)
{
string value = it.second ? "true" : "false";
if (it.first == stage)
{
fvVector.emplace_back(STATE_DB_ACL_L3V4V6_SUPPORTED, value);
}
}

m_aclStageCapabilityTable.set(stage_str, fvVector);
}

Expand Down Expand Up @@ -4231,6 +4326,16 @@ bool AclOrch::isAclActionListMandatoryOnTableCreation(acl_stage_type_t stage) co
return it->second.isActionListMandatoryOnTableCreation;
}

bool AclOrch::isAclL3V4V6TableSupported(acl_stage_type_t stage) const
{
const auto& it = m_L3V4V6Capability.find(stage);
if (it == m_L3V4V6Capability.cend())
{
return false;
}
return it->second;
}

bool AclOrch::isAclActionSupported(acl_stage_type_t stage, sai_acl_action_type_t action) const
{
const auto& it = m_aclCapabilities.find(stage);
Expand Down Expand Up @@ -4484,6 +4589,8 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
}
bool bHasTCPFlag = false;
bool bHasIPProtocol = false;
bool bHasIPV4 = false;
bool bHasIPV6 = false;
for (const auto& itr : kfvFieldsValues(t))
{
string attr_name = to_upper(fvField(itr));
Expand All @@ -4494,6 +4601,14 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
{
bHasTCPFlag = true;
}
if (attr_name == MATCH_SRC_IP || attr_name == MATCH_DST_IP)
{
bHasIPV4 = true;
}
if (attr_name == MATCH_SRC_IPV6 || attr_name == MATCH_DST_IPV6)
{
bHasIPV6 = true;
}
if (attr_name == MATCH_IP_PROTOCOL || attr_name == MATCH_NEXT_HEADER)
{
bHasIPProtocol = true;
Expand Down Expand Up @@ -4542,6 +4657,15 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
}
}

if (bHasIPV4 && bHasIPV6)
{
if (type == TABLE_TYPE_L3V4V6)
{
SWSS_LOG_ERROR("Rule '%s' is invalid since it has both v4 and v6 matchfields.", rule_id.c_str());
bAllAttributesOk = false;
}
}

// validate and create ACL rule
if (bAllAttributesOk && newRule->validate())
{
Expand Down
2 changes: 2 additions & 0 deletions orchagent/aclorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,14 @@ class AclOrch : public Orch, public Observer
bool isAclMirrorV6Supported() const;
bool isAclMirrorV4Supported() const;
bool isAclMirrorTableSupported(string type) const;
bool isAclL3V4V6TableSupported(acl_stage_type_t stage) const;
bool isAclActionListMandatoryOnTableCreation(acl_stage_type_t stage) const;
bool isAclActionSupported(acl_stage_type_t stage, sai_acl_action_type_t action) const;
bool isAclActionEnumValueSupported(sai_acl_action_type_t action, sai_acl_action_parameter_t param) const;

bool m_isCombinedMirrorV6Table = true;
map<string, bool> m_mirrorTableCapabilities;
map<acl_stage_type_t, bool> m_L3V4V6Capability;

void registerFlexCounter(const AclRule& rule);
void deregisterFlexCounter(const AclRule& rule);
Expand Down
1 change: 1 addition & 0 deletions orchagent/acltable.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extern "C" {

#define TABLE_TYPE_L3 "L3"
#define TABLE_TYPE_L3V6 "L3V6"
#define TABLE_TYPE_L3V4V6 "L3V4V6"
#define TABLE_TYPE_MIRROR "MIRROR"
#define TABLE_TYPE_MIRRORV6 "MIRRORV6"
#define TABLE_TYPE_MIRROR_DSCP "MIRROR_DSCP"
Expand Down
Loading

0 comments on commit 6343045

Please sign in to comment.