mirror of
https://github.com/apache/nuttx.git
synced 2026-08-02 12:49:00 +00:00
fix(net/igmp): restore General Query handling broken by pointer compare
The group address in the IGMP header is declared as uint16_t grpaddr[2],
so it decays to a pointer. Comparing it against INADDR_ANY compares the
address of a struct member against 0, which is always false. The General
Query branch is therefore unreachable and GCC discards it entirely.
Commit 09bb292fa2 ("net/igmp: fix build warning on GCC 12.2.0") replaced
the original
if (igmp->grpaddr == 0)
with
if (net_ipv4addr_cmp(igmp->grpaddr, INADDR_ANY) != 0)
but net_ipv4addr_cmp(a, b) expands to (a == b) and INADDR_ANY expands to
((in_addr_t)0), so the emitted comparison is unchanged. The -Waddress
diagnostic disappeared only because the comparison now originates inside
a macro expanded from a header included via -isystem, and GCC suppresses
warnings from system-header macros. The defect was hidden, not fixed.
That commit also rewrote the unicast query test from group->grpaddr != 0,
which was well-formed, into the same pointer comparison, making it
unconditionally true.
Convert the header field with net_ip4addr_conv32() once, and compare the
resulting in_addr_t. The conversion was already being done in the
group-specific branch, so this only hoists it and reuses it.
Impact: a General Query (destination 224.0.0.1, group address 0) is the
periodic query every IGMP querier sends. It currently falls through to
the group-specific branch, where igmp_grpallocfind() allocates a group
for 0.0.0.0 and schedules a report for it, while joined groups never have
their report timers restarted. The querier then ages out the membership
and multicast delivery to the device stops.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
This commit is contained in:
parent
adf4a543e3
commit
f20cf4aac3
1 changed files with 11 additions and 5 deletions
|
|
@ -174,6 +174,13 @@ void igmp_input(struct net_driver_s *dev)
|
|||
* receivers.
|
||||
*/
|
||||
|
||||
/* The group address lies in the IGMP header where it is stored as
|
||||
* an unaligned uint16_t[2] in network order. Convert it to an
|
||||
* in_addr_t before it is used in any comparison.
|
||||
*/
|
||||
|
||||
grpaddr = net_ip4addr_conv32(igmp->grpaddr);
|
||||
|
||||
/* Check if the query was sent to all systems */
|
||||
|
||||
if (net_ipv4addr_cmp(destipaddr, g_ipv4_allsystems))
|
||||
|
|
@ -195,7 +202,7 @@ void igmp_input(struct net_driver_s *dev)
|
|||
* Query."
|
||||
*/
|
||||
|
||||
if (net_ipv4addr_cmp(igmp->grpaddr, INADDR_ANY) != 0)
|
||||
if (net_ipv4addr_cmp(grpaddr, INADDR_ANY))
|
||||
{
|
||||
FAR struct igmp_group_s *member;
|
||||
|
||||
|
|
@ -230,7 +237,7 @@ void igmp_input(struct net_driver_s *dev)
|
|||
}
|
||||
}
|
||||
}
|
||||
else /* if (net_ipv4addr_cmp(igmp->grpaddr, INADDR_ANY) == 0) */
|
||||
else /* if (!net_ipv4addr_cmp(grpaddr, INADDR_ANY)) */
|
||||
{
|
||||
ninfo("Group-specific multicast query\n");
|
||||
|
||||
|
|
@ -240,8 +247,7 @@ void igmp_input(struct net_driver_s *dev)
|
|||
|
||||
IGMP_STATINCR(g_netstats.igmp.ucast_query);
|
||||
|
||||
grpaddr = net_ip4addr_conv32(igmp->grpaddr);
|
||||
group = igmp_grpallocfind(dev, &grpaddr);
|
||||
group = igmp_grpallocfind(dev, &grpaddr);
|
||||
|
||||
if (group != NULL)
|
||||
{
|
||||
|
|
@ -259,7 +265,7 @@ void igmp_input(struct net_driver_s *dev)
|
|||
|
||||
/* Not sent to all systems -- Unicast query */
|
||||
|
||||
else if (net_ipv4addr_cmp(igmp->grpaddr, INADDR_ANY) == 0)
|
||||
else if (!net_ipv4addr_cmp(grpaddr, INADDR_ANY))
|
||||
{
|
||||
ninfo("Unicast query\n");
|
||||
IGMP_STATINCR(g_netstats.igmp.ucast_query);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue