Module Name: src Committed By: martin Date: Sat Aug 24 16:46:35 UTC 2024
Modified Files: src/sys/netinet [netbsd-9]: if_arp.c in.c src/tests/net/arp [netbsd-9]: t_arp.sh t_dad.sh Log Message: Pull up following revision(s) (requested by ozaki-r in ticket #1883): tests/net/arp/t_dad.sh: revision 1.16 sys/netinet/in.c: revision 1.248 tests/net/arp/t_arp.sh: revision 1.46 sys/netinet/if_arp.c: revision 1.314 arp: fix the behavior on detecting an address duplication without IPv4 DAD On receiving an ARP request that has the same source protocol address as the own address, i.e., address duplication, the original behavior of a kernel prior to supporing IPv4 DAD is to send an ARP reply. It is the same with a latest kernel with DAD enabled. However, a latest kernel without DAD sends back an GARP packet. Restore the original behavior. inet: send GARP on link up if DAD is disabled This behavior was accidentally removed at rev 1.233. tests, arp: add tests of address duplications without DAD tests, arp: add tests for GARP on link up To generate a diff of this commit: cvs rdiff -u -r1.282.2.6 -r1.282.2.7 src/sys/netinet/if_arp.c cvs rdiff -u -r1.234.2.1 -r1.234.2.2 src/sys/netinet/in.c cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/tests/net/arp/t_arp.sh cvs rdiff -u -r1.15 -r1.15.14.1 src/tests/net/arp/t_dad.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.282.2.6 src/sys/netinet/if_arp.c:1.282.2.7 --- src/sys/netinet/if_arp.c:1.282.2.6 Fri Jan 24 18:57:02 2020 +++ src/sys/netinet/if_arp.c Sat Aug 24 16:46:35 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.282.2.6 2020/01/24 18:57:02 martin Exp $ */ +/* $NetBSD: if_arp.c,v 1.282.2.7 2024/08/24 16:46:35 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.282.2.6 2020/01/24 18:57:02 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.282.2.7 2024/08/24 16:46:35 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1166,8 +1166,20 @@ again: */ if (in_nullhost(isaddr)) ARP_STATINC(ARP_STAT_RCVZEROSPA); - else if (in_hosteq(isaddr, myaddr)) + else if (in_hosteq(isaddr, myaddr)) { ARP_STATINC(ARP_STAT_RCVLOCALSPA); + /* This is the original behavior prior to supporting IPv4 DAD */ + if (!ip_dad_enabled()) { + char llabuf[LLA_ADDRSTRLEN]; + log(LOG_ERR, + "duplicate IP address %s sent from link address %s\n", + IN_PRINT(ipbuf, &isaddr), + lla_snprintf(llabuf, sizeof(llabuf), ar_sha(ah), + ah->ar_hln)); + itaddr = myaddr; + goto reply; + } + } if (in_nullhost(itaddr)) ARP_STATINC(ARP_STAT_RCVZEROTPA); @@ -1181,7 +1193,7 @@ again: * AND our address is either tentative or duplicated * If it was unicast then it's a valid Unicast Poll from RFC 1122. */ - if (do_dad && + if (ip_dad_enabled() && do_dad && (in_hosteq(isaddr, myaddr) || (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr) && m->m_flags & M_BCAST && Index: src/sys/netinet/in.c diff -u src/sys/netinet/in.c:1.234.2.1 src/sys/netinet/in.c:1.234.2.2 --- src/sys/netinet/in.c:1.234.2.1 Thu Oct 8 18:04:59 2020 +++ src/sys/netinet/in.c Sat Aug 24 16:46:35 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: in.c,v 1.234.2.1 2020/10/08 18:04:59 martin Exp $ */ +/* $NetBSD: in.c,v 1.234.2.2 2024/08/24 16:46:35 martin Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.234.2.1 2020/10/08 18:04:59 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.234.2.2 2024/08/24 16:46:35 martin Exp $"); #include "arp.h" @@ -1470,8 +1470,7 @@ in_if_link_up(struct ifnet *ifp) /* If detached then mark as tentative */ if (ia->ia4_flags & IN_IFF_DETACHED) { ia->ia4_flags &= ~IN_IFF_DETACHED; - if (ip_dad_enabled() && if_do_dad(ifp) && - ia->ia_dad_start != NULL) + if (if_do_dad(ifp) && ia->ia_dad_start != NULL) ia->ia4_flags |= IN_IFF_TENTATIVE; else if ((ia->ia4_flags & IN_IFF_TENTATIVE) == 0) rt_addrmsg(RTM_NEWADDR, ifa); Index: src/tests/net/arp/t_arp.sh diff -u src/tests/net/arp/t_arp.sh:1.37.2.1 src/tests/net/arp/t_arp.sh:1.37.2.2 --- src/tests/net/arp/t_arp.sh:1.37.2.1 Thu Sep 5 08:45:53 2019 +++ src/tests/net/arp/t_arp.sh Sat Aug 24 16:46:35 2024 @@ -1,4 +1,4 @@ -# $NetBSD: t_arp.sh,v 1.37.2.1 2019/09/05 08:45:53 martin Exp $ +# $NetBSD: t_arp.sh,v 1.37.2.2 2024/08/24 16:46:35 martin Exp $ # # Copyright (c) 2015 The NetBSD Foundation, Inc. # All rights reserved. @@ -386,6 +386,35 @@ test_garp_common() atf_check -s exit:0 -o not-match:"$pkt" cat ./out fi + # + # GARP on Link up + # + atf_check -s exit:0 rump.ifconfig shmif0 media none + extract_new_packets bus1 > ./out + atf_check -s exit:0 rump.ifconfig shmif0 media auto + + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + + if $no_dad; then + # A GARP packet is sent for both primary and alias addresses. + pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) + atf_check -s exit:0 -o match:"$pkt" cat ./out + pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) + atf_check -s exit:0 -o match:"$pkt" cat ./out + else + # No GARP is sent. + pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) + atf_check -s exit:0 -o not-match:"$pkt" cat ./out + pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) + atf_check -s exit:0 -o not-match:"$pkt" cat ./out + # DAD packets are sent instead. + pkt=$(make_pkt_str_arpreq 10.0.0.3 0.0.0.0) + atf_check -s exit:0 -o match:"$pkt" cat ./out + pkt=$(make_pkt_str_arpreq 10.0.0.4 0.0.0.0) + atf_check -s exit:0 -o match:"$pkt" cat ./out + fi + rump_server_destroy_ifaces } Index: src/tests/net/arp/t_dad.sh diff -u src/tests/net/arp/t_dad.sh:1.15 src/tests/net/arp/t_dad.sh:1.15.14.1 --- src/tests/net/arp/t_dad.sh:1.15 Sat Mar 11 02:01:10 2017 +++ src/tests/net/arp/t_dad.sh Sat Aug 24 16:46:35 2024 @@ -1,4 +1,4 @@ -# $NetBSD: t_dad.sh,v 1.15 2017/03/11 02:01:10 ozaki-r Exp $ +# $NetBSD: t_dad.sh,v 1.15.14.1 2024/08/24 16:46:35 martin Exp $ # # Copyright (c) 2015 The NetBSD Foundation, Inc. # All rights reserved. @@ -32,6 +32,7 @@ DEBUG=${DEBUG:-false} atf_test_case dad_basic cleanup atf_test_case dad_duplicated cleanup +atf_test_case dad_duplicated_nodad cleanup dad_basic_head() { @@ -45,6 +46,12 @@ dad_duplicated_head() atf_set "require.progs" "rump_server" } +dad_duplicated_nodad_head() +{ + atf_set "descr" "Tests for IPv4 DAD duplicated state w/o DAD" + atf_set "require.progs" "rump_server" +} + setup_server() { local sock=$1 @@ -69,6 +76,16 @@ make_pkt_str() echo $pkt } +make_reply_str() +{ + local srcmac=$1 + local dstmac=$2 + local ip=$3 + pkt="$srcmac > $dstmac, ethertype ARP \(0x0806\), length 42:" + pkt="Reply $ip is-at $srcmac, length 28" + echo $pkt +} + dad_basic_body() { local pkt= @@ -190,6 +207,71 @@ dad_duplicated_body() rump_server_destroy_ifaces } +dad_duplicated_nodad_body() +{ + local localip1=10.0.1.1 + local localip2=10.0.1.11 + local peerip=10.0.1.2 + local lmac= pmac= + + rump_server_start $SOCKLOCAL + rump_server_start $SOCKPEER + + export RUMP_SERVER=$SOCKLOCAL + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.dad_count=0 + export RUMP_SERVER=$SOCKPEER + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.dad_count=0 + + setup_server $SOCKLOCAL $localip1 + setup_server $SOCKPEER $peerip + + export RUMP_SERVER=$SOCKLOCAL + + # The primary address isn't marked as duplicated + atf_check -s exit:0 -o not-match:"${localip1}.+DUPLICATED" \ + rump.ifconfig shmif0 + + extract_new_packets bus1 > ./out + + # GARP packets are sent + pkt=$(make_pkt_str $localip1 $localip1) + atf_check -s exit:0 -o match:"$pkt" cat ./out + pkt=$(make_pkt_str $peerip $peerip) + atf_check -s exit:0 -o match:"$pkt" cat ./out + + # No DAD probe packets are sent + pkt=$(make_pkt_str $localip1 0.0.0.0) + atf_check -s exit:0 -o not-match:"$pkt" cat ./out + pkt=$(make_pkt_str $peerip 0.0.0.0) + atf_check -s exit:0 -o not-match:"$pkt" cat ./out + + # + # Add a new address duplicated with the peer server + # + atf_check -s exit:0 rump.ifconfig shmif0 inet $peerip alias + atf_check -s exit:0 sleep 2 + + # The new address is NOT marked as duplicated + atf_check -s exit:0 -o not-match:"${peerip}.+DUPLICATED" \ + rump.ifconfig shmif0 + + lmac=$(get_macaddr $SOCKLOCAL) + pmac=$(get_macaddr $SOCKPEER) + extract_new_packets bus1 > ./out + + # The peer just replies a GARP of the peer + pkt=$(make_reply_str $pmac $lmac $peerip) + atf_check -s exit:0 -o match:"$pkt" cat ./out + + # A unique address isn't marked as duplicated + atf_check -s exit:0 rump.ifconfig shmif0 inet $localip2 alias + atf_check -s exit:0 sleep 2 + atf_check -s exit:0 -o not-match:"${localip2}.+DUPLICATED" \ + rump.ifconfig shmif0 + + rump_server_destroy_ifaces +} + dad_basic_cleanup() { $DEBUG && dump @@ -202,8 +284,16 @@ dad_duplicated_cleanup() cleanup } +dad_duplicated_nodad_cleanup() +{ + + $DEBUG && dump + cleanup +} + atf_init_test_cases() { atf_add_test_case dad_basic atf_add_test_case dad_duplicated + atf_add_test_case dad_duplicated_nodad }