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>
igmp_input() verified the packet length with:
if (dev->d_len < NET_LL_HDRLEN(dev) + (iphdrlen + IGMP_HDRLEN))
but dev->d_len at this point holds the IPv4 total length (IP header plus
payload) without the link-layer header, consistent with the convention
established in ipv4_in()/ipv6_in() (which do `dev->d_len -=
NET_LL_HDRLEN(dev)`) and used by all other transport input handlers
(icmp, tcp, udp), none of which reference NET_LL_HDRLEN.
Adding NET_LL_HDRLEN(dev) to the right-hand side made the check always
true for valid IGMP packets:
iphdrlen + IGMP_HDRLEN < NET_LL_HDRLEN + iphdrlen + IGMP_HDRLEN
(= 0 < NET_LL_HDRLEN)
so every well-formed IGMP message hit the "Length error" path and was
silently dropped, breaking IGMP membership query/report processing.
Drop the extra NET_LL_HDRLEN(dev) so the check matches the other
protocol handlers.
Signed-off-by: zhekunren <zhekunren@qq.com>
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>
debug.h is a NuttX-specific, non-POSIX header. Placing it in the
top-level include/ directory creates naming conflicts with external
projects that define their own debug.h.
This commit moves the canonical header to include/nuttx/debug.h,
following the NuttX convention for non-POSIX/non-standard headers,
and updates all in-tree references.
A backward-compatibility shim is left at include/debug.h that
emits a deprecation #warning and re-includes <nuttx/debug.h>,
allowing out-of-tree code to continue building while migrating.
Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
optimize the current code format according to the previous net_xxx_wait
implementation to reduce multiple calls of similar code
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
reduce the execution consumption of irrelevant code
testing the TX rates of TCP and UDP based on the Infineon board can
increase them by 13%.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Setting group->flags to IGMP_SCHEDMSG is a possible outcome, not unacceptable. If it occurs, an error log message will be reported
Signed-off-by: wangchen <wangchen41@xiaomi.com>
Most tools used for compliance and SBOM generation use SPDX identifiers
This change brings us a step closer to an easy SBOM generation.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
If the flag is not set, The flag is affected by the previously sent and
received packets, L2 header may be filled with ipv6
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
add ref count for ipv4 multicast and leave the multicast group when close
behavior alignment with linux.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
1. Update all CMakeLists.txt to adapt to new layout
2. Fix cmake build break
3. Update all new file license
4. Fully compatible with current compilation environment(use configure.sh or cmake as you choose)
------------------
How to test
From within nuttx/. Configure:
cmake -B build -DBOARD_CONFIG=sim/nsh -GNinja
cmake -B build -DBOARD_CONFIG=sim:nsh -GNinja
cmake -B build -DBOARD_CONFIG=sabre-6quad/smp -GNinja
cmake -B build -DBOARD_CONFIG=lm3s6965-ek/qemu-flat -GNinja
(or full path in custom board) :
cmake -B build -DBOARD_CONFIG=$PWD/boards/sim/sim/sim/configs/nsh -GNinja
This uses ninja generator (install with sudo apt install ninja-build). To build:
$ cmake --build build
menuconfig:
$ cmake --build build -t menuconfig
--------------------------
2. cmake/build: reformat the cmake style by cmake-format
https://github.com/cheshirekow/cmake_format
$ pip install cmakelang
$ for i in `find -name CMakeLists.txt`;do cmake-format $i -o $i;done
$ for i in `find -name *\.cmake`;do cmake-format $i -o $i;done
Co-authored-by: Matias N <matias@protobits.dev>
Signed-off-by: chao an <anchao@xiaomi.com>
Allocate the device buffer only if the protocol really need to send data.
not all protocols require the driver to prepare additional iob before
sending, especially UDP, each iob reserves l2/l3 header in advance
after prepare write buffer, net device could reuse this entry to send directly
Signed-off-by: chao an <anchao@xiaomi.com>
igmp/igmp_input.c: In function 'igmp_input':
igmp/igmp_input.c:201:31: warning: the comparison will always evaluate as 'false' for the address of 'grpaddr' will never be NULL [-Waddress]
201 | if (igmp->grpaddr == 0)
| ^~
In file included from nuttx/include/nuttx/net/netstats.h:67,
from igmp/igmp_input.c:53:
nuttx/include/nuttx/net/igmp.h:132:12: note: 'grpaddr' declared here
132 | uint16_t grpaddr[2]; /* 32-bit Group address */
| ^~~~~~~
Signed-off-by: chao an <anchao@xiaomi.com>
The following nxstyle errors are known.
They are a part of the copyright notice.
net/igmp/igmp_poll.c:22:82: error: Long line found
net/igmp/igmp_poll.c:29:82: error: Long line found
The following nxstyle errors are known.
They are a part of the copyright notice.
net/igmp/igmp_mcastmac.c:22:82: error: Long line found
net/igmp/igmp_mcastmac.c:29:82: error: Long line found
The following nxstyle errors are intentionally left
because they are a part of the copyright notice.
net/igmp/igmp_join.c:22:82: error: Long line found
net/igmp/igmp_join.c:29:82: error: Long line found
to save the preserved space(1KB) and also avoid the heap overhead
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I694073f68e1bd63960cedeea1ddec441437be025
igmp/igmp_timer.c: In function ‘igmp_timeout’:
igmp/igmp_timer.c:163:11: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
163 | group = (FAR struct igmp_group_s *)arg;
| ^
igmp/igmp_timer.c: In function ‘igmp_startticks’:
igmp/igmp_timer.c:200:55: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
200 | ret = wd_start(group->wdog, ticks, igmp_timeout, 1, (uint32_t)group);
| ^
igmp/igmp_timer.c:200:38: warning: passing argument 3 of ‘wd_start’ from incompatible pointer type [-Wincompatible-pointer-types]
200 | ret = wd_start(group->wdog, ticks, igmp_timeout, 1, (uint32_t)group);
| ^~~~~~~~~~~~
| |
| void (*)(int, uint32_t, ...) {aka void (*)(int, unsigned int, ...)}
In file included from igmp/igmp_timer.c:50:
/home/xiaoxiang/mirtos/nuttx/include/nuttx/wdog.h:233:53: note: expected ‘wdentry_t’ {aka ‘void (*)(int, long unsigned int, ...)’} but argument is of type ‘void (*)(int, uint32_t, ...)’ {aka ‘void (*)(int, unsigned int, ...)’}
233 | int wd_start(WDOG_ID wdog, int32_t delay, wdentry_t wdentry, int argc, ...);
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I153355f85f583f5441d97a0b1278bce167eb3fd0