sfc: add basic flower matches to offload
Subsystems (3)
v2 cover sfc: add basic flower matches to offload
From: Edward Cree <[email protected]>
Support offloading TC flower rules with matches on L2-L4 fields.
Changed in v2:
* changed CHECK macro to not hide control flow. Annoyingly, gcc complains if we don't use the result of the OR-expression we're using to get short- circuiting behaviour (ensuring we only report the first error), so we have to have an if-statement that's semantically redundant.
* added explanation to patch #1 of why these checks aren't vital for correctness (and thus don't need to have a Fixes tag or go to net).
Edward Cree (5):
sfc: check recirc_id match caps before MAE offload
sfc: add Layer 2 matches to ef100 TC offload
sfc: add Layer 3 matches to ef100 TC offload
sfc: add Layer 3 flag matches to ef100 TC offload
sfc: add Layer 4 matches to ef100 TC offload
drivers/net/ethernet/sfc/mae.c | 131 ++++++++++++++++++++++++++++++ drivers/net/ethernet/sfc/mcdi.h | 12 +++ drivers/net/ethernet/sfc/tc.c | 137 +++++++++++++++++++++++++++++--- drivers/net/ethernet/sfc/tc.h | 16 ++++ 4 files changed, 285 insertions(+), 11 deletions(-)
PATCH v2 1/5 sfc: check recirc_id match caps before MAE offload
From: Edward Cree <[email protected]>
Offloaded TC rules always match on recirc_id in the MAE, so we should
check that the MAE reported support for this match before attempting to insert the rule.
These checks allow us to fail early, avoiding the PCIe round-trip to
firmware for an MC_CMD_MAE_ACTION_RULE_INSERT that will only fail, and more importantly providing a more informative error message that identifies which match field is unsupported.
--- drivers/net/ethernet/sfc/mae.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/net/ethernet/sfc/mae.c +17 -0
@@ -250,6 +250,20 @@ static int efx_mae_match_check_cap_typ(u8 support, enum mask_type typ) } } +/* Validate field mask against hardware capabilities. Captures caller's 'rc' */ +#define CHECK (_mcdi, _field) ({ \ + enum mask_type typ = classify_mask((const u8 *)&mask->_field, \ + sizeof(mask->_field)); \ + \ + rc = efx_mae_match_check_cap_typ(supported_fields[MAE_FIELD_ ## _mcdi],\ + typ); \ + if (rc) \ + NL_SET_ERR_MSG_FMT_MOD(extack, \ + "No support for %s mask in field %s", \ + mask_type_name(typ), #_field); \ + rc; \ +}) +int efx_mae_match_check_caps (struct efx_nic *efx,const struct efx_tc_match_fields *mask,struct netlink_ext_ack *extack)
@@ -269,8 +283,11 @@ int efx_mae_match_check_caps(struct efx_nic *efx, mask_type_name(ingress_port_mask_type));return rc; } +if (CHECK (RECIRC_ID , recirc_id)) +return rc;return 0 ; } +#undef CHECKstatic bool efx_mae_asl_id (u32 id) {
PATCH v2 2/5 sfc: add Layer 2 matches to ef100 TC offload
In reply to [email protected]From: Edward Cree <[email protected]>
Support matching on EtherType, VLANs and ethernet source/destination
addresses, with masking if supported by the hardware.
--- drivers/net/ethernet/sfc/mae.c | 37 +++++++++++++++++++- drivers/net/ethernet/sfc/mcdi.h | 6 ++++ drivers/net/ethernet/sfc/tc.c | 62 ++++++++++++++++++++++++++++++--- drivers/net/ethernet/sfc/tc.h | 4 +++ 4 files changed, 103 insertions(+), 6 deletions(-)
drivers/net/ethernet/sfc/mae.c +36 -1
@@ -283,7 +283,14 @@ int efx_mae_match_check_caps(struct efx_nic *efx, mask_type_name(ingress_port_mask_type));return rc; } -if (CHECK (RECIRC_ID , recirc_id)) +if (CHECK (ETHER_TYPE , eth_proto) || +CHECK (VLAN0_TCI , vlan_tci[0 ]) || +CHECK (VLAN0_PROTO , vlan_proto[0 ]) || +CHECK (VLAN1_TCI , vlan_tci[1 ]) || +CHECK (VLAN1_PROTO , vlan_proto[1 ]) || +CHECK (ETH_SADDR , eth_saddr) || +CHECK (ETH_DADDR , eth_daddr) || +CHECK (RECIRC_ID , recirc_id))return rc;return 0 ; }
@@ -460,6 +467,34 @@ static int efx_mae_populate_match_criteria(MCDI_DECLARE_STRUCT_PTR(match_crit), match->value.recirc_id);MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_RECIRC_ID_MASK , match->mask.recirc_id); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETHER_TYPE_BE , + match->value.eth_proto); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETHER_TYPE_BE_MASK , + match->mask.eth_proto); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN0_TCI_BE , + match->value.vlan_tci[0 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN0_TCI_BE_MASK , + match->mask.vlan_tci[0 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN0_PROTO_BE , + match->value.vlan_proto[0 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN0_PROTO_BE_MASK , + match->mask.vlan_proto[0 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN1_TCI_BE , + match->value.vlan_tci[1 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN1_TCI_BE_MASK , + match->mask.vlan_tci[1 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN1_PROTO_BE , + match->value.vlan_proto[1 ]); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_VLAN1_PROTO_BE_MASK , + match->mask.vlan_proto[1 ]); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETH_SADDR_BE ), + match->value.eth_saddr,ETH_ALEN ); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETH_SADDR_BE_MASK ), + match->mask.eth_saddr,ETH_ALEN ); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETH_DADDR_BE ), + match->value.eth_daddr,ETH_ALEN ); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETH_DADDR_BE_MASK ), + match->mask.eth_daddr,ETH_ALEN );return 0 ; }
drivers/net/ethernet/sfc/mcdi.h +6 -0
@@ -224,6 +224,12 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);#define MCDI_WORD (_buf, _field) \ ((u16)BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 2) + \ le16_to_cpu(*(__force const __le16 *)MCDI_PTR(_buf, _field))) +/* Write a 16-bit field defined in the protocol as being big-endian. */ +#define MCDI_STRUCT_SET_WORD_BE (_buf, _field, _value) do { \ + BUILD_BUG_ON(_field ## _LEN != 2); \ + BUILD_BUG_ON(_field ## _OFST & 1); \ + *(__force __be16 *)MCDI_STRUCT_PTR(_buf, _field) = (_value); \ + } while (0)#define MCDI_SET_DWORD (_buf, _field, _value) \ EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0, _value)#define MCDI_STRUCT_SET_DWORD (_buf, _field, _value) \
drivers/net/ethernet/sfc/tc.c +57 -5
89 lines not on this page · raw message
drivers/net/ethernet/sfc/tc.h +4 -0
@@ -26,6 +26,10 @@ struct efx_tc_match_fields {/* L1 */ u32 ingress_port;u8 recirc_id; +/* L2 (inner when encap) */ +__be16 eth_proto; +__be16 vlan_tci[2 ], vlan_proto[2 ]; +u8 eth_saddr[ETH_ALEN ], eth_daddr[ETH_ALEN ]; };struct efx_tc_match {
PATCH v2 3/5 sfc: add Layer 3 matches to ef100 TC offload
In reply to [email protected]From: Edward Cree <[email protected]>
Support matching on IP protocol, Type of Service, Time To Live, source
and destination addresses, with masking if supported by the hardware.
--- drivers/net/ethernet/sfc/mae.c | 39 +++++++++++++++++++++++ drivers/net/ethernet/sfc/mcdi.h | 6 ++++ drivers/net/ethernet/sfc/tc.c | 56 +++++++++++++++++++++++++++------ drivers/net/ethernet/sfc/tc.h | 8 +++++ 4 files changed, 100 insertions(+), 9 deletions(-)
drivers/net/ethernet/sfc/mae.c +39 -0
@@ -290,6 +290,15 @@ int efx_mae_match_check_caps(struct efx_nic *efx,CHECK (VLAN1_PROTO , vlan_proto[1 ]) ||CHECK (ETH_SADDR , eth_saddr) ||CHECK (ETH_DADDR , eth_daddr) || +CHECK (IP_PROTO , ip_proto) || +CHECK (IP_TOS , ip_tos) || +CHECK (IP_TTL , ip_ttl) || +CHECK (SRC_IP4 , src_ip) || +CHECK (DST_IP4 , dst_ip) || +#ifdef CONFIG_IPV6 +CHECK (SRC_IP6 , src_ip6) || +CHECK (DST_IP6 , dst_ip6) || +#endif CHECK(RECIRC_ID, recirc_id)) return rc;return 0 ;
@@ -495,6 +504,36 @@ static int efx_mae_populate_match_criteria(MCDI_DECLARE_STRUCT_PTR(match_crit), match->value.eth_daddr, ETH_ALEN);memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_ETH_DADDR_BE_MASK ), match->mask.eth_daddr,ETH_ALEN ); +MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_PROTO , + match->value.ip_proto); +MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_PROTO_MASK , + match->mask.ip_proto); +MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_TOS , + match->value.ip_tos); +MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_TOS_MASK , + match->mask.ip_tos); +MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_TTL , + match->value.ip_ttl); +MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_TTL_MASK , + match->mask.ip_ttl); +MCDI_STRUCT_SET_DWORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_SRC_IP4_BE , + match->value.src_ip); +MCDI_STRUCT_SET_DWORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_SRC_IP4_BE_MASK , + match->mask.src_ip); +MCDI_STRUCT_SET_DWORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_DST_IP4_BE , + match->value.dst_ip); +MCDI_STRUCT_SET_DWORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_DST_IP4_BE_MASK , + match->mask.dst_ip); +#ifdef CONFIG_IPV6 +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_SRC_IP6_BE ), + &match->value.src_ip6,sizeof (struct in6_addr )); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_SRC_IP6_BE_MASK ), + &match->mask.src_ip6,sizeof (struct in6_addr )); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_DST_IP6_BE ), + &match->value.dst_ip6,sizeof (struct in6_addr )); +memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_DST_IP6_BE_MASK ), + &match->mask.dst_ip6,sizeof (struct in6_addr )); +#endif return 0 ; }
drivers/net/ethernet/sfc/mcdi.h +6 -0
@@ -236,6 +236,12 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); EFX_POPULATE_DWORD_1(*_MCDI_STRUCT_DWORD(_buf, _field), EFX_DWORD_0, _value)#define MCDI_DWORD (_buf, _field) \ EFX_DWORD_FIELD(*_MCDI_DWORD(_buf, _field), EFX_DWORD_0) +/* Write a 32-bit field defined in the protocol as being big-endian. */ +#define MCDI_STRUCT_SET_DWORD_BE (_buf, _field, _value) do { \ + BUILD_BUG_ON(_field ## _LEN != 4); \ + BUILD_BUG_ON(_field ## _OFST & 3); \ + *(__force __be32 *)MCDI_STRUCT_PTR(_buf, _field) = (_value); \ + } while (0)#define MCDI_POPULATE_DWORD_1 (_buf, _field, _name1, _value1) \ EFX_POPULATE_DWORD_1(*_MCDI_DWORD(_buf, _field), \ MC_CMD_ ## _name1, _value1)
drivers/net/ethernet/sfc/tc.c +47 -9
86 lines not on this page · raw message
drivers/net/ethernet/sfc/tc.h +8 -0
@@ -15,6 +15,8 @@#include <linux/rhashtable.h> #include "net_driver.h" +#define IS_ALL_ONES (v) (!(typeof (v))~(v)) +struct efx_tc_action_set {u16 deliver:1 ;u32 dest_mport;
@@ -30,6 +32,12 @@ struct efx_tc_match_fields {__be16 eth_proto;__be16 vlan_tci[2 ], vlan_proto[2 ];u8 eth_saddr[ETH_ALEN ], eth_daddr[ETH_ALEN ]; +/* L3 (when IP) */ +u8 ip_proto, ip_tos, ip_ttl; +__be32 src_ip, dst_ip; +#ifdef CONFIG_IPV6 +struct in6_addr src_ip6, dst_ip6; +#endif };struct efx_tc_match {
PATCH v2 4/5 sfc: add Layer 3 flag matches to ef100 TC offload
In reply to [email protected]From: Edward Cree <[email protected]>
Support matching on ip_frag and ip_firstfrag.
--- drivers/net/ethernet/sfc/mae.c | 25 +++++++++++++++++++++++++ drivers/net/ethernet/sfc/tc.c | 10 +++++++++- drivers/net/ethernet/sfc/tc.h | 1 + 3 files changed, 35 insertions(+), 1 deletion(-)
drivers/net/ethernet/sfc/mae.c +25 -0
@@ -263,6 +263,18 @@ static int efx_mae_match_check_cap_typ(u8 support, enum mask_type typ) mask_type_name(typ), #_field); \ rc; \ }) +/* Booleans need special handling */ +#define CHECK_BIT (_mcdi, _field) ({ \ + enum mask_type typ = mask->_field ? MASK_ONES : MASK_ZEROES; \ + \ + rc = efx_mae_match_check_cap_typ(supported_fields[MAE_FIELD_ ## _mcdi],\ + typ); \ + if (rc) \ + NL_SET_ERR_MSG_FMT_MOD(extack, \ + "No support for %s mask in field %s", \ + mask_type_name(typ), #_field); \ + rc; \ +}) int efx_mae_match_check_caps(struct efx_nic *efx, const struct efx_tc_match_fields *mask,
@@ -299,10 +311,13 @@ int efx_mae_match_check_caps(struct efx_nic *efx,CHECK (SRC_IP6 , src_ip6) ||CHECK (DST_IP6 , dst_ip6) || #endif +CHECK_BIT (IS_IP_FRAG , ip_frag) || +CHECK_BIT (IP_FIRST_FRAG , ip_firstfrag) || CHECK(RECIRC_ID, recirc_id)) return rc; return 0; } +#undef CHECK_BIT#undef CHECKstatic bool efx_mae_asl_id (u32 id)
@@ -472,6 +487,16 @@ static int efx_mae_populate_match_criteria(MCDI_DECLARE_STRUCT_PTR(match_crit), }MCDI_STRUCT_SET_DWORD (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_INGRESS_MPORT_SELECTOR_MASK , match->mask.ingress_port); +EFX_POPULATE_DWORD_2 (*_MCDI_STRUCT_DWORD (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_FLAGS ), +MAE_FIELD_MASK_VALUE_PAIRS_V2_IS_IP_FRAG , + match->value.ip_frag, +MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_FIRST_FRAG , + match->value.ip_firstfrag); +EFX_POPULATE_DWORD_2 (*_MCDI_STRUCT_DWORD (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_FLAGS_MASK ), +MAE_FIELD_MASK_VALUE_PAIRS_V2_IS_IP_FRAG , + match->mask.ip_frag, +MAE_FIELD_MASK_VALUE_PAIRS_V2_IP_FIRST_FRAG , + match->mask.ip_firstfrag);MCDI_STRUCT_SET_BYTE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_RECIRC_ID , match->value.recirc_id); MCDI_STRUCT_SET_BYTE(match_crit, MAE_FIELD_MASK_VALUE_PAIRS_V2_RECIRC_ID_MASK,
drivers/net/ethernet/sfc/tc.c +9 -1
@@ -168,7 +168,15 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx,break ; } -if (fm.mask->flags) { +if (fm.mask->flags &FLOW_DIS_IS_FRAGMENT ) { + match->value.ip_frag = fm.key->flags &FLOW_DIS_IS_FRAGMENT ; + match->mask.ip_frag = true; + } +if (fm.mask->flags &FLOW_DIS_FIRST_FRAG ) { + match->value.ip_firstfrag = fm.key->flags &FLOW_DIS_FIRST_FRAG ; + match->mask.ip_firstfrag = true; + } +if (fm.mask->flags & ~(FLOW_DIS_IS_FRAGMENT |FLOW_DIS_FIRST_FRAG )) {NL_SET_ERR_MSG_FMT_MOD (extack,"Unsupported match on control.flags %#x" , fm.mask->flags);return -EOPNOTSUPP ;
drivers/net/ethernet/sfc/tc.h +1 -0
@@ -38,6 +38,7 @@ struct efx_tc_match_fields {#ifdef CONFIG_IPV6 struct in6_addr src_ip6, dst_ip6;#endif +bool ip_frag, ip_firstfrag; };struct efx_tc_match {
PATCH v2 5/5 sfc: add Layer 4 matches to ef100 TC offload
In reply to [email protected]From: Edward Cree <[email protected]>
Support matching on UDP/TCP source and destination ports and TCP flags,
with masking if supported by the hardware.
--- drivers/net/ethernet/sfc/mae.c | 15 +++++++++++++++ drivers/net/ethernet/sfc/tc.c | 21 +++++++++++++++++++-- drivers/net/ethernet/sfc/tc.h | 3 +++ 3 files changed, 37 insertions(+), 2 deletions(-)
drivers/net/ethernet/sfc/mae.c +15 -0
@@ -311,6 +311,9 @@ int efx_mae_match_check_caps(struct efx_nic *efx,CHECK (SRC_IP6 , src_ip6) ||CHECK (DST_IP6 , dst_ip6) || #endif +CHECK (L4_SPORT , l4_sport) || +CHECK (L4_DPORT , l4_dport) || +CHECK (TCP_FLAGS , tcp_flags) ||CHECK_BIT (IS_IP_FRAG , ip_frag) ||CHECK_BIT (IP_FIRST_FRAG , ip_firstfrag) || CHECK(RECIRC_ID, recirc_id))
@@ -559,6 +562,18 @@ static int efx_mae_populate_match_criteria(MCDI_DECLARE_STRUCT_PTR(match_crit),memcpy (MCDI_STRUCT_PTR (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_DST_IP6_BE_MASK ), &match->mask.dst_ip6,sizeof (struct in6_addr ));#endif +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_L4_SPORT_BE , + match->value.l4_sport); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_L4_SPORT_BE_MASK , + match->mask.l4_sport); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_L4_DPORT_BE , + match->value.l4_dport); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_L4_DPORT_BE_MASK , + match->mask.l4_dport); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_TCP_FLAGS_BE , + match->value.tcp_flags); +MCDI_STRUCT_SET_WORD_BE (match_crit,MAE_FIELD_MASK_VALUE_PAIRS_V2_TCP_FLAGS_BE_MASK , + match->mask.tcp_flags);return 0 ; }
drivers/net/ethernet/sfc/tc.c +19 -2
@@ -190,6 +190,8 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx, BIT(FLOW_DISSECTOR_KEY_CVLAN) | BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | + BIT(FLOW_DISSECTOR_KEY_PORTS) | + BIT(FLOW_DISSECTOR_KEY_TCP) | BIT(FLOW_DISSECTOR_KEY_IP))) {NL_SET_ERR_MSG_FMT_MOD (extack,"Unsupported flower keys %#x" , dissector->used_keys);
@@ -204,8 +206,10 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx,if (dissector->used_keys & (BIT (FLOW_DISSECTOR_KEY_IPV4_ADDRS ) |BIT (FLOW_DISSECTOR_KEY_IPV6_ADDRS ) | -BIT (FLOW_DISSECTOR_KEY_IP ))) { -NL_SET_ERR_MSG_FMT_MOD (extack,"L3 flower keys %#x require protocol ipv[46]" , +BIT (FLOW_DISSECTOR_KEY_PORTS ) | +BIT (FLOW_DISSECTOR_KEY_IP ) | +BIT (FLOW_DISSECTOR_KEY_TCP ))) { +NL_SET_ERR_MSG_FMT_MOD (extack,"L3/L4 flower keys %#x require protocol ipv[46]" , dissector->used_keys);return -EINVAL ; }
@@ -249,6 +253,16 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx, }MAP_KEY_AND_MASK (BASIC , basic, ip_proto, ip_proto); +/* Make sure we're TCP/UDP if any L4 keys used. */ +if ((match->value.ip_proto !=IPPROTO_UDP && + match->value.ip_proto !=IPPROTO_TCP ) || !IS_ALL_ONES (match->mask.ip_proto)) +if (dissector->used_keys & + (BIT (FLOW_DISSECTOR_KEY_PORTS ) | +BIT (FLOW_DISSECTOR_KEY_TCP ))) { +NL_SET_ERR_MSG_FMT_MOD (extack,"L4 flower keys %#x require ipproto udp or tcp" , + dissector->used_keys); +return -EINVAL ; + }MAP_KEY_AND_MASK (IP , ip, tos, ip_tos);MAP_KEY_AND_MASK (IP , ip, ttl, ip_ttl);if (ipv ==4 ) {
@@ -261,6 +275,9 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx, MAP_KEY_AND_MASK(IPV6_ADDRS, ipv6_addrs, dst, dst_ip6); }#endif +MAP_KEY_AND_MASK (PORTS , ports, src, l4_sport); +MAP_KEY_AND_MASK (PORTS , ports, dst, l4_dport); +MAP_KEY_AND_MASK (TCP , tcp, flags, tcp_flags);return 0 ; }
drivers/net/ethernet/sfc/tc.h +3 -0
@@ -39,6 +39,9 @@ struct efx_tc_match_fields {struct in6_addr src_ip6, dst_ip6;#endif bool ip_frag, ip_firstfrag; +/* L4 */ +__be16 l4_sport, l4_dport;/* Ports (UDP, TCP) */ +__be16 tcp_flags; };struct efx_tc_match {
This series was applied to netdev/net-next.git (master) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net-next.git (master) by Jakub Kicinski <[email protected]>:
Quoted 12 lines · On Thu, 3 Nov 2022 15:27:26 +0000 you wrote:
From: Edward Cree <[email protected]>
Support offloading TC flower rules with matches on L2-L4 fields.
Changed in v2:
* changed CHECK macro to not hide control flow. Annoyingly, gcc complains if we don't use the result of the OR-expression we're using to get short- circuiting behaviour (ensuring we only report the first error), so we have to have an if-statement that's semantically redundant.
* added explanation to patch #1 of why these checks aren't vital for correctness (and thus don't need to have a Fixes tag or go to net).
Quoted 1 line
[...]
Here is the summary with links:
- [v2,net-next,1/5] sfc: check recirc_id match caps before MAE offload
https://git.kernel.org/netdev/net-next/c/f0b59ad11e29 - [v2,net-next,2/5] sfc: add Layer 2 matches to ef100 TC offload https://git.kernel.org/netdev/net-next/c/6d1c604d1098 - [v2,net-next,3/5] sfc: add Layer 3 matches to ef100 TC offload https://git.kernel.org/netdev/net-next/c/c178dff3f92d - [v2,net-next,4/5] sfc: add Layer 3 flag matches to ef100 TC offload https://git.kernel.org/netdev/net-next/c/5ca7ef293866 - [v2,net-next,5/5] sfc: add Layer 4 matches to ef100 TC offload https://git.kernel.org/netdev/net-next/c/5d1d24da00db
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html