You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ar...@apache.org on 2026/04/23 07:11:14 UTC
(nuttx) branch master updated: net/devif: Reorder ipv4_input packet classification.
This is an automated email from the ASF dual-hosted git repository.
anchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 5428220062f net/devif: Reorder ipv4_input packet classification.
5428220062f is described below
commit 5428220062f84f7867d050e3db5ae0e3c5b3bb07
Author: Shunchao Hu <an...@gmail.com>
AuthorDate: Sun Apr 19 10:25:15 2026 +0800
net/devif: Reorder ipv4_input packet classification.
Rework ipv4_input() packet classification to make the control flow
clearer and keep the common local-unicast case first.
This change:
- handles local packets first
- keeps broadcast/multicast handling in dedicated branches
It also prevents broadcast and multicast packets from falling through
into the unicast forward path.
Signed-off-by: Shunchao Hu <an...@gmail.com>
---
net/devif/ipv4_input.c | 154 ++++++++++++++++++-------------------------------
1 file changed, 57 insertions(+), 97 deletions(-)
diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c
index 5c167a793ee..77ea651499b 100644
--- a/net/devif/ipv4_input.c
+++ b/net/devif/ipv4_input.c
@@ -311,140 +311,100 @@ static int ipv4_in(FAR struct net_driver_s *dev)
destipaddr = net_ip4addr_conv32(ipv4->destipaddr);
-#if defined(CONFIG_NET_BROADCAST) && defined(NET_UDP_HAVE_STACK)
- /* If IP broadcast support is configured, we check for a broadcast
- * UDP packet, which may be destined to us (even if there is no IP
- * address yet assigned to the device as is the case when we are
- * negotiating over DHCP for an address).
+ /* Keep the common local-unicast case on the fast path, then classify
+ * non-local packets as broadcast, multicast, or forwardable unicast.
*/
- if (ipv4->proto == IP_PROTO_UDP &&
- net_ipv4addr_cmp(destipaddr, INADDR_BROADCAST))
+ if (net_ipv4addr_cmp(destipaddr, dev->d_ipaddr))
{
-#ifdef CONFIG_NET_IPFORWARD_BROADCAST
- /* Forward broadcast packets */
-
- ipv4_forward_broadcast(dev, ipv4);
-
- /* Process the incoming packet if not forwardable */
-
- if (dev->d_len > 0)
-#endif
+#ifdef CONFIG_NET_ICMP
+ if (net_ipv4addr_cmp(dev->d_ipaddr, INADDR_ANY))
{
- ret = udp_ipv4_input(dev);
+ nwarn("WARNING: No IP address assigned\n");
+ goto drop;
}
-
- goto done;
- }
- else
#endif
-#if defined(CONFIG_NET_BROADCAST) && defined(NET_UDP_HAVE_STACK)
- /* The address is not the broadcast address and we have been assigned a
- * address. So there is also the possibility that the destination address
- * is a sub-net broadcast address which we will need to handle just as for
- * the broadcast address above.
- */
-
- if (ipv4->proto == IP_PROTO_UDP &&
- net_ipv4addr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask) &&
- net_ipv4addr_broadcast(destipaddr, dev->d_netmask))
+ }
+ else if (net_ipv4addr_cmp(destipaddr, INADDR_BROADCAST) ||
+ (net_ipv4addr_maskcmp(destipaddr, dev->d_ipaddr,
+ dev->d_netmask) &&
+ net_ipv4addr_broadcast(destipaddr, dev->d_netmask)))
{
#ifdef CONFIG_NET_IPFORWARD_BROADCAST
- /* Forward broadcast packets */
-
ipv4_forward_broadcast(dev, ipv4);
-
- /* Process the incoming packet if not forwardable */
-
- if (dev->d_len > 0)
#endif
+
+#if defined(CONFIG_NET_BROADCAST) && defined(NET_UDP_HAVE_STACK)
+ if (ipv4->proto == IP_PROTO_UDP)
{
ret = udp_ipv4_input(dev);
+ goto done;
}
-
- goto done;
- }
- else
#endif
- /* Check if the packet is destined for our IP address. */
- if (!net_ipv4addr_cmp(destipaddr, dev->d_ipaddr))
+#ifdef CONFIG_NET_STATISTICS
+ g_netstats.ipv4.drop++;
+#endif
+ goto drop;
+ }
+ else if (IN_MULTICAST(NTOHL(destipaddr)))
{
- /* No.. This is not our IP address. Check for an IPv4 IGMP group
- * address
- */
-
#ifdef CONFIG_NET_IGMP
- in_addr_t destip = net_ip4addr_conv32(ipv4->destipaddr);
- if (igmp_grpfind(dev, &destip) != NULL)
+ if (igmp_grpfind(dev, &destipaddr) != NULL)
{
#ifdef CONFIG_NET_IPFORWARD_BROADCAST
- /* Forward multicast packets */
-
ipv4_forward_broadcast(dev, ipv4);
-
- /* Return success if the packet was forwarded. */
-
- if (dev->d_len == 0)
- {
- goto done;
- }
#endif
}
else
#endif
{
- /* No.. The packet is not destined for us. */
-
+#ifdef CONFIG_NET_STATISTICS
+ g_netstats.ipv4.drop++;
+#endif
+ goto drop;
+ }
+ }
+ else
+ {
#ifdef CONFIG_NET_IPFORWARD
- /* Try to forward the packet */
+ /* Try to forward the unicast packet. */
- if (ipv4_forward(dev, ipv4) >= 0)
- {
- /* The packet was forwarded. Return success; d_len will
- * be set appropriately by the forwarding logic: Cleared
- * if the packet is forward via anoother device or non-
- * zero if it will be forwarded by the same device that
- * it was received on.
- */
-
- goto done;
- }
- else
+ if (ipv4_forward(dev, ipv4) >= 0)
+ {
+ /* The packet was forwarded. Return success; d_len will
+ * be set appropriately by the forwarding logic: Cleared
+ * if the packet is forward via another device or non-zero
+ * if it will be forwarded by the same device that it was
+ * received on.
+ */
+
+ goto done;
+ }
+ else
#endif
#if defined(NET_UDP_HAVE_STACK) && defined(CONFIG_NET_BINDTODEVICE)
- /* If the protocol specific socket option NET_BINDTODEVICE
- * is selected, then we must forward all UDP packets to the bound
- * socket.
- */
+ /* If the protocol specific socket option NET_BINDTODEVICE
+ * is selected, then we must forward all UDP packets to the bound
+ * socket.
+ */
- if (ipv4->proto != IP_PROTO_UDP)
+ if (ipv4->proto != IP_PROTO_UDP)
#endif
- {
- /* Not destined for us and not forwardable... Drop the
- * packet.
- */
+ {
+ /* Not destined for us and not forwardable... Drop the
+ * packet.
+ */
- ninfo("WARNING: Not destined for us; not forwardable... "
- "Dropping!\n");
+ ninfo("WARNING: Not destined for us; not forwardable... "
+ "Dropping!\n");
#ifdef CONFIG_NET_STATISTICS
- g_netstats.ipv4.drop++;
+ g_netstats.ipv4.drop++;
#endif
- goto drop;
- }
+ goto drop;
}
}
-#ifdef CONFIG_NET_ICMP
-
- /* In other cases, the device must be assigned a non-zero IP address. */
-
- else if (net_ipv4addr_cmp(dev->d_ipaddr, INADDR_ANY))
- {
- nwarn("WARNING: No IP address assigned\n");
- goto drop;
- }
-#endif
#ifdef CONFIG_NET_IPV4_CHECKSUMS
if (((dev->d_features & NETDEV_RX_CSUM) == 0)