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: