@@ -32,6 +32,8 @@ extern CrmOrch *gCrmOrch;
3232
3333acl_rule_attr_lookup_t aclMatchLookup =
3434{
35+ { MATCH_IN_PORTS, SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS },
36+ { MATCH_OUT_PORTS, SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS },
3537 { MATCH_SRC_IP, SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP },
3638 { MATCH_DST_IP, SAI_ACL_ENTRY_ATTR_FIELD_DST_IP },
3739 { MATCH_SRC_IPV6, SAI_ACL_ENTRY_ATTR_FIELD_SRC_IPV6 },
@@ -108,15 +110,6 @@ static acl_ip_type_lookup_t aclIpTypeLookup =
108110 { IP_TYPE_ARP_REPLY, SAI_ACL_IP_TYPE_ARP_REPLY }
109111};
110112
111- inline string toUpper (const string& str)
112- {
113- string uppercase = str;
114-
115- transform (uppercase.begin (), uppercase.end (), uppercase.begin (), ::toupper);
116-
117- return uppercase;
118- }
119-
120113inline string trim (const std::string& str, const std::string& whitespace = " \t " )
121114{
122115 const auto strBegin = str.find_first_not_of (whitespace);
@@ -171,9 +164,59 @@ bool AclRule::validateAddMatch(string attr_name, string attr_value)
171164 {
172165 if (aclMatchLookup.find (attr_name) == aclMatchLookup.end ())
173166 {
167+ SWSS_LOG_ERROR (" Failed to locate match criterion %s" ,
168+ attr_name.c_str ());
174169 return false ;
175170 }
176- else if (attr_name == MATCH_IP_TYPE)
171+ else if (attr_name == MATCH_IN_PORTS)
172+ {
173+ auto ports = tokenize (attr_value, ' ,' );
174+
175+ if (ports.size () == 0 )
176+ {
177+ return false ;
178+ }
179+
180+ m_inPorts.clear ();
181+ for (auto alias : ports)
182+ {
183+ Port port;
184+ if (!gPortsOrch ->getPort (alias, port))
185+ {
186+ SWSS_LOG_ERROR (" Failed to locate port %s" , alias.c_str ());
187+ return false ;
188+ }
189+ m_inPorts.push_back (port.m_port_id );
190+ }
191+
192+ value.aclfield .data .objlist .count = static_cast <uint32_t >(m_inPorts.size ());
193+ value.aclfield .data .objlist .list = m_inPorts.data ();
194+ }
195+ else if (attr_name == MATCH_OUT_PORTS)
196+ {
197+ auto ports = tokenize (attr_value, ' ,' );
198+
199+ if (ports.size () == 0 )
200+ {
201+ return false ;
202+ }
203+
204+ m_outPorts.clear ();
205+ for (auto alias : ports)
206+ {
207+ Port port;
208+ if (!gPortsOrch ->getPort (alias, port))
209+ {
210+ SWSS_LOG_ERROR (" Failed to locate port %s" , alias.c_str ());
211+ return false ;
212+ }
213+ m_outPorts.push_back (port.m_port_id );
214+ }
215+
216+ value.aclfield .data .objlist .count = static_cast <uint32_t >(m_outPorts.size ());
217+ value.aclfield .data .objlist .list = m_outPorts.data ();
218+ }
219+ else if (attr_name == MATCH_IP_TYPE)
177220 {
178221 if (!processIpType (attr_value, value.aclfield .data .u32 ))
179222 {
@@ -183,7 +226,7 @@ bool AclRule::validateAddMatch(string attr_name, string attr_value)
183226
184227 value.aclfield .mask .u32 = 0xFFFFFFFF ;
185228 }
186- else if (attr_name == MATCH_TCP_FLAGS)
229+ else if (attr_name == MATCH_TCP_FLAGS)
187230 {
188231 vector<string> flagsData;
189232 string flags, mask;
@@ -220,12 +263,12 @@ bool AclRule::validateAddMatch(string attr_name, string attr_value)
220263 }
221264 value.aclfield .mask .u8 = (uint8_t )val;
222265 }
223- else if (attr_name == MATCH_ETHER_TYPE || attr_name == MATCH_L4_SRC_PORT || attr_name == MATCH_L4_DST_PORT)
266+ else if (attr_name == MATCH_ETHER_TYPE || attr_name == MATCH_L4_SRC_PORT || attr_name == MATCH_L4_DST_PORT)
224267 {
225268 value.aclfield .data .u16 = to_uint<uint16_t >(attr_value);
226269 value.aclfield .mask .u16 = 0xFFFF ;
227270 }
228- else if (attr_name == MATCH_DSCP)
271+ else if (attr_name == MATCH_DSCP)
229272 {
230273 /* Support both exact value match and value/mask match */
231274 auto dscp_data = tokenize (attr_value, ' /' );
@@ -241,7 +284,7 @@ bool AclRule::validateAddMatch(string attr_name, string attr_value)
241284 value.aclfield .mask .u8 = 0x3F ;
242285 }
243286 }
244- else if (attr_name == MATCH_IP_PROTOCOL)
287+ else if (attr_name == MATCH_IP_PROTOCOL)
245288 {
246289 value.aclfield .data .u8 = to_uint<uint8_t >(attr_value);
247290 value.aclfield .mask .u8 = 0xFF ;
@@ -286,7 +329,7 @@ bool AclRule::validateAddMatch(string attr_name, string attr_value)
286329 return false ;
287330 }
288331 }
289- else if (attr_name == MATCH_TC)
332+ else if (attr_name == MATCH_TC)
290333 {
291334 value.aclfield .data .u8 = to_uint<uint8_t >(attr_value);
292335 value.aclfield .mask .u8 = 0xFF ;
@@ -328,7 +371,7 @@ bool AclRule::processIpType(string type, sai_uint32_t &ip_type)
328371{
329372 SWSS_LOG_ENTER ();
330373
331- auto it = aclIpTypeLookup.find (toUpper (type));
374+ auto it = aclIpTypeLookup.find (to_upper (type));
332375
333376 if (it == aclIpTypeLookup.end ())
334377 {
@@ -428,7 +471,8 @@ bool AclRule::create()
428471 status = sai_acl_api->create_acl_entry (&m_ruleOid, gSwitchId , (uint32_t )rule_attrs.size (), rule_attrs.data ());
429472 if (status != SAI_STATUS_SUCCESS)
430473 {
431- SWSS_LOG_ERROR (" Failed to create ACL rule" );
474+ SWSS_LOG_ERROR (" Failed to create ACL rule %s, rv:%d" ,
475+ m_id.c_str (), status);
432476 AclRange::remove (range_objects, range_object_list.count );
433477 decreaseNextHopRefCount ();
434478 }
@@ -515,7 +559,7 @@ shared_ptr<AclRule> AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir
515559 /* Find action configured by user. Based on action type create rule. */
516560 for (const auto & itr : kfvFieldsValues (data))
517561 {
518- string attr_name = toUpper (fvField (itr));
562+ string attr_name = to_upper (fvField (itr));
519563 string attr_value = fvValue (itr);
520564 if (attr_name == ACTION_PACKET_ACTION || attr_name == ACTION_MIRROR_ACTION ||
521565 attr_name == ACTION_DTEL_FLOW_OP || attr_name == ACTION_DTEL_INT_SESSION ||
@@ -660,7 +704,7 @@ bool AclRuleL3::validateAddAction(string attr_name, string _attr_value)
660704{
661705 SWSS_LOG_ENTER ();
662706
663- string attr_value = toUpper (_attr_value);
707+ string attr_value = to_upper (_attr_value);
664708 sai_attribute_value_t value;
665709
666710 if (attr_name != ACTION_PACKET_ACTION)
@@ -764,7 +808,7 @@ sai_object_id_t AclRuleL3::getRedirectObjectId(const string& redirect_value)
764808 {
765809 SWSS_LOG_INFO (" ACL Redirect action target next hop group: '%s' doesn't exist on the switch. Creating it." , ips.to_string ().c_str ());
766810
767- if (!m_pAclOrch->m_routeOrch ->addNextHopGroup (ips))
811+ if (!m_pAclOrch->m_routeOrch ->addNextHopGroup (ips))
768812 {
769813 SWSS_LOG_ERROR (" Can't create required target next hop group '%s'" , ips.to_string ().c_str ());
770814 return SAI_NULL_OBJECT_ID;
@@ -1013,6 +1057,7 @@ bool AclTable::validate()
10131057 if (type == ACL_TABLE_UNKNOWN || type == ACL_TABLE_CTRLPLANE) return false ;
10141058 if (stage == ACL_STAGE_UNKNOWN) return false ;
10151059 if (portSet.empty ()) return false ;
1060+
10161061 return true ;
10171062}
10181063
@@ -1022,11 +1067,17 @@ bool AclTable::create()
10221067
10231068 sai_attribute_t attr;
10241069 vector<sai_attribute_t > table_attrs;
1025- vector<int32_t > bpoint_list = { SAI_ACL_BIND_POINT_TYPE_PORT, SAI_ACL_BIND_POINT_TYPE_LAG };
1070+ vector<int32_t > bpoint_list;
1071+
1072+ // PFC watch dog ACLs are only applied to port
10261073 if (type == ACL_TABLE_PFCWD)
10271074 {
10281075 bpoint_list = { SAI_ACL_BIND_POINT_TYPE_PORT };
10291076 }
1077+ else
1078+ {
1079+ bpoint_list = { SAI_ACL_BIND_POINT_TYPE_PORT, SAI_ACL_BIND_POINT_TYPE_LAG };
1080+ }
10301081
10311082 attr.id = SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST;
10321083 attr.value .s32list .count = static_cast <uint32_t >(bpoint_list.size ());
@@ -1085,6 +1136,7 @@ bool AclTable::create()
10851136 attr.value .booldata = true ;
10861137 table_attrs.push_back (attr);
10871138 }
1139+
10881140 attr.id = SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT;
10891141 attr.value .booldata = true ;
10901142 table_attrs.push_back (attr);
@@ -1097,7 +1149,7 @@ bool AclTable::create()
10971149 attr.value .booldata = true ;
10981150 table_attrs.push_back (attr);
10991151
1100- if (stage == ACL_STAGE_INGRESS)
1152+ if (stage == ACL_STAGE_INGRESS)
11011153 {
11021154 int32_t range_types_list[] = { SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE, SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE };
11031155 attr.id = SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE;
@@ -1287,7 +1339,7 @@ bool AclRuleDTelFlowWatchListEntry::validateAddAction(string attr_name, string a
12871339 SWSS_LOG_ENTER ();
12881340
12891341 sai_attribute_value_t value;
1290- string attr_value = toUpper (attr_val);
1342+ string attr_value = to_upper (attr_val);
12911343 sai_object_id_t session_oid;
12921344
12931345 if (!m_pDTelOrch ||
@@ -1366,7 +1418,7 @@ bool AclRuleDTelFlowWatchListEntry::validate()
13661418{
13671419 SWSS_LOG_ENTER ();
13681420
1369- if (!m_pDTelOrch)
1421+ if (!m_pDTelOrch)
13701422 {
13711423 return false ;
13721424 }
@@ -1503,7 +1555,7 @@ bool AclRuleDTelDropWatchListEntry::validateAddAction(string attr_name, string a
15031555 }
15041556
15051557 sai_attribute_value_t value;
1506- string attr_value = toUpper (attr_val);
1558+ string attr_value = to_upper (attr_val);
15071559
15081560 if (attr_name != ACTION_DTEL_DROP_REPORT_ENABLE &&
15091561 attr_name != ACTION_DTEL_TAIL_DROP_REPORT_ENABLE)
@@ -1556,7 +1608,7 @@ AclRange *AclRange::create(sai_acl_range_type_t type, int min, int max)
15561608
15571609 acl_range_properties_t rangeProperties = make_tuple (type, min, max);
15581610 auto range_it = m_ranges.find (rangeProperties);
1559- if (range_it == m_ranges.end ())
1611+ if (range_it == m_ranges.end ())
15601612 {
15611613 sai_attribute_t attr;
15621614 vector<sai_attribute_t > range_attrs;
@@ -1611,7 +1663,7 @@ bool AclRange::remove(sai_acl_range_type_t type, int min, int max)
16111663
16121664 auto range_it = m_ranges.find (make_tuple (type, min, max));
16131665
1614- if (range_it == m_ranges.end ())
1666+ if (range_it == m_ranges.end ())
16151667 {
16161668 return false ;
16171669 }
@@ -1733,7 +1785,7 @@ AclOrch::~AclOrch()
17331785{
17341786 m_mirrorOrch->detach (this );
17351787
1736- if (m_dTelOrch)
1788+ if (m_dTelOrch)
17371789 {
17381790 m_dTelOrch->detach (this );
17391791 }
@@ -1905,7 +1957,7 @@ void AclOrch::doAclTableTask(Consumer &consumer)
19051957 {
19061958 newTable.id = table_id;
19071959
1908- string attr_name = toUpper (fvField (itp));
1960+ string attr_name = to_upper (fvField (itp));
19091961 string attr_value = fvValue (itp);
19101962
19111963 SWSS_LOG_DEBUG (" TABLE ATTRIBUTE: %s : %s" , attr_name.c_str (), attr_value.c_str ());
@@ -2016,7 +2068,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
20162068
20172069 for (const auto & itr : kfvFieldsValues (t))
20182070 {
2019- string attr_name = toUpper (fvField (itr));
2071+ string attr_name = to_upper (fvField (itr));
20202072 string attr_value = fvValue (itr);
20212073
20222074 SWSS_LOG_INFO (" ATTRIBUTE: %s %s" , attr_name.c_str (), attr_value.c_str ());
@@ -2044,7 +2096,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
20442096 // validate and create ACL rule
20452097 if (bAllAttributesOk && newRule->validate ())
20462098 {
2047- if (addAclRule (newRule, table_id))
2099+ if (addAclRule (newRule, table_id))
20482100 it = consumer.m_toSync .erase (it);
20492101 else
20502102 it++;
@@ -2057,7 +2109,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
20572109 }
20582110 else if (op == DEL_COMMAND)
20592111 {
2060- if (removeAclRule (table_id, rule_id))
2112+ if (removeAclRule (table_id, rule_id))
20612113 it = consumer.m_toSync .erase (it);
20622114 else
20632115 it++;
@@ -2213,7 +2265,7 @@ bool AclOrch::processAclTableType(string type, acl_table_type_t &table_type)
22132265{
22142266 SWSS_LOG_ENTER ();
22152267
2216- auto tt = aclTableTypeLookUp.find (toUpper (type));
2268+ auto tt = aclTableTypeLookUp.find (to_upper (type));
22172269
22182270 if (tt == aclTableTypeLookUp.end ())
22192271 {
@@ -2229,7 +2281,7 @@ bool AclOrch::processAclTableStage(string stage, acl_stage_type_t &acl_stage)
22292281{
22302282 SWSS_LOG_ENTER ();
22312283
2232- auto iter = aclStageLookUp.find (toUpper (stage));
2284+ auto iter = aclStageLookUp.find (to_upper (stage));
22332285
22342286 if (iter == aclStageLookUp.end ())
22352287 {
0 commit comments