I'd like to change the behavior of arptfree() to stop checking the
reference counter of the route:

  - to keep the logic for reference counting rout entries simple,

  - and to align it with the NDP behavior (see nd6_free()).


With this diff expired ARP entries get removed from the routing table,
no matter if there are still referenced (cached) or not.  This is safe
because removing an entry will mark it DOWN so it wont be used by code
having a reference to it.

Ok?

Index: netinet/if_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.170
diff -u -p -r1.170 if_ether.c
--- netinet/if_ether.c  28 Sep 2015 08:26:58 -0000      1.170
+++ netinet/if_ether.c  2 Oct 2015 12:39:38 -0000
@@ -91,7 +91,7 @@ int   arpt_prune = (5*60*1);  /* walk list 
 int    arpt_keep = (20*60);    /* once resolved, good for 20 more minutes */
 int    arpt_down = 20;         /* once declared down, don't send for 20 secs */
 
-void arptfree(struct llinfo_arp *);
+void arptfree(struct rtentry *);
 void arptimer(void *);
 struct rtentry *arplookup(u_int32_t, int, int, u_int);
 void in_arpinput(struct mbuf *);
@@ -141,7 +141,7 @@ arptimer(void *arg)
 
                nla = LIST_NEXT(la, la_list);
                if (rt->rt_expire && rt->rt_expire <= time_second)
-                       arptfree(la); /* timer has expired; clear */
+                       arptfree(rt); /* timer has expired; clear */
        }
        splx(s);
 }
@@ -780,26 +780,20 @@ out:
  * Free an arp entry.
  */
 void
-arptfree(struct llinfo_arp *la)
+arptfree(struct rtentry *rt)
 {
-       struct rtentry *rt = la->la_rt;
-       struct sockaddr_dl *sdl;
-       u_int tid = 0;
+       struct llinfo_arp *la = (struct llinfo_arp *)rt->rt_llinfo;
+       struct sockaddr_dl *sdl = SDL(rt->rt_gateway);
+       int s;
 
-       if (rt == NULL)
-               panic("arptfree");
-       if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
-           sdl->sdl_family == AF_LINK) {
+       if ((sdl != NULL) && (sdl->sdl_family == AF_LINK)) {
                sdl->sdl_alen = 0;
                la->la_asked = 0;
-               rt->rt_flags &= ~RTF_REJECT;
-               return;
        }
 
-       if (rt->rt_ifp)
-               tid = rt->rt_ifp->if_rdomain;
-
-       rtdeletemsg(rt, tid);
+       s = splsoftnet();
+       rtdeletemsg(rt, rt->rt_ifp->if_rdomain);
+       splx(s);
 }
 
 /*

Reply via email to