net/igmp: fix checksum validation that always dropped valid IGMP packets - #19720
Merged
xiaoxiang781216 merged 1 commit intoAug 7, 2026
Merged
Conversation
zhekunren
requested review from
jerpelea,
xiaoxiang781216 and
yamt
as code owners
August 6, 2026 13:36
xiaoxiang781216
approved these changes
Aug 6, 2026
acassis
approved these changes
Aug 6, 2026
acassis
left a comment
Contributor
There was a problem hiding this comment.
@zhekunren if you used AI to help you (based on long messages in the commit message), please include: Assisted-by: the name of AI
igmp_input() validated the IGMP checksum with: if (net_chksum((FAR uint16_t *)igmp, IGMP_HDRLEN) != 0) but net_chksum() returns the raw one's complement sum of the 16-bit words (it does NOT take the one's complement of that sum). For a valid IGMP packet whose checksum field holds ~S (as written by igmp_send()), the sum of all 16-bit words is S + ~S = 0xffff, never 0. So the existing check `!= 0` was always true for any well-formed IGMP message, sending every valid packet down the "Checksum error" path to be silently dropped and breaking IGMP membership query/report processing. Compare against 0xffff instead, matching the convention used by the other transport input handlers: - ipv4_input.c: (ipv4_chksum(IPv4BUF) != 0xffff) - tcp_input.c: (tcp_chksum(dev) != 0xffff) This is also consistent with the sender side in igmp_send.c, which stores `igmp->chksum = ~igmp_chksum(...)`. Signed-off-by: zhekunren <zhekunren@qq.com> Assisted-by: GLM-5.2 <noreply@z.ai>
zhekunren
force-pushed
the
fix/igmp-checksum-validation
branch
from
August 7, 2026 02:02
abc50d8 to
a233f9d
Compare
Contributor
Author
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
igmp_input()rejected every well-formed IGMP packet as a checksum error because the validation comparednet_chksum()against0instead of0xffff. This breaks IGMP membership query/report processing entirely wheneverCONFIG_NET_IGMP_CHECKSUMSis enabled.Problem
In
net/igmp/igmp_input.c, the IGMP checksum was validated as:With
CONFIG_NET_IGMP_CHECKSUMSenabled, every valid IGMP message hits thegoto droppath and is silently discarded, so the host never answers Membership Queries and never processes Membership Reports from neighbors.Root Cause
net_chksum()(innet/utils/net_chksum.c) returns the raw one's complement sum of all 16-bit words over the buffer — it does not take the one's complement of that sum:For a valid IGMP packet, the sender (
net/igmp/igmp_send.c) storesigmp->chksum = ~igmp_chksum(...). LetSbe the one's complement sum of the header with the checksum field zeroed. The received packet therefore contains~Sin the checksum field, and summing all 16-bit words yields:So the correct validation is
!= 0xffff, not!= 0. The old check!= 0is true for every legal IGMP packet (it can only be 0 in the degenerate case where the sum is exactly 0), so all valid packets were dropped.This is the same Internet checksum principle used by IPv4 (RFC 1071) and TCP/UDP.
Fix
Compare against
0xffff:Consistency
This matches the convention already used by the other transport input handlers in the tree:
net/devif/ipv4_input.c—(ipv4_chksum(IPv4BUF) != 0xffff)net/tcp/tcp_input.c—(tcp_chksum(dev) != 0xffff)and is symmetric with the sender side in
net/igmp/igmp_send.c, which writesigmp->chksum = ~igmp_chksum(...).Impact
goto drop).CONFIG_NET_IGMP_CHECKSUMS=y: Membership Queries now correctly trigger the delaying-member state machine, and Membership Reports correctly cancel the report timer.CONFIG_NET_IGMP_CHECKSUMSis disabled (the block is compiled out).f11df565("net/igmp: fix length check that always dropped valid IGMP packets") — together they restore a fully broken IGMP input path.Testing
Verified by inspection against
net_chksum()semantics and cross-checked withipv4_input.c/tcp_input.c. Code path is gated behindCONFIG_NET_IGMP_CHECKSUMSso the default build is unchanged.