Netdev List
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: luizluca@gmail.com
Cc: Jakub Kicinski <kuba@kernel.org>,
	andrew@lunn.ch, olteanv@gmail.com, davem@davemloft.net,
	edumazet@google.com, pabeni@redhat.com, horms@kernel.org,
	linusw@kernel.org, alsi@bang-olufsen.dk, yury.norov@gmail.com,
	linux@rasmusvillemoes.dk, linux@armlinux.org.uk,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [net-next PATCH v3 7/8] net: dsa: realtek: rtl8365mb: add FDB support
Date: Sun, 10 May 2026 10:35:16 -0700	[thread overview]
Message-ID: <20260510173516.3920093-1-kuba@kernel.org> (raw)
In-Reply-To: <20260506-realtek_forward-v3-7-1d87c5f85a3b@gmail.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net: dsa: realtek: rtl8365mb: add FDB support

Implement support for FDB and MDB management for the RTL8365MB series
switches. Introduce a mutex lock (l2_lock) to protect concurrent L2 table
updates. Add support for forwarding database operations, including unicast
and multicast entry handling as well as fast aging support.

> diff --git a/drivers/net/dsa/realtek/rtl8365mb_l2.c b/drivers/net/dsa/realtek/rtl8365mb_l2.c
> --- /dev/null
> +++ b/drivers/net/dsa/realtek/rtl8365mb_l2.c

[ ... ]

> +static void rtl8365mb_l2_data_to_uc(const u16 *data, struct rtl8365mb_l2_uc *uc)
> +{

[ ... ]

> +	uc->key.efid = FIELD_GET(RTL8365MB_L2_UC_D4_EFID_MASK, data[4]);
> +	uc->key.vid = FIELD_GET(RTL8365MB_L2_UC_D3_VID_MASK, data[3]);
> +	uc->key.ivl = FIELD_GET(RTL8365MB_L2_UC_D3_IVL_MASK, data[3]);
> +	uc->key.fid = FIELD_GET(RTL8365MB_L2_UC_D4_FID_MASK, data[4]);

Because vid and fid share the same union memory in struct rtl8365mb_l2_uc_key,
does setting fid immediately after vid overwrite the 12-bit vid value with
the 4-bit fid value?

When rtl83xx_port_fdb_dump() later passes entry.vid to the DSA core, it
appears this sends the corrupted fid value instead, breaking VLAN visibility
in userspace tools like bridge fdb show.

[ ... ]

> +static void rtl8365mb_l2_data_to_mc(const u16 *data, struct rtl8365mb_l2_mc *mc)
> +{

[ ... ]

> +	mc->is_static = FIELD_GET(RTL8365MB_L2_MC_STATIC_MASK, data[5]);
> +	mc->member = FIELD_GET(RTL8365MB_L2_MC_MBR_MASK, data[4]) |
> +		     (FIELD_GET(RTL8365MB_L2_MC_MBR_EXT1_MASK, data[3]) << 8) |
> +		     (FIELD_GET(RTL8365MB_L2_MC_MBR_EXT2_MASK, data[5]) << 8);

Could this shift for MBR_EXT2_MASK be incorrect? 

It seems this shifts MBR_EXT2_MASK by 8 instead of 10. This causes the
extended bit for port 10 to collide with the EXT1 bits (which are correctly
shifted by 8) and leaves bit 10 perpetually unset.

In rtl8365mb_l2_mc_to_data(), the shift used is 10:

data[5] |= FIELD_PREP(RTL8365MB_L2_MC_MBR_EXT2_MASK, mc->member >> 10);

When the driver performs a read-modify-write operation on an existing
multicast entry, this shift mismatch might cause port 10 to be silently
dropped and port 8 to be erroneously altered.

[ ... ]

> +int rtl8365mb_l2_add_mc(struct realtek_priv *priv, int port,
> +			const unsigned char mac_addr[static ETH_ALEN],
> +			u16 vid)
> +{

[ ... ]

> +	mc.member |= BIT(port);
> +	mc.is_static = 1;
> +	rtl8365mb_l2_mc_to_data(&mc, data);
> +
> +	/* First look for an existing entry (to get existing port members) */
> +	ret = rtl8365mb_table_query(priv, RTL8365MB_TABLE_L2,
> +				    RTL8365MB_TABLE_OP_READ, &addr,
> +				    RTL8365MB_TABLE_L2_METHOD_MAC, 0,
> +				    data, RTL8365MB_L2_ENTRY_SIZE);
> +	if (!ret) {
> +		/* There is already an entry... */
> +		rtl8365mb_l2_data_to_mc(data, &mc);
> +		/* the port must be added as a member */
> +		mc.member |= BIT(port);
> +		rtl8365mb_l2_mc_to_data(&mc, data);

If an entry already exists in hardware, rtl8365mb_l2_data_to_mc() overwrites
the mc struct with the hardware state. If the existing hardware entry was 
dynamically learned (e.g., via IGMP snooping), is_static is overwritten to 0.

Would this cause the software-requested static MDB entry to be subject to 
hardware aging?

> diff --git a/drivers/net/dsa/realtek/rtl83xx.c b/drivers/net/dsa/realtek/rtl83xx.c
> --- a/drivers/net/dsa/realtek/rtl83xx.c
> +++ b/drivers/net/dsa/realtek/rtl83xx.c

[ ... ]

> +int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port,
> +			  dsa_fdb_dump_cb_t *cb, void *data)
> +{

[ ... ]

> +	mutex_lock(&priv->l2_lock);
> +	while (true) {
> +		start_addr = addr;
> +
> +		dev_dbg(priv->dev, "l2_get_next_uc, addr:%d, port:%d\n",
> +			addr, port);
> +		ret = priv->ops->l2_get_next_uc(priv, &addr, port, &entry);
> +		dev_dbg(priv->dev,
> +			"l2_get_next_uc addr:%d mac:%pM vid:%d static:%d ret:%pe\n",
> +			addr, entry.mac_addr, entry.vid, entry.is_static,
> +			ERR_PTR(ret));
> +
> +		if (ret == -ENOENT)
> +			break;
> +		if (ret)
> +			break;
> +
> +		if (addr < start_addr)
> +			break;
> +
> +		cb(entry.mac_addr, entry.vid, entry.is_static, data);

If the netlink socket buffer fills up, the callback returns -EMSGSIZE.
Since the return value of cb() is ignored here, does the loop fail to abort
and continue iterating the hardware table?

This would result in the netlink subsystem receiving an incorrect success
(or -ENOENT) instead of -EMSGSIZE, preventing it from resuming the dump later
and silently truncating FDB lists.

> +
> +		addr++;
> +
> +		/* Avoid querying beyond the valid L2 table range. */
> +		if (addr > l2_table_size)
> +			break;
> +	}
> +	mutex_unlock(&priv->l2_lock);
> +
> +	return ret;

When l2_get_next_uc() reaches the end of the hardware table, it returns
-ENOENT. 

Because ret is not reset to 0, this returns -ENOENT to the DSA core upon
successful completion. Should this return 0 on success to adhere to the
expected API contract?

  parent reply	other threads:[~2026-05-10 17:35 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-07  2:58 [net-next PATCH v3 0/8] net: dsa: realtek: rtl8365mb: bridge offloading and VLAN support Luiz Angelo Daros de Luca
2026-05-07  2:58 ` [net-next PATCH v3 1/8] net: dsa: realtek: rtl8365mb: use ERR_PTR Luiz Angelo Daros de Luca
2026-05-10 15:23   ` Mieczyslaw Nalewaj
2026-05-07  2:58 ` [net-next PATCH v3 2/8] net: dsa: realtek: rtl8365mb: use dsa helpers for port iteration Luiz Angelo Daros de Luca
2026-05-10 15:23   ` Mieczyslaw Nalewaj
2026-05-10 17:34   ` Jakub Kicinski
2026-05-10 17:35   ` Jakub Kicinski
2026-05-07  2:58 ` [net-next PATCH v3 3/8] net: dsa: realtek: rtl8365mb: prepare for multiple source files Luiz Angelo Daros de Luca
2026-05-10 15:23   ` Mieczyslaw Nalewaj
2026-05-07  2:58 ` [net-next PATCH v3 4/8] net: dsa: realtek: rtl8365mb: add table lookup interface Luiz Angelo Daros de Luca
2026-05-10 15:24   ` Mieczyslaw Nalewaj
2026-05-10 17:34   ` Jakub Kicinski
2026-05-07  2:58 ` [net-next PATCH v3 5/8] net: dsa: realtek: rtl8365mb: add VLAN support Luiz Angelo Daros de Luca
2026-05-10 15:24   ` Mieczyslaw Nalewaj
2026-05-10 17:34   ` Jakub Kicinski
2026-05-10 17:35   ` Jakub Kicinski
2026-05-07  2:58 ` [net-next PATCH v3 6/8] net: dsa: realtek: rtl8365mb: add port_bridge_{join,leave} Luiz Angelo Daros de Luca
2026-05-10 15:25   ` Mieczyslaw Nalewaj
2026-05-10 17:34   ` Jakub Kicinski
2026-05-10 17:35   ` Jakub Kicinski
2026-05-07  2:58 ` [net-next PATCH v3 7/8] net: dsa: realtek: rtl8365mb: add FDB support Luiz Angelo Daros de Luca
2026-05-10 15:25   ` Mieczyslaw Nalewaj
2026-05-10 17:34   ` Jakub Kicinski
2026-05-10 17:35   ` Jakub Kicinski [this message]
2026-05-11 15:00     ` Mieczyslaw Nalewaj
2026-05-07  2:58 ` [net-next PATCH v3 8/8] net: dsa: realtek: rtl8365mb: add bridge port flags Luiz Angelo Daros de Luca
2026-05-10 15:26   ` Mieczyslaw Nalewaj
2026-05-10 17:34   ` Jakub Kicinski
2026-05-10 17:34 ` [net-next PATCH v3 0/8] net: dsa: realtek: rtl8365mb: bridge offloading and VLAN support Jakub Kicinski
2026-05-11  4:58   ` Luiz Angelo Daros de Luca
2026-05-11  9:31     ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260510173516.3920093-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=alsi@bang-olufsen.dk \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=linusw@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=linux@rasmusvillemoes.dk \
    --cc=luizluca@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=yury.norov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox