Re: [PATCH 3/4] ipv4: igmp: encode multicast exponential fields

Nikolay Aleksandrov <[email protected]>
Newsgroups gmane.linux.network.bridge
Message-ID <f23ed1b3-6321-4e6d-9cda-ec5d34304f3b__17229.9737738044$1774614212$gmane$org@blackwall.org>
On 26/03/2026 17:07, Ujjal Roy wrote:
> In IGMP, QQIC and MRC fields are not currently encoded
> when generating query packets. Since the receiver of the
> query interprets these fields using the IGMPv3 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.
> 
> Encode and assign the corresponding protocol fields during
> query generation. Introduce the logic to dynamically
> calculate the exponent and mantissa using bit-scan (fls).
> This ensures QQIC and MRC fields (8-bit) are properly
> encoded when transmitting query packets with intervals
> that exceed their respective linear threshold value of
> 128 (for QQI/MRT).
> 
> RFC 3376: if QQIC/MRC >= 128, the QQIC/MRC field represents
> a floating-point value as follows:
>       0 1 2 3 4 5 6 7
>      +-+-+-+-+-+-+-+-+
>      |1| exp | mant  |
>      +-+-+-+-+-+-+-+-+
> 
> Signed-off-by: Ujjal Roy <[email protected]>
> ---
>   include/linux/igmp.h      | 80 +++++++++++++++++++++++++++++++++++++++
>   net/bridge/br_multicast.c | 14 +++----
>   2 files changed, 86 insertions(+), 8 deletions(-)
> 
[snip]
> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index 1438c023db62..1de6242413e0 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -939,7 +939,7 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brm
>   	struct sk_buff *skb;
>   	struct igmphdr *ih;
>   	struct ethhdr *eth;
> -	unsigned long lmqt;
> +	unsigned long lmqt, mrt;
>   	struct iphdr *iph;
>   	u16 lmqt_srcs = 0;

please keep reverse xmas tree order

>   
> @@ -1004,15 +1004,15 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brm
>   	skb_put(skb, 24);
>   
>   	skb_set_transport_header(skb, skb->len);
> +	mrt = group ? brmctx->multicast_last_member_interval :
> +		      brmctx->multicast_query_response_interval;
>   	*igmp_type = IGMP_HOST_MEMBERSHIP_QUERY;
>   
>   	switch (brmctx->multicast_igmp_version) {
>   	case 2:
>   		ih = igmp_hdr(skb);
>   		ih->type = IGMP_HOST_MEMBERSHIP_QUERY;
> -		ih->code = (group ? brmctx->multicast_last_member_interval :
> -				    brmctx->multicast_query_response_interval) /
> -			   (HZ / IGMP_TIMER_SCALE);
> +		ih->code = mrt / (HZ / IGMP_TIMER_SCALE);
>   		ih->group = group;
>   		ih->csum = 0;
>   		csum = &ih->csum;
> @@ -1021,11 +1021,9 @@ static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brm
>   	case 3:
>   		ihv3 = igmpv3_query_hdr(skb);
>   		ihv3->type = IGMP_HOST_MEMBERSHIP_QUERY;
> -		ihv3->code = (group ? brmctx->multicast_last_member_interval :
> -				      brmctx->multicast_query_response_interval) /
> -			     (HZ / IGMP_TIMER_SCALE);
> +		ihv3->code = igmpv3_mrc(mrt / (HZ / IGMP_TIMER_SCALE));
>   		ihv3->group = group;
> -		ihv3->qqic = brmctx->multicast_query_interval / HZ;
> +		ihv3->qqic = igmpv3_qqic(brmctx->multicast_query_interval / HZ);
>   		ihv3->nsrcs = htons(lmqt_srcs);
>   		ihv3->resv = 0;
>   		ihv3->suppress = sflag;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.