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);
 }
 
 /*

Reply via email to