RE: [PATCH net-next v2 5/5] bridge: Use ndisc_parse_options() to parse ND options in br_nd_send()

From: Danielle Ratson

Date: Wed Aug 05 2026 - 04:23:04 EST


> -----Original Message-----
> From: Danielle Ratson <danieller@xxxxxxxxxx>
> Sent: Monday, 3 August 2026 14:25
> To: netdev@xxxxxxxxxxxxxxx
> Cc: dsahern@xxxxxxxxxx; Ido Schimmel <idosch@xxxxxxxxxx>;
> davem@xxxxxxxxxxxxx; edumazet@xxxxxxxxxx; kuba@xxxxxxxxxx;
> pabeni@xxxxxxxxxx; horms@xxxxxxxxxx; razor@xxxxxxxxxxxxx; ja@xxxxxx; Petr
> Machata <petrm@xxxxxxxxxx>; fw@xxxxxxxxx; kuniyu@xxxxxxxxxx;
> bridge@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Danielle Ratson
> <danieller@xxxxxxxxxx>
> Subject: [PATCH net-next v2 5/5] bridge: Use ndisc_parse_options() to parse
> ND options in br_nd_send()
>
> Replace the manual ND option parsing loop in br_nd_send() with
> ndisc_parse_options(), which provides proper validation and avoids the class
> of bugs that were fixed by commit 53fc685243bd ("bridge: Avoid infinite loop
> when suppressing NS messages with invalid options") and commit
> 850837965af1 ("bridge: br_nd_send: validate ND option lengths").
>
> Use ndisc_opt_addr_data() to extract the source link-layer address from the
> parsed options, which correctly validates the option length for the underlying
> device type.
>
> Export ndisc_parse_options() so that it can be resolved from the bridge when
> it is built as a module (CONFIG_BRIDGE=m); otherwise modpost fails with an
> undefined symbol.
>
> Reviewed-by: Petr Machata <petrm@xxxxxxxxxx>
> Acked-by: Nikolay Aleksandrov <razor@xxxxxxxxxxxxx>
> Signed-off-by: Danielle Ratson <danieller@xxxxxxxxxx>
> ---

Sashiko wrote:

"
--- Patch [5]: [PATCH net-next v2 5/5] bridge: Use ndisc_parse_options() to parse ND options in br_nd_send() ---
commit a5e722187a4312d62366c8f19772265d9169d89e
Author: Danielle Ratson <danieller@xxxxxxxxxx>
bridge: Use ndisc_parse_options() to parse ND options in br_nd_send()
This commit replaces the manual ND option parsing loop in br_nd_send()
with ndisc_parse_options() to provide proper validation. It also exports
ndisc_parse_options() from the IPv6 module so it can be called from the
bridge subsystem.
> diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c
> --- a/net/bridge/br_arp_nd_proxy.c
> +++ b/net/bridge/br_arp_nd_proxy.c
[ ... ]
> @@ -284,20 +285,21 @@ static void br_nd_send(struct net_bridge *br, struct net_bridge_port *p,
> daddr = eth_hdr(request)->h_source;
> ns = (struct nd_msg *)skb_transport_header(request);
>
> - /* Do we need option processing ? */
> - ns_olen = request->len - (skb_network_offset(request) +
> - sizeof(struct ipv6hdr)) - sizeof(*ns);
> - for (i = 0; i < ns_olen - 1; i += (ns->opt[i + 1] << 3)) {
> - if (!ns->opt[i + 1] || i + (ns->opt[i + 1] << 3) > ns_olen) {
> - kfree_skb(reply);
> - return;
> - }
> - if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) {
> - if ((ns->opt[i + 1] << 3) >=
> - sizeof(struct nd_opt_hdr) + ETH_ALEN)
> - daddr = ns->opt + i + sizeof(struct nd_opt_hdr);
> - break;
> - }
> + /* Derive the option length from the IPv6 payload length so that any
> + * trailing L2 padding in the skb is not parsed as ND options.
> + */
> + ns_olen = ntohs(ipv6_hdr(request)->payload_len) - sizeof(*ns);
> + if (!ndisc_parse_options(dev, ns->opt, ns_olen, &ndopts)) {

Will this cause a link-time build failure when CONFIG_BRIDGE=y and
CONFIG_IPV6=m?
The commit message mentions exporting ndisc_parse_options() allows it to be
resolved when the bridge is built as a module (CONFIG_BRIDGE=m).
However, since ndisc_parse_options() is defined in net/ipv6/ndisc.c, it is
compiled into the ipv6.ko module when CONFIG_IPV6=m. If the bridge subsystem
is built in (CONFIG_BRIDGE=y), vmlinux won't be able to resolve the symbol
at link time.
"

CONFIG_IPV6 is built-in only. It's a bool, not a tristate. So it is not a possible scenario.