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"
}