On Fri, Oct 02, 2015 at 04:03:46PM +0200, Martin Pieuchot wrote:
> 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?

The splsoftnet() in arptfree() is not needed, the whole loop in
arptimer() is protected by splsoftnet().

otherwise OK bluhm@

> 
> 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