On Tue, Apr 25, 2023 at 04:15:49PM +0000, Klemens Nanni wrote: > A clearer version of this diff would use two new bools `expired' and `reject' > rather than a ternary `reject', but that can be polished and retested later.
Or simpler even, use new `expired' and existing `refresh'. Refresh and reject are mutually exclusive actions. This is easier to grok, imho. Index: if_ether.c =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.c,v retrieving revision 1.263 diff -u -p -r1.263 if_ether.c --- if_ether.c 25 Apr 2023 16:24:25 -0000 1.263 +++ if_ether.c 25 Apr 2023 16:54:37 -0000 @@ -339,7 +339,7 @@ arpresolve(struct ifnet *ifp, struct rte struct rtentry *rt = NULL; char addr[INET_ADDRSTRLEN]; time_t uptime; - int refresh = 0, reject = 0; + int refresh = 0, expired = 0; if (m->m_flags & M_BCAST) { /* broadcast */ memcpy(desten, etherbroadcastaddr, sizeof(etherbroadcastaddr)); @@ -444,13 +444,12 @@ arpresolve(struct ifnet *ifp, struct rte } #endif if (rt->rt_expire) { - reject = ~RTF_REJECT; + expired = 1; if (la->la_asked == 0 || rt->rt_expire != uptime) { rt->rt_expire = uptime; if (la->la_asked++ < arp_maxtries) refresh = 1; else { - reject = RTF_REJECT; rt->rt_expire += arpt_down; la->la_asked = 0; la->la_refreshed = 0; @@ -461,19 +460,23 @@ arpresolve(struct ifnet *ifp, struct rte } mtx_leave(&arp_mtx); - if (reject == RTF_REJECT && !ISSET(rt->rt_flags, RTF_REJECT)) { - KERNEL_LOCK(); - SET(rt->rt_flags, RTF_REJECT); - KERNEL_UNLOCK(); - } - if (reject == ~RTF_REJECT && ISSET(rt->rt_flags, RTF_REJECT)) { - KERNEL_LOCK(); - CLR(rt->rt_flags, RTF_REJECT); - KERNEL_UNLOCK(); - } - if (refresh) - arprequest(ifp, &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr, - &satosin(dst)->sin_addr.s_addr, ac->ac_enaddr); + if (expired) { + if (refresh) { + KERNEL_LOCK(); + CLR(rt->rt_flags, RTF_REJECT); + KERNEL_UNLOCK(); + } else { + KERNEL_LOCK(); + SET(rt->rt_flags, RTF_REJECT); + KERNEL_UNLOCK(); + + arprequest(ifp, + &satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr, + &satosin(dst)->sin_addr.s_addr, + ac->ac_enaddr); + } + } + return (EAGAIN); bad: