Subject: Re: [PATCH net-next v2 4/5] ipv6: mld: encode multicast exponential fields

From: Ido Schimmel <[email-masked]>
Date: Wed, 1 Apr 2026 10:29:15 +0300

On Mon, Mar 30, 2026 at 07:16:10PM +0000, Ujjal Roy wrote:
> In MLD, QQIC and MRC fields are not currently encoded when

s/currently/correctly/

> generating query packets. Since the receiver of the query
> interprets these fields using the MLDv2 floating-point
> decoding logic, any raw interval value that exceeds the
> linear threshold is currently parsed incorrectly as an
> exponential value, leading to an incorrect interval
> calculation.

[...]

> +static inline u16 mldv2_mrc(unsigned long mrd)
> +{
> +	u16 mc_man, mc_exp;
> +
> +	/* RFC3810: MRC < 32768 is literal */
> +	if (mrd < MLD_MRC_MIN_THRESHOLD)
> +		return (u16)mrd;
> +
> +	/* Saturate at max representable (mant = 0xFFF, exp = 7) -> 8387584 */
> +	if (mrd >= MLD_MRC_MAX_THRESHOLD)
> +		return 0xFFFF;
> +
> +	mc_exp = (u16)(fls(mrd) - 16);
> +	mc_man = (u16)((mrd >> (mc_exp + 3)) & 0x0FFF);
> +
> +	return (0x8000 | (mc_exp << 12) | mc_man);
> +}

[...]

> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index 27010744d7ae..c2d144f6a86e 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -1181,7 +1181,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm
>  		break;
>  	case 2:
>  		mld2q = (struct mld2_query *)icmp6_hdr(skb);
> -		mld2q->mld2q_mrc = htons((u16)jiffies_to_msecs(interval));
> +		mld2q->mld2q_mrc = htons((u16)jiffies_to_msecs(mldv2_mrc(interval)));

This looks wrong. mldv2_mrc() is supposed to receive the maximum
response delay in milliseconds, but you are passing jiffies.

>  		mld2q->mld2q_type = ICMPV6_MGM_QUERY;
>  		mld2q->mld2q_code = 0;
>  		mld2q->mld2q_cksum = 0;
> @@ -1190,7 +1190,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm
>  		mld2q->mld2q_suppress = sflag;
>  		mld2q->mld2q_qrv = 2;
>  		mld2q->mld2q_nsrcs = htons(llqt_srcs);
> -		mld2q->mld2q_qqic = brmctx->multicast_query_interval / HZ;
> +		mld2q->mld2q_qqic = mldv2_qqic(brmctx->multicast_query_interval / HZ);
>  		mld2q->mld2q_mca = *group;
>  		csum = &mld2q->mld2q_cksum;
>  		csum_start = (void *)mld2q;
> -- 
> 2.43.0
>