summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-04-18 11:40:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-04-18 11:40:54 -0700
commit7586c8501d090609c6eb1af6ba05e3ed68806c83 (patch)
tree2877f311f9be4bd2f70e16c34e632c96a25a1977 /drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
parent360a348fd7fe72ec42a80d025e6fc81cda19f48e (diff)
parentc24cd679b075b0e953ea167b0aa2b2d59e4eba7f (diff)
downloadlinux-stable-7586c8501d090609c6eb1af6ba05e3ed68806c83.tar.gz
linux-stable-7586c8501d090609c6eb1af6ba05e3ed68806c83.tar.bz2
linux-stable-7586c8501d090609c6eb1af6ba05e3ed68806c83.zip
Merge tag 'net-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski: "A little calmer than usual, probably just the timing of sub-tree PRs. Including fixes from netfilter. Current release - regressions: - inet: bring NLM_DONE out to a separate recv() again, fix user space which assumes multiple recv()s will happen and gets blocked forever - drv: mlx5: - restore mistakenly dropped parts in register devlink flow - use channel mdev reference instead of global mdev instance for coalescing - acquire RTNL lock before RQs/SQs activation/deactivation Previous releases - regressions: - net: change maximum number of UDP segments to 128, fix virtio compatibility with Windows peers - usb: ax88179_178a: avoid writing the mac address before first reading Previous releases - always broken: - sched: fix mirred deadlock on device recursion - netfilter: - br_netfilter: skip conntrack input hook for promisc packets - fixes removal of duplicate elements in the pipapo set backend - various fixes for abort paths and error handling - af_unix: don't peek OOB data without MSG_OOB - drv: flower: fix fragment flags handling in multiple drivers - drv: ravb: fix jumbo frames and packet stats accounting Misc: - kselftest_harness: fix Clang warning about zero-length format - tun: limit printing rate when illegal packet received by tun dev" * tag 'net-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (46 commits) net: ethernet: ti: am65-cpsw-nuss: cleanup DMA Channels before using them net: usb: ax88179_178a: avoid writing the mac address before first reading net: ravb: Fix RX byte accounting for jumbo packets net: ravb: Fix GbEth jumbo packet RX checksum handling net: ravb: Allow RX loop to move past DMA mapping errors net: ravb: Count packets instead of descriptors in R-Car RX path net: ethernet: mtk_eth_soc: fix WED + wifi reset net:usb:qmi_wwan: support Rolling modules selftests: kselftest_harness: fix Clang warning about zero-length format net/sched: Fix mirred deadlock on device recursion netfilter: nf_tables: fix memleak in map from abort path netfilter: nf_tables: restore set elements when delete set fails netfilter: nf_tables: missing iterator type in lookup walk s390/ism: Properly fix receive message buffer allocation net: dsa: mt7530: fix port mirroring for MT7988 SoC switch net: dsa: mt7530: fix mirroring frames received on local port tun: limit printing rate when illegal packet received by tun dev ice: Fix checking for unsupported keys on non-tunnel device ice: tc: allow zero flags in parsing tc flower ice: tc: check src_vsi in case of traffic from VF ...
Diffstat (limited to 'drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c')
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
index 523e0c470894..55f255a3c9db 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
@@ -36,6 +36,27 @@ struct sparx5_tc_flower_template {
u16 l3_proto; /* protocol specified in the template */
};
+/* SparX-5 VCAP fragment types:
+ * 0 = no fragment, 1 = initial fragment,
+ * 2 = suspicious fragment, 3 = valid follow-up fragment
+ */
+enum { /* key / mask */
+ FRAG_NOT = 0x03, /* 0 / 3 */
+ FRAG_SOME = 0x11, /* 1 / 1 */
+ FRAG_FIRST = 0x13, /* 1 / 3 */
+ FRAG_LATER = 0x33, /* 3 / 3 */
+ FRAG_INVAL = 0xff, /* invalid */
+};
+
+/* Flower fragment flag to VCAP fragment type mapping */
+static const u8 sparx5_vcap_frag_map[4][4] = { /* is_frag */
+ { FRAG_INVAL, FRAG_INVAL, FRAG_INVAL, FRAG_FIRST }, /* 0/0 */
+ { FRAG_NOT, FRAG_NOT, FRAG_INVAL, FRAG_INVAL }, /* 0/1 */
+ { FRAG_INVAL, FRAG_INVAL, FRAG_INVAL, FRAG_INVAL }, /* 1/0 */
+ { FRAG_SOME, FRAG_LATER, FRAG_INVAL, FRAG_FIRST } /* 1/1 */
+ /* 0/0 0/1 1/0 1/1 <-- first_frag */
+};
+
static int
sparx5_tc_flower_es0_tpid(struct vcap_tc_flower_parse_usage *st)
{
@@ -145,29 +166,27 @@ sparx5_tc_flower_handler_control_usage(struct vcap_tc_flower_parse_usage *st)
flow_rule_match_control(st->frule, &mt);
if (mt.mask->flags) {
- if (mt.mask->flags & FLOW_DIS_FIRST_FRAG) {
- if (mt.key->flags & FLOW_DIS_FIRST_FRAG) {
- value = 1; /* initial fragment */
- mask = 0x3;
- } else {
- if (mt.mask->flags & FLOW_DIS_IS_FRAGMENT) {
- value = 3; /* follow up fragment */
- mask = 0x3;
- } else {
- value = 0; /* no fragment */
- mask = 0x3;
- }
- }
- } else {
- if (mt.mask->flags & FLOW_DIS_IS_FRAGMENT) {
- value = 3; /* follow up fragment */
- mask = 0x3;
- } else {
- value = 0; /* no fragment */
- mask = 0x3;
- }
+ u8 is_frag_key = !!(mt.key->flags & FLOW_DIS_IS_FRAGMENT);
+ u8 is_frag_mask = !!(mt.mask->flags & FLOW_DIS_IS_FRAGMENT);
+ u8 is_frag_idx = (is_frag_key << 1) | is_frag_mask;
+
+ u8 first_frag_key = !!(mt.key->flags & FLOW_DIS_FIRST_FRAG);
+ u8 first_frag_mask = !!(mt.mask->flags & FLOW_DIS_FIRST_FRAG);
+ u8 first_frag_idx = (first_frag_key << 1) | first_frag_mask;
+
+ /* Lookup verdict based on the 2 + 2 input bits */
+ u8 vdt = sparx5_vcap_frag_map[is_frag_idx][first_frag_idx];
+
+ if (vdt == FRAG_INVAL) {
+ NL_SET_ERR_MSG_MOD(st->fco->common.extack,
+ "Match on invalid fragment flag combination");
+ return -EINVAL;
}
+ /* Extract VCAP fragment key and mask from verdict */
+ value = (vdt >> 4) & 0x3;
+ mask = vdt & 0x3;
+
err = vcap_rule_add_key_u32(st->vrule,
VCAP_KF_L3_FRAGMENT_TYPE,
value, mask);