Module Name: src Committed By: ozaki-r Date: Wed Sep 9 01:24:01 UTC 2015
Modified Files: src/sys/netinet: if_arp.c Log Message: Remove wrong KASSERT in arptfree la_rt can be NULL because arptimer that calls arptfree doesn't always free llentry so llentry can remain with la_rt == NULL. So we instead check whether la_rt is NULL or not and do arptfree if not. This fixes PR kern/50184 (confirmed by martin@) and PR kern/50186 (maybe). To generate a diff of this commit: cvs rdiff -u -r1.179 -r1.180 src/sys/netinet/if_arp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.179 src/sys/netinet/if_arp.c:1.180 --- src/sys/netinet/if_arp.c:1.179 Wed Sep 9 01:22:28 2015 +++ src/sys/netinet/if_arp.c Wed Sep 9 01:24:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.179 2015/09/09 01:22:28 ozaki-r Exp $ */ +/* $NetBSD: if_arp.c,v 1.180 2015/09/09 01:24:01 ozaki-r Exp $ */ /*- * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.179 2015/09/09 01:22:28 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.180 2015/09/09 01:24:01 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -159,7 +159,7 @@ static void arp_init(void); static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *, const struct sockaddr *); -static void arptfree(struct llentry *); +static void arptfree(struct rtentry *); static void arptimer(void *); static struct llentry *arplookup(struct ifnet *, struct mbuf *, const struct in_addr *, int, int, int, struct rtentry *); @@ -351,8 +351,11 @@ arptimer(void *arg) /* XXX: LOR avoidance. We still have ref on lle. */ LLE_WUNLOCK(lle); - /* We have to call this w/o lock */ - arptfree(lle); + if (lle->la_rt != NULL) { + /* We have to call arptfree w/o IF_AFDATA_LOCK */ + arptfree(lle->la_rt); + lle->la_rt = NULL; + } IF_AFDATA_LOCK(ifp); LLE_WLOCK(lle); @@ -1423,18 +1426,11 @@ out: /* * Free an arp entry. */ -static void arptfree(struct llentry *la) +static void arptfree(struct rtentry *rt) { - struct rtentry *rt = la->la_rt; - - KASSERT(rt != NULL); - - if (la->la_rt != NULL) { - rtfree(la->la_rt); - la->la_rt = NULL; - } rtrequest(RTM_DELETE, rt_getkey(rt), NULL, rt_mask(rt), 0, NULL); + rtfree(rt); } /*