Thread (1 message) flat view 1 message, 1 author, 2d ago
HOTtoday

[PATCH AUTOSEL 6.18-6.12] net: hns3: improve the unused_tuple parameter setting

From: Sasha Levin <sashal@kernel.org>
Date: 2026-08-31 13:40:02
Also in: linux-patches, lkml, stable
Subsystem: hisilicon network subsystem 3 driver (hns3), hisilicon network subsystem driver, networking drivers, the rest · Maintainers: Jian Shen, Jijie Shao, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

From: Jijie Shao <shaojijie@huawei.com>

[ Upstream commit 1ad6f1ff3e96c7ee888475740c8acdaf822e0813 ]

Currently, when the tc tool is used to set flow table rules, the IP address
and MAC address can be configured separately, for example, src_xx or dst_xx
can be configured separately.

Therefore, the driver needs to check whether the mask is all zero in
keys, such as FLOW_DISSECTOR_KEY_IPV4_ADDRS, FLOW_DISSECTOR_KEY_IPV6_ADDRS,
and FLOW_DISSECTOR_KEY_ETH_ADDRS.
If the mask is all zero, the tuple is not configured.
In this case, the driver adds the tuple to unused_tuple.

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
Link: https://patch.msgid.link/20260610060618.834987-3-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit Message Forensics

**Step 1.1 — Subject line**
Record: `[net: hns3]` `[improve]` — improve `unused_tuple` handling when
parsing tc flower match keys for MAC and IP addresses.

**Step 1.2 — Tags**
Record:
- **Signed-off-by:** Jijie Shao `[off-list ref]` (author)
- **Link:**
  https://patch.msgid.link/20260610060618.834987-3-shaojijie@huawei.com
- **Signed-off-by:** Jakub Kicinski `[off-list ref]` (netdev
  maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
  by:`, or `Cc: stable@vger.kernel.org`

Notable: maintainer merge (`kuba@kernel.org`), but no fuzzer or user bug
report tags.

**Step 1.3 — Body analysis**
Record:
- **Bug:** When `tc` installs flower rules with only `src_*` or only
  `dst_*` for IP/MAC, the dissector key (`FLOW_DISSECTOR_KEY_ETH_ADDRS`,
  `FLOW_DISSECTOR_KEY_IPV4_ADDRS`, `FLOW_DISSECTOR_KEY_IPV6_ADDRS`) can
  be present while one side’s mask is all-zero.
- **Symptom:** Driver fails to mark that tuple as unused; hardware flow-
  director rules are programmed incorrectly instead of treating the
  field as a wildcard.
- **Root cause:** `hclge_get_cls_key_mac()` / `hclge_get_cls_key_ip()`
  only set `unused_tuple` when the entire key is absent, not when an
  individual mask is zero.

**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Subject says “improve,” but this is a correctness fix
for tc flower hardware offload, not a cosmetic cleanup.

---

## Phase 2: Diff Analysis

**Step 2.1 — Inventory**
Record:
- **Files:** `drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c`
  (+12 lines)
- **Functions:** `hclge_get_cls_key_mac()`, `hclge_get_cls_key_ip()`
- **Scope:** Single-file, surgical driver fix

**Step 2.2 — Code flow change**
Record:
- **MAC hunk:** After copying eth addr keys/masks, if `match.mask->dst`
  or `match.mask->src` is all-zero, set `INNER_DST_MAC` /
  `INNER_SRC_MAC` in `unused_tuple`.
- **IPv4 hunk:** If `match.mask->src` or `match.mask->dst` is zero, set
  corresponding `INNER_SRC_IP` / `INNER_DST_IP`.
- **IPv6 hunk:** If `ipv6_addr_any(&match.mask->src/dst)`, set
  corresponding IP unused bits.
- **Before:** Only the `else` branch (key fully absent) marked tuples
  unused.
- **After:** Per-field zero masks are also treated as unused, matching
  ethtool-path behavior elsewhere in the same file.

**Step 2.3 — Bug mechanism**
Record: **Logic / correctness fix.** Category: incorrect hardware tuple
programming.

When `unused_tuple` is **not** set, `hclge_fd_convert_tuple()` programs
hardware using:

```862:863:drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
#define calc_x(x, k, v) ((x) = ~(k) & (v))
#define calc_y(y, k, v) ((y) = (k) & (v))
With mask `k = 0`, this yields `X = key`, `Y = 0`  not wildcard
behavior. When `unused_tuple` **is** set, `hclge_fd_convert_tuple()`
skips programming that tuple (wildcard). The ethtool path already does
zero-mask checks (e.g. `hclge_fd_check_ether_tuple()`); the tc flower
path did not.

**Step 2.4  Fix quality**
Record: Obviously correct, minimal, mirrors existing driver logic. Low
regression risk. Does not fix the same gap in `hclge_get_cls_key_port()`
(ports), but that is a separate pre-existing issue.

---

## Phase 3: Git History Investigation

**Step 3.1  Blame**
Record: `hclge_get_cls_key_mac()` introduced in `0205ec041ec61` (net:
hns3: add support for hw tc offload of tc flower, Dec 2020).
`hclge_get_cls_key_ip()` mostly from same commit; signature extended in
`e199a5b29f199` (2024).

**Step 3.2  Fixes: tag**
Record: N/A  no `Fixes:` tag.

**Step 3.3  Related file history**
Record: Commit `1ad6f1ff3e96c` is patch 2/6 of enhance tc flow offload
support on master. Other series commits add actions, dissectors,
debugfs, and file split  not required for this 12-line fix. Standalone.

**Step 3.4  Author context**
Record: Jijie Shao is an active hns3 contributor (FD/TC-related commits
in this tree).

**Step 3.5  Dependencies**
Record: None. Functions and structures exist unchanged in 6.18.y.
Cherry-pick to current HEAD applies cleanly (auto-merge, exit 0).

---

## Phase 4: Mailing List and External Research

**Step 4.1  Original discussion**
Record: `b4 dig -c 1ad6f1ff3e96c` 
https://patch.msgid.link/20260610060618.834987-3-shaojijie@huawei.com
Series: V4 net-next 2/6. Revisions v1v4 found via `b4 dig -a`. Lore
direct fetch blocked by bot protection; thread retrieved via `b4 dig
-m`.

**Step 4.2  Reviewers**
Record: `b4 dig -w` CCd `davem@davemloft.net`, `kuba@kernel.org`,
`pabeni@redhat.com`, `netdev@vger.kernel.org`, Huawei maintainers. No
explicit stable nomination found in mbox grep.

**Step 4.3  Bug report**
Record: No external bug report, syzbot, or user `Reported-by:`.

**Step 4.4  Series context**
Record: Part of 6-patch enhancement series, but this patch only fixes
existing cls-flower parsing; does not depend on new actions/dissectors
from patches 36.

**Step 4.5  Stable list**
Record: Not searched on lore stable (no stable nomination found in
retrieved mbox). UNVERIFIED whether stable@ discussed this separately.

---

## Phase 5: Code Semantic Analysis

**Step 5.1  Key functions**
Record: `hclge_get_cls_key_mac()`, `hclge_get_cls_key_ip()`, called from
`hclge_parse_cls_flower()`.

**Step 5.2  Callers**
Record: `hclge_parse_cls_flower()`  `hclge_add_cls_flower()` 
`add_cls_flower` in `hnae3` ops  `hns3_nic_setup_tc()`
(`ndo_setup_tc`). Reachable from userspace via `tc` flower rules on HNS3
NICs.

**Step 5.3  Callees**
Record: `flow_rule_match_*`, `ether_addr_copy`, `ipv6_addr_be32_to_cpu`,
`unused_tuple |= BIT(...)`.

**Step 5.4  Reachability**
Record: Userspace-triggered via `tc filter add ... flower ...` on
HiSilicon HNS3 hardware with flow-director/tc-flower offload enabled
(`CONFIG_HNS3`).

**Step 5.5  Similar patterns**
Record: Ethtool FD path in same file already checks zero masks
(`hclge_fd_check_tcpip4_tuple()`, `hclge_fd_check_ether_tuple()`, etc.).
tc flower path was inconsistent.

---

## Phase 6: Cross-Reference Against Local Tree (6.18.y)

**Step 6.1  Buggy code present?**
Record: **Yes.** Local tree is **v6.18.44** (`git describe HEAD`).
`hclge_get_cls_key_mac()` and `hclge_get_cls_key_ip()` lack zero-mask
checks. Commit `1ad6f1ff3e96c` is **not** an ancestor of HEAD (`NOT IN
TREE`). Bug present since tc flower support landed (2020).

**Step 6.2  Backport complications**
Record: Clean cherry-pick (auto-merge, no conflicts). Expected apply:
**clean**.

**Step 6.3  Related fixes already present?**
Record: No equivalent fix found in 6.18.y history for this specific
issue.

---

## Phase 7: Subsystem Context

**Step 7.1  Subsystem / criticality**
Record: `drivers/net/ethernet/hisilicon/hns3`  **IMPORTANT**
(server/cloud NIC driver, tc offload data path).

**Step 7.2  Activity**
Record: Actively maintained; recent TC/FD fixes in this file (e.g.
`d7beeb64be5ca`, `6b36e5c4741f1`).

---

## Phase 8: Impact and Risk Assessment

**Step 8.1  Who is affected**
Record: Users of HiSilicon HNS3 NICs with hardware tc flower offload,
configuring rules with partial src/dst IP or MAC matching.

**Step 8.2  Trigger conditions**
Record: Common  `tc flower` rules matching only source or only
destination IP/MAC. Unprivileged users can install tc rules (with
appropriate capabilities/namespace policy).

**Step 8.3  Failure mode / severity**
Record: Incorrect hardware packet classification / queue steering; rules
may not match intended traffic or may match too narrowly. **Severity:
MEDIUM**  functional data-path bug, not kernel crash, deadlock, or
memory corruption.

**Step 8.4  Risk vs benefit**
Record:
- **Benefit:** MEDIUM  fixes real mis-steering for standard tc usage on
  production NICs
- **Risk:** LOW  12 lines, mirrors proven ethtool logic
- **Ratio:** Favorable for stable

---

## Phase 9: Final Synthesis

**Evidence FOR backport:**
- Real, verifiable logic bug in tc flower offload path
- Bug present in 6.18.y since 2020
- Small, self-contained, applies cleanly
- Aligns tc path with existing ethtool FD logic in same driver
- Userspace-reachable via `tc` on widely deployed server NICs
- Maintainer-reviewed and merged

**Evidence AGAINST backport:**
- No crash, security, or corruption angle
- No user/fuzzer bug report
- Part of larger net-next enhancement series (though patch itself is
  independent)
- Port matching has same class of bug but is not addressed here

**Stable rules checklist:**
1. Obviously correct and tested? **PASS**  logic mirrors existing
   driver patterns; no `Tested-by:` but change is straightforward
2. Fixes a real bug affecting users? **PASS**  incorrect HW filtering
   for partial tc flower matches
3. Important issue? **PASS (borderline)**  incorrect packet steering on
   production networking path; not crash-level but user-visible and
   operationally significant
4. Small and contained? **PASS**  12 lines, 1 file
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS**  verified clean cherry-pick

**Exception category:** None (not quirk/ID/DT/docs/build).

---

## Problem Summary

This commit fixes a long-standing inconsistency in the HNS3 drivers tc
flower offload path. When users install `tc flower` rules specifying
only source or only destination IP/MAC addresses, the flow dissector
includes the address key with a zero mask for the unspecified side. The
driver must mark those tuples as unused so hardware treats them as
wildcards. Without this fix, `unused_tuple` is not set, hardware is
programmed with zero-mask tuple values, and flow-director rules behave
incorrectly.

For **Linux 6.18.y**, the buggy code is present, the fix is absent, the
patch applies cleanly, and it is standalone. This is appropriate stable
material: a small, low-risk driver correctness fix for a userspace-
visible data-path bug.

---

## Verification

- [Phase 1] Parsed commit message and tags from provided diff and `git
  show 1ad6f1ff3e96c`
- [Phase 2] Analyzed diff: +12 lines in `hclge_get_cls_key_mac()` and
  `hclge_get_cls_key_ip()`
- [Phase 2] Verified `calc_x`/`calc_y` macros and
  `hclge_fd_convert_tuple()` skip logic
- [Phase 2] Verified ethtool path already has zero-mask checks
  (`hclge_fd_check_ether_tuple()` etc.)
- [Phase 3] `git blame`: buggy code from `0205ec041ec61` (2020)
- [Phase 3] `git merge-base --is-ancestor 1ad6f1ff3e96c HEAD`  NOT IN
  TREE
- [Phase 3] Cherry-pick test: `git cherry-pick --no-commit
  1ad6f1ff3e96c`  exit 0, auto-merge
- [Phase 4] `b4 dig -c 1ad6f1ff3e96c`  lore URL found
- [Phase 4] `b4 dig -a`  v1v4 series revisions
- [Phase 4] `b4 dig -w`  netdev maintainers CCd
- [Phase 4] `b4 dig -m`  cover letter retrieved; patch 2/6 context
  confirmed
- [Phase 5] Traced call chain: `hns3_nic_setup_tc` 
  `hclge_add_cls_flower`  `hclge_parse_cls_flower`
- [Phase 6] `git describe HEAD`  v6.18.44; Makefile 6.18.44
- [Phase 6] Read current `hclge_main.c`  buggy code confirmed present
  (no zero-mask checks in MAC/IP cls helpers)
- [Phase 8] Assessed severity as MEDIUM functional data-path bug
- UNVERIFIED: No direct lore stable-list discussion
- UNVERIFIED: No runtime test evidence beyond maintainer merge

**YES****Task result:** The branch search found commit `1ad6f1ff3e96c`
on `master`  it matches the patch under review and is not in the local
6.18.44 tree.

**Verdict (unchanged):** Backport **YES**. Small, standalone fix for
incorrect tc flower hardware filtering when only src or dst IP/MAC is
specified; applies cleanly to 6.18.y.

 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c  | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 7f174453928c1..08f7bda4ef4c4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -7261,6 +7261,10 @@ static void hclge_get_cls_key_mac(const struct flow_rule *flow,
 		ether_addr_copy(rule->tuples_mask.dst_mac, match.mask->dst);
 		ether_addr_copy(rule->tuples.src_mac, match.key->src);
 		ether_addr_copy(rule->tuples_mask.src_mac, match.mask->src);
+		if (is_zero_ether_addr(match.mask->dst))
+			rule->unused_tuple |= BIT(INNER_DST_MAC);
+		if (is_zero_ether_addr(match.mask->src))
+			rule->unused_tuple |= BIT(INNER_SRC_MAC);
 	} else {
 		rule->unused_tuple |= BIT(INNER_DST_MAC);
 		rule->unused_tuple |= BIT(INNER_SRC_MAC);
@@ -7309,6 +7313,10 @@ static int hclge_get_cls_key_ip(const struct flow_rule *flow,
 		rule->tuples.dst_ip[IPV4_INDEX] = be32_to_cpu(match.key->dst);
 		rule->tuples_mask.dst_ip[IPV4_INDEX] =
 						be32_to_cpu(match.mask->dst);
+		if (!match.mask->src)
+			rule->unused_tuple |= BIT(INNER_SRC_IP);
+		if (!match.mask->dst)
+			rule->unused_tuple |= BIT(INNER_DST_IP);
 	} else if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
 		struct flow_match_ipv6_addrs match;
 
@@ -7321,6 +7329,10 @@ static int hclge_get_cls_key_ip(const struct flow_rule *flow,
 				      match.key->dst.s6_addr32);
 		ipv6_addr_be32_to_cpu(rule->tuples_mask.dst_ip,
 				      match.mask->dst.s6_addr32);
+		if (ipv6_addr_any(&match.mask->src))
+			rule->unused_tuple |= BIT(INNER_SRC_IP);
+		if (ipv6_addr_any(&match.mask->dst))
+			rule->unused_tuple |= BIT(INNER_DST_IP);
 	} else {
 		rule->unused_tuple |= BIT(INNER_SRC_IP);
 		rule->unused_tuple |= BIT(INNER_DST_IP);
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help