Module Name:    src
Committed By:   martin
Date:           Fri Sep 13 14:17:26 UTC 2024

Modified Files:
        src/sys/netinet [netbsd-10]: if_arp.c
        src/tests/net/arp [netbsd-10]: t_arp.sh

Log Message:
Pull up following revision(s) (requested by ozaki-r in ticket #859):

        tests/net/arp/t_arp.sh: revision 1.47
        tests/net/arp/t_arp.sh: revision 1.48
        sys/netinet/if_arp.c: revision 1.315

arp: allow to send packets without an ARP resolution just after
receiving an ARP request

On receiving an ARP request, the current implemention creates an ARP
cache entry but with ND_LLINFO_NOSTATE.  Such an entry still needs
an ARP resolution to send back a packet to the requester.  The original
behavior before introducing the common ND framework didn't need the
resolution.  IPv6 doesn't as well.  To restore the original behavior,
make a new ARP cache entry with ND_LLINFO_STALE like IPv6 does.

tests: dedup t_arp.sh like others (NFC)

tests: add tests for ARP cache entry creations


To generate a diff of this commit:
cvs rdiff -u -r1.311.2.2 -r1.311.2.3 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.45.6.1 -r1.45.6.2 src/tests/net/arp/t_arp.sh

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.311.2.2 src/sys/netinet/if_arp.c:1.311.2.3
--- src/sys/netinet/if_arp.c:1.311.2.2	Sat Aug 24 16:45:05 2024
+++ src/sys/netinet/if_arp.c	Fri Sep 13 14:17:26 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.311.2.2 2024/08/24 16:45:05 martin Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.311.2.3 2024/09/13 14:17:26 martin Exp $	*/
 
 /*
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.311.2.2 2024/08/24 16:45:05 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.311.2.3 2024/09/13 14:17:26 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1034,6 +1034,17 @@ again:
 			/* This was a solicited ARP reply. */
 			la->ln_byhint = 0;
 			new_state = ND_LLINFO_REACHABLE;
+		} else if (op == ARPOP_REQUEST &&
+		           (la->ln_state == ND_LLINFO_NOSTATE ||
+			    la->ln_state == ND_LLINFO_INCOMPLETE)) {
+			/*
+			 * If an ARP request comes but there is no entry
+			 * and a new one has been created or an entry exists
+			 * but incomplete, make it stale to allow to send
+			 * packets to the requester without an ARP resolution.
+			 */
+			la->ln_byhint = 0;
+			new_state = ND_LLINFO_STALE;
 		}
 		rt_cmd = la->la_flags & LLE_VALID ? 0 : RTM_ADD;
 	}

Index: src/tests/net/arp/t_arp.sh
diff -u src/tests/net/arp/t_arp.sh:1.45.6.1 src/tests/net/arp/t_arp.sh:1.45.6.2
--- src/tests/net/arp/t_arp.sh:1.45.6.1	Sat Aug 24 16:45:04 2024
+++ src/tests/net/arp/t_arp.sh	Fri Sep 13 14:17:26 2024
@@ -1,4 +1,4 @@
-#	$NetBSD: t_arp.sh,v 1.45.6.1 2024/08/24 16:45:04 martin Exp $
+#	$NetBSD: t_arp.sh,v 1.45.6.2 2024/09/13 14:17:26 martin Exp $
 #
 # Copyright (c) 2015 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -39,72 +39,6 @@ IP4DST_FAIL2=10.0.99.99
 DEBUG=${DEBUG:-false}
 TIMEOUT=1
 
-atf_test_case arp_cache_expiration cleanup
-atf_test_case arp_command cleanup
-atf_test_case arp_garp cleanup
-atf_test_case arp_garp_without_dad cleanup
-atf_test_case arp_cache_overwriting cleanup
-atf_test_case arp_proxy_arp_pub cleanup
-atf_test_case arp_proxy_arp_pubproxy cleanup
-atf_test_case arp_link_activation cleanup
-atf_test_case arp_static cleanup
-
-arp_cache_expiration_head()
-{
-	atf_set "descr" "Tests for ARP cache expiration"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_command_head()
-{
-	atf_set "descr" "Tests for arp_commands of arp(8)"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_garp_head()
-{
-	atf_set "descr" "Tests for GARP"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_garp_without_dad_head()
-{
-
-	atf_set "descr" "Tests for GARP with DAD disabled"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_cache_overwriting_head()
-{
-	atf_set "descr" "Tests for behavior of overwriting ARP caches"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_proxy_arp_pub_head()
-{
-	atf_set "descr" "Tests for Proxy ARP (pub)"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_proxy_arp_pubproxy_head()
-{
-	atf_set "descr" "Tests for Proxy ARP (pub proxy)"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_link_activation_head()
-{
-	atf_set "descr" "Tests for activating a new MAC address"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_static_head()
-{
-
-	atf_set "descr" "Tests for static ARP entries"
-	atf_set "require.progs" "rump_server"
-}
-
 setup_dst_server()
 {
 
@@ -155,7 +89,7 @@ get_timeout()
 	echo $timeout
 }
 
-arp_cache_expiration_body()
+test_cache_expiration()
 {
 	local arp_keep=7
 
@@ -212,7 +146,7 @@ check_arp_static_entry()
 	fi
 }
 
-arp_command_body()
+test_command()
 {
 	local arp_keep=5
 	local bonus=2
@@ -415,19 +349,19 @@ test_garp_common()
 	rump_server_destroy_ifaces
 }
 
-arp_garp_body()
+test_garp()
 {
 
 	test_garp_common false
 }
 
-arp_garp_without_dad_body()
+test_garp_without_dad()
 {
 
 	test_garp_common true
 }
 
-arp_cache_overwriting_body()
+test_cache_overwriting()
 {
 
 	rump_server_start $SOCKSRC
@@ -576,21 +510,21 @@ test_proxy_arp()
 	atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2
 }
 
-arp_proxy_arp_pub_body()
+test_proxy_arp_pub()
 {
 
 	test_proxy_arp pub
 	rump_server_destroy_ifaces
 }
 
-arp_proxy_arp_pubproxy_body()
+test_proxy_arp_pubproxy()
 {
 
 	test_proxy_arp pubproxy
 	rump_server_destroy_ifaces
 }
 
-arp_link_activation_body()
+test_link_activation()
 {
 
 	rump_server_start $SOCKSRC
@@ -627,7 +561,7 @@ arp_link_activation_body()
 	rump_server_destroy_ifaces
 }
 
-arp_static_body()
+test_static()
 {
 	local macaddr_src=
 
@@ -652,70 +586,7 @@ arp_static_body()
 	rump_server_destroy_ifaces
 }
 
-arp_cache_expiration_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_command_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_garp_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_garp_without_dad_cleanup()
-{
-
-	$DEBUG && dump
-	cleanup
-}
-
-arp_cache_overwriting_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_proxy_arp_pub_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_proxy_arp_pubproxy_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_link_activation_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-arp_static_cleanup()
-{
-	$DEBUG && dump
-	cleanup
-}
-
-atf_test_case arp_rtm cleanup
-arp_rtm_head()
-{
-
-	atf_set "descr" "Tests for routing messages on operations of ARP entries"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_rtm_body()
+test_rtm()
 {
 	local macaddr_src= macaddr_dst=
 	local file=./tmp
@@ -793,22 +664,7 @@ arp_rtm_body()
 	rump_server_destroy_ifaces
 }
 
-arp_rtm_cleanup()
-{
-
-	$DEBUG && dump
-	cleanup
-}
-
-atf_test_case arp_purge_on_route_change cleanup
-arp_purge_on_route_change_head()
-{
-
-	atf_set "descr" "Tests if ARP entries are removed on route change"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_purge_on_route_change_body()
+test_purge_on_route_change()
 {
 
 	rump_server_start $SOCKSRC
@@ -835,22 +691,7 @@ arp_purge_on_route_change_body()
 	rump_server_destroy_ifaces
 }
 
-arp_purge_on_route_change_cleanup()
-{
-
-	$DEBUG && dump
-	cleanup
-}
-
-atf_test_case arp_purge_on_route_delete cleanup
-arp_purge_on_route_delete_head()
-{
-
-	atf_set "descr" "Tests if ARP entries are removed on route delete"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_purge_on_route_delete_body()
+test_purge_on_route_delete()
 {
 
 	rump_server_start $SOCKSRC
@@ -873,22 +714,7 @@ arp_purge_on_route_delete_body()
 	rump_server_destroy_ifaces
 }
 
-arp_purge_on_route_delete_cleanup()
-{
-
-	$DEBUG && dump
-	cleanup
-}
-
-atf_test_case arp_purge_on_ifdown cleanup
-arp_purge_on_ifdown_head()
-{
-
-	atf_set "descr" "Tests if ARP entries are removed on interface down"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_purge_on_ifdown_body()
+test_purge_on_ifdown()
 {
 
 	rump_server_start $SOCKSRC
@@ -911,22 +737,7 @@ arp_purge_on_ifdown_body()
 	rump_server_destroy_ifaces
 }
 
-arp_purge_on_ifdown_cleanup()
-{
-
-	$DEBUG && dump
-	cleanup
-}
-
-atf_test_case arp_stray_entries cleanup
-arp_stray_entries_head()
-{
-
-	atf_set "descr" "Tests if ARP entries are removed on route change"
-	atf_set "require.progs" "rump_server"
-}
-
-arp_stray_entries_body()
+test_stray_entries()
 {
 
 	rump_server_start $SOCKSRC
@@ -990,27 +801,113 @@ arp_stray_entries_body()
 	rump_server_destroy_ifaces
 }
 
-arp_stray_entries_cleanup()
+test_cache_creation_common()
+{
+	local no_dad=$1
+
+	rump_server_start $SOCKSRC
+	rump_server_start $SOCKDST
+
+	if $no_dad; then
+		export RUMP_SERVER=$SOCKSRC
+		atf_check -s exit:0 -o match:'3 -> 0' \
+		    rump.sysctl -w net.inet.ip.dad_count=0
+		export RUMP_SERVER=$SOCKDST
+		atf_check -s exit:0 -o match:'3 -> 0' \
+		    rump.sysctl -w net.inet.ip.dad_count=0
+	fi
+
+	setup_dst_server
+	setup_src_server
+
+	macaddr_src=$(get_macaddr $SOCKSRC shmif0)
+	macaddr_dst=$(get_macaddr $SOCKDST shmif0)
+
+	# ARP cache entries are not created for DAD/GARP packets.
+	export RUMP_SERVER=$SOCKSRC
+	atf_check -s exit:0 -o empty rump.arp -n -a
+	export RUMP_SERVER=$SOCKDST
+	atf_check -s exit:0 -o empty rump.arp -n -a
+
+	export RUMP_SERVER=$SOCKSRC
+
+	extract_new_packets bus1 > ./out
+
+	atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
+	$DEBUG && rump.arp -n -a
+
+	extract_new_packets bus1 > ./out
+
+	atf_check -s exit:0 -o match:"\? \(10.0.1.2\) at $macaddr_dst on shmif0 [0-9]+s R" \
+	    rump.arp -n -a
+
+	export RUMP_SERVER=$SOCKDST
+
+	# An entry was first created as stale then sending an ARP reply made it delay.
+	atf_check -s exit:0 -o match:"\? \(10.0.1.1\) at $macaddr_src on shmif0 [0-9]+s D" \
+	    rump.arp -n -a
+
+	# The sender resolves the receiver's address.
+	pkt=$(make_pkt_str_arpreq 10.0.1.2 10.0.1.1)
+	atf_check -s exit:0 -o match:"$pkt" cat ./out
+
+	# The receiver doesn't resolv the sender's address because the ARP request
+	# from the sender has let make an entry already.
+	pkt=$(make_pkt_str_arpreq 10.0.1.1 10.0.1.2)
+	atf_check -s exit:0 -o not-match:"$pkt" cat ./out
+
+	rump_server_destroy_ifaces
+}
+
+test_cache_creation()
 {
 
-	$DEBUG && dump
-	cleanup
+	test_cache_creation_common false
+}
+
+test_cache_creation_nodad()
+{
+
+	test_cache_creation_common true
+}
+
+add_test()
+{
+	local name=$1
+	local desc="$2"
+
+	atf_test_case "arp_${name}" cleanup
+	eval "arp_${name}_head() {
+			atf_set descr \"${desc}\"
+			atf_set require.progs rump_server
+		}
+	    arp_${name}_body() {
+			test_${name}
+		}
+	    arp_${name}_cleanup() {
+			\$DEBUG && dump
+			cleanup
+		}"
+	atf_add_test_case "arp_${name}"
 }
 
 atf_init_test_cases()
 {
-	atf_add_test_case arp_cache_expiration
-	atf_add_test_case arp_command
-	atf_add_test_case arp_garp
-	atf_add_test_case arp_garp_without_dad
-	atf_add_test_case arp_cache_overwriting
-	atf_add_test_case arp_proxy_arp_pub
-	atf_add_test_case arp_proxy_arp_pubproxy
-	atf_add_test_case arp_link_activation
-	atf_add_test_case arp_static
-	atf_add_test_case arp_rtm
-	atf_add_test_case arp_purge_on_route_change
-	atf_add_test_case arp_purge_on_route_delete
-	atf_add_test_case arp_purge_on_ifdown
-	atf_add_test_case arp_stray_entries
+
+	add_test cache_expiration      "Tests for ARP cache expiration"
+	add_test command               "Tests for arp_commands of arp(8)"
+	add_test garp                  "Tests for GARP"
+	add_test garp_without_dad      "Tests for GARP with DAD disabled"
+	add_test cache_overwriting     "Tests for behavior of overwriting ARP caches"
+	add_test proxy_arp_pub         "Tests for Proxy ARP (pub)"
+	add_test proxy_arp_pubproxy    "Tests for Proxy ARP (pub proxy)"
+	add_test link_activation       "Tests for activating a new MAC address"
+	add_test static                "Tests for static ARP entries"
+	add_test rtm                   "Tests for routing messages on operations of ARP entries"
+	add_test purge_on_route_change "Tests if ARP entries are removed on route change"
+	add_test purge_on_route_delete "Tests if ARP entries are removed on route delete"
+	add_test purge_on_ifdown       "Tests if ARP entries are removed on interface down"
+	add_test stray_entries         "Tests if ARP entries are removed on route change"
+	add_test cache_creation        "Tests for ARP cache creation"
+	add_test cache_creation_nodad  "Tests for ARP cache creation without DAD"
 }

Reply via email to