diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index a83f31cac70..31a3ebef30b 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -249,6 +249,7 @@ MALLOC_DECLARE(M_LLTABLE); #define LLE_VALID 0x0008 /* ll_addr is valid */ #define LLE_PUB 0x0020 /* publish entry ??? */ #define LLE_LINKED 0x0040 /* linked to lookup structure */ +#define LLE_UNRESOLVED 0x0080 /* address unresolved */ /* LLE request flags */ #define LLE_EXCLUSIVE 0x2000 /* return lle xlocked */ diff --git a/sys/net/nd.c b/sys/net/nd.c index ef67a4cd39d..ba714714cea 100644 --- a/sys/net/nd.c +++ b/sys/net/nd.c @@ -115,6 +115,7 @@ nd_timer(void *arg) missed = ND_LLINFO_INCOMPLETE; ln->ln_state = ND_LLINFO_WAITDELETE; + ln->la_flags |= LLE_UNRESOLVED; break; case ND_LLINFO_REACHABLE: @@ -362,8 +363,10 @@ nd_resolve(struct llentry *ln, const struct rtentry *rt, struct mbuf *m, * the oldest packet in the queue will be removed. */ if (ln->ln_state == ND_LLINFO_NOSTATE || - ln->ln_state == ND_LLINFO_WAITDELETE) + ln->ln_state == ND_LLINFO_WAITDELETE) { + ln->ln_asked = 0; ln->ln_state = ND_LLINFO_INCOMPLETE; + } #ifdef MBUFTRACE m_claimm(m, ln->lle_tbl->llt_mowner); @@ -400,7 +403,7 @@ nd_resolve(struct llentry *ln, const struct rtentry *rt, struct mbuf *m, ln->la_numheld, nd->nd_maxqueuelen); ln->la_numheld++; - if (ln->ln_asked >= nd->nd_mmaxtries) + if ((ln->la_flags & LLE_UNRESOLVED) != 0) error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ? EHOSTUNREACH : EHOSTDOWN; else diff --git a/sys/netinet/if_arp.c b/sys/netinet/if_arp.c index 2934534efb1..fc4d0252a74 100644 --- a/sys/netinet/if_arp.c +++ b/sys/netinet/if_arp.c @@ -1056,6 +1056,7 @@ again: KASSERT(sizeof(la->ll_addr) >= ifp->if_addrlen); memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen); la->la_flags |= LLE_VALID; + la->la_flags &= ~LLE_UNRESOLVED; la->ln_asked = 0; if (new_state != 0) { la->ln_state = new_state; diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 8ae3392fbac..d8891f952b6 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1399,6 +1399,7 @@ nd6_cache_lladdr( */ memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen); ln->la_flags |= LLE_VALID; + ln->la_flags &= ~LLE_UNRESOLVED; } if (!is_newentry) { diff --git a/tests/net/arp/t_arp.sh b/tests/net/arp/t_arp.sh index e0aa1a672a6..b2dd9a17368 100644 --- a/tests/net/arp/t_arp.sh +++ b/tests/net/arp/t_arp.sh @@ -907,6 +907,29 @@ test_resolution() rump_server_destroy_ifaces } +test_keep_sending() +{ + + rump_server_start $SOCKSRC + setup_src_server + + export RUMP_SERVER=$SOCKSRC + + extract_new_packets bus1 > ./out + + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w 10 -c 10 $IP4DST + + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + pkt=$(make_pkt_str_arpreq $IP4DST $IP4SRC) + n=$(grep -E "$pkt" ./out |wc -l) + atf_check -s exit:0 test $n -ge 10 + + rump_server_destroy_ifaces +} + add_test() { local name=$1 @@ -947,4 +970,5 @@ atf_init_test_cases() add_test cache_creation "Tests for ARP cache creation" add_test cache_creation_nodad "Tests for ARP cache creation without DAD" add_test resolution "Tests for ARP resolution" + add_test keep_sending "Tests if ARP keeps sending requests" }