Module Name:    src
Committed By:   martin
Date:           Mon Feb  5 14:55:16 UTC 2018

Modified Files:
        src/sys/kern [netbsd-8]: subr_workqueue.c
        src/sys/net [netbsd-8]: if.c route.c
        src/sys/net/agr [netbsd-8]: if_agr.c if_agrether.c if_agrsubr.c
            if_agrsubr.h
        src/sys/netinet6 [netbsd-8]: nd6.c nd6_rtr.c
        src/sys/netipsec [netbsd-8]: ipsec.c ipsec_input.c

Log Message:
Pull up following revision(s) (requested by ozaki-r in ticket #528):
        sys/net/agr/if_agr.c: revision 1.42
        sys/netinet6/nd6_rtr.c: revision 1.137
        sys/netinet6/nd6_rtr.c: revision 1.138
        sys/net/agr/if_agr.c: revision 1.46
        sys/net/route.c: revision 1.206
        sys/net/if.c: revision 1.419
        sys/net/agr/if_agrether.c: revision 1.10
        sys/netinet6/nd6.c: revision 1.241
        sys/netinet6/nd6.c: revision 1.242
        sys/netinet6/nd6.c: revision 1.243
        sys/netinet6/nd6.c: revision 1.244
        sys/netinet6/nd6.c: revision 1.245
        sys/netipsec/ipsec_input.c: revision 1.52
        sys/netipsec/ipsec_input.c: revision 1.53
        sys/net/agr/if_agrsubr.h: revision 1.5
        sys/kern/subr_workqueue.c: revision 1.35
        sys/netipsec/ipsec.c: revision 1.124
        sys/net/agr/if_agrsubr.c: revision 1.11
        sys/net/agr/if_agrsubr.c: revision 1.12
Simplify; share agr_vlan_add and agr_vlan_del (NFCI)
Fix late NULL-checking (CID 1427782: Null pointer dereferences (REVERSE_INULL))
KNF: replace soft tabs with hard tabs
Add missing NULL-checking for m_pullup (CID 1427770: Null pointer dereferences 
(NULL_RETURNS))
Add locking.
Revert "Get rid of unnecessary splsoftnet" (v1.133)
It's not always true that softnet_lock is held these places.
See PR kern/52947.
Get rid of unnecessary splsoftnet (redo)
Unless NET_MPSAFE, splsoftnet is still needed for rt_* functions.
Use existing fill_[pd]rlist() functions to calculate size of buffer to
allocate, rather than relying on an arbitrary length passed in from
userland.
Allow copyout() of partial results if the user buffer is too small, to
be consistent with the way sysctl(3) is documented.
Garbage-collect now-unused third parrameter in the fill_[pd]rlist()
functions.
As discussed on IRC.
OK kamil@ and christos@
XXX Needs pull-up to netbsd-8 branch.
Simplify, from christos@
More simplification, this time from ozaki-r@
No need to break after return.
One more from christos@
No need to initialize fill_func
more cleanup (don't allow oldlenp == NULL)
Destroy ifq_lock at the end of if_detach
It still can be used in if_detach.
Prevent rt_free_global.wk from being enqueued to workqueue doubly
Check if a queued work is tried to be enqueued again, which is not allowed


To generate a diff of this commit:
cvs rdiff -u -r1.33.30.1 -r1.33.30.2 src/sys/kern/subr_workqueue.c
cvs rdiff -u -r1.394.2.6 -r1.394.2.7 src/sys/net/if.c
cvs rdiff -u -r1.194.6.5 -r1.194.6.6 src/sys/net/route.c
cvs rdiff -u -r1.41.6.1 -r1.41.6.2 src/sys/net/agr/if_agr.c
cvs rdiff -u -r1.9 -r1.9.46.1 src/sys/net/agr/if_agrether.c
cvs rdiff -u -r1.10 -r1.10.10.1 src/sys/net/agr/if_agrsubr.c
cvs rdiff -u -r1.4 -r1.4.124.1 src/sys/net/agr/if_agrsubr.h
cvs rdiff -u -r1.232.2.5 -r1.232.2.6 src/sys/netinet6/nd6.c
cvs rdiff -u -r1.135.6.1 -r1.135.6.2 src/sys/netinet6/nd6_rtr.c
cvs rdiff -u -r1.99.2.2 -r1.99.2.3 src/sys/netipsec/ipsec.c
cvs rdiff -u -r1.43.2.1 -r1.43.2.2 src/sys/netipsec/ipsec_input.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/kern/subr_workqueue.c
diff -u src/sys/kern/subr_workqueue.c:1.33.30.1 src/sys/kern/subr_workqueue.c:1.33.30.2
--- src/sys/kern/subr_workqueue.c:1.33.30.1	Tue Jan 16 13:01:10 2018
+++ src/sys/kern/subr_workqueue.c	Mon Feb  5 14:55:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_workqueue.c,v 1.33.30.1 2018/01/16 13:01:10 martin Exp $	*/
+/*	$NetBSD: subr_workqueue.c,v 1.33.30.2 2018/02/05 14:55:16 martin Exp $	*/
 
 /*-
  * Copyright (c)2002, 2005, 2006, 2007 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.33.30.1 2018/01/16 13:01:10 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_workqueue.c,v 1.33.30.2 2018/02/05 14:55:16 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -354,6 +354,19 @@ workqueue_destroy(struct workqueue *wq)
 	kmem_free(wq->wq_ptr, workqueue_size(wq->wq_flags));
 }
 
+#ifdef DEBUG
+static void
+workqueue_check_duplication(struct workqueue_queue *q, work_impl_t *wk)
+{
+	work_impl_t *_wk;
+
+	SIMPLEQ_FOREACH(_wk, &q->q_queue_pending, wk_entry) {
+		if (_wk == wk)
+			panic("%s: tried to enqueue a queued work", __func__);
+	}
+}
+#endif
+
 void
 workqueue_enqueue(struct workqueue *wq, struct work *wk0, struct cpu_info *ci)
 {
@@ -365,6 +378,9 @@ workqueue_enqueue(struct workqueue *wq, 
 
 	mutex_enter(&q->q_mutex);
 	KASSERT(q->q_waiter == NULL);
+#ifdef DEBUG
+	workqueue_check_duplication(q, wk);
+#endif
 	SIMPLEQ_INSERT_TAIL(&q->q_queue_pending, wk, wk_entry);
 	cv_signal(&q->q_cv);
 	mutex_exit(&q->q_mutex);

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.394.2.6 src/sys/net/if.c:1.394.2.7
--- src/sys/net/if.c:1.394.2.6	Sat Jan 13 05:43:44 2018
+++ src/sys/net/if.c	Mon Feb  5 14:55:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.394.2.6 2018/01/13 05:43:44 snj Exp $	*/
+/*	$NetBSD: if.c,v 1.394.2.7 2018/02/05 14:55:16 martin Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394.2.6 2018/01/13 05:43:44 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394.2.7 2018/02/05 14:55:16 martin Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1336,8 +1336,6 @@ if_detach(struct ifnet *ifp)
 		altq_detach(&ifp->if_snd);
 #endif
 
-	mutex_obj_free(ifp->if_snd.ifq_lock);
-
 #if NCARP > 0
 	/* Remove the interface from any carp group it is a part of.  */
 	if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP)
@@ -1500,6 +1498,7 @@ again:
 
 	mutex_obj_free(ifp->if_ioctl_lock);
 	ifp->if_ioctl_lock = NULL;
+	mutex_obj_free(ifp->if_snd.ifq_lock);
 
 	splx(s);
 

Index: src/sys/net/route.c
diff -u src/sys/net/route.c:1.194.6.5 src/sys/net/route.c:1.194.6.6
--- src/sys/net/route.c:1.194.6.5	Sat Feb  3 22:07:26 2018
+++ src/sys/net/route.c	Mon Feb  5 14:55:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: route.c,v 1.194.6.5 2018/02/03 22:07:26 snj Exp $	*/
+/*	$NetBSD: route.c,v 1.194.6.6 2018/02/05 14:55:16 martin Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.194.6.5 2018/02/03 22:07:26 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.194.6.6 2018/02/05 14:55:16 martin Exp $");
 
 #include <sys/param.h>
 #ifdef RTFLUSH_DEBUG
@@ -256,6 +256,7 @@ static struct {
 	struct work		wk;
 	kmutex_t		lock;
 	SLIST_HEAD(, rtentry)	queue;
+	bool			enqueued;
 } rt_free_global __cacheline_aligned;
 
 /* psref for rtentry */
@@ -459,6 +460,7 @@ rt_init(void)
 
 	mutex_init(&rt_free_global.lock, MUTEX_DEFAULT, IPL_SOFTNET);
 	SLIST_INIT(&rt_free_global.queue);
+	rt_free_global.enqueued = false;
 
 	rt_psref_class = psref_class_create("rtentry", IPL_SOFTNET);
 
@@ -693,6 +695,7 @@ rt_free_work(struct work *wk, void *arg)
 		struct rtentry *rt;
 
 		mutex_enter(&rt_free_global.lock);
+		rt_free_global.enqueued = false;
 		if ((rt = SLIST_FIRST(&rt_free_global.queue)) == NULL) {
 			mutex_exit(&rt_free_global.lock);
 			return;
@@ -718,8 +721,11 @@ rt_free(struct rtentry *rt)
 	mutex_enter(&rt_free_global.lock);
 	rt_ref(rt);
 	SLIST_INSERT_HEAD(&rt_free_global.queue, rt, rt_free);
+	if (!rt_free_global.enqueued) {
+		workqueue_enqueue(rt_free_global.wq, &rt_free_global.wk, NULL);
+		rt_free_global.enqueued = true;
+	}
 	mutex_exit(&rt_free_global.lock);
-	workqueue_enqueue(rt_free_global.wq, &rt_free_global.wk, NULL);
 }
 
 #ifdef NET_MPSAFE

Index: src/sys/net/agr/if_agr.c
diff -u src/sys/net/agr/if_agr.c:1.41.6.1 src/sys/net/agr/if_agr.c:1.41.6.2
--- src/sys/net/agr/if_agr.c:1.41.6.1	Tue Jan  2 10:20:33 2018
+++ src/sys/net/agr/if_agr.c	Mon Feb  5 14:55:15 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_agr.c,v 1.41.6.1 2018/01/02 10:20:33 snj Exp $	*/
+/*	$NetBSD: if_agr.c,v 1.41.6.2 2018/02/05 14:55:15 martin Exp $	*/
 
 /*-
  * Copyright (c)2005 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_agr.c,v 1.41.6.1 2018/01/02 10:20:33 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_agr.c,v 1.41.6.2 2018/02/05 14:55:15 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -254,62 +254,6 @@ agrport_ioctl(struct agr_port *port, u_l
 /*
  * INTERNAL FUNCTIONS
  */
-
-/*
- * Enable vlan hardware assist for the specified port.
- */
-static int
-agr_vlan_add(struct agr_port *port, void *arg)
-{
-	struct ifnet *ifp = port->port_ifp;
-	struct ethercom *ec_port = (void *)ifp;
-	int error=0;
-
-	if (ec_port->ec_nvlans++ == 0 &&
-	    (ec_port->ec_capabilities & ETHERCAP_VLAN_MTU) != 0) {
-		struct ifnet *p = port->port_ifp;
-		/*
-		 * Enable Tx/Rx of VLAN-sized frames.
-		 */
-		ec_port->ec_capenable |= ETHERCAP_VLAN_MTU;
-		if (p->if_flags & IFF_UP) {
-			error = if_flags_set(p, p->if_flags);
-			if (error) {
-				if (ec_port->ec_nvlans-- == 1)
-					ec_port->ec_capenable &=
-					    ~ETHERCAP_VLAN_MTU;
-				return (error);
-			}
-		}
-	}
-
-	return error;
-}
-
-/*
- * Disable vlan hardware assist for the specified port.
- */
-static int
-agr_vlan_del(struct agr_port *port, void *arg)
-{
-	struct ethercom *ec_port = (void *)port->port_ifp;
-
-	/* Disable vlan support */
-	if (ec_port->ec_nvlans-- == 1) {
-		/*
-		 * Disable Tx/Rx of VLAN-sized frames.
-		 */
-		ec_port->ec_capenable &= ~ETHERCAP_VLAN_MTU;
-		if (port->port_ifp->if_flags & IFF_UP) {
-			(void)if_flags_set(port->port_ifp,
-			    port->port_ifp->if_flags);
-		}
-	}
-
-	return 0;
-}
-
-
 /*
  * Check for vlan attach/detach.
  * ec->ec_nvlans is directly modified by the vlan driver.
@@ -332,8 +276,9 @@ agr_vlan_check(struct ifnet *ifp, struct
 		agr_port_foreach(sc, agr_vlan_add, NULL);
 		sc->sc_nvlans = ec->ec_nvlans;
 	} else if (ec->ec_nvlans == 0) {
+		bool force_zero = false;
 		/* vlan removed */
-		agr_port_foreach(sc, agr_vlan_del, NULL);
+		agr_port_foreach(sc, agr_vlan_del, &force_zero);
 		sc->sc_nvlans = 0;
 	}
 }
@@ -673,7 +618,9 @@ agr_addport(struct ifnet *ifp, struct if
 	 * of each port to that of the first port. No need for arps 
 	 * since there are no inet addresses assigned to the ports.
 	 */
+	IFNET_LOCK(ifp_port);
 	error = if_addr_init(ifp_port, ifp->if_dl, true);
+	IFNET_UNLOCK(ifp_port);
 
 	if (error) {
 		printf("%s: if_addr_init error %d\n", __func__, error);

Index: src/sys/net/agr/if_agrether.c
diff -u src/sys/net/agr/if_agrether.c:1.9 src/sys/net/agr/if_agrether.c:1.9.46.1
--- src/sys/net/agr/if_agrether.c:1.9	Wed Oct 19 01:49:50 2011
+++ src/sys/net/agr/if_agrether.c	Mon Feb  5 14:55:15 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_agrether.c,v 1.9 2011/10/19 01:49:50 dyoung Exp $	*/
+/*	$NetBSD: if_agrether.c,v 1.9.46.1 2018/02/05 14:55:15 martin Exp $	*/
 
 /*-
  * Copyright (c)2005 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_agrether.c,v 1.9 2011/10/19 01:49:50 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_agrether.c,v 1.9.46.1 2018/02/05 14:55:15 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/callout.h>
@@ -166,23 +166,10 @@ agrether_portinit(struct agr_softc *sc, 
 	}
 
 	/* Enable vlan support */
-	if ((ec->ec_nvlans > 0) && 
-	     ec_port->ec_nvlans++ == 0 &&
-	    (ec_port->ec_capabilities & ETHERCAP_VLAN_MTU) != 0) {
-		struct ifnet *p = port->port_ifp;
-		/*
-		 * Enable Tx/Rx of VLAN-sized frames.
-		 */
-		ec_port->ec_capenable |= ETHERCAP_VLAN_MTU;
-		if (p->if_flags & IFF_UP) {
-			error = if_flags_set(p, p->if_flags);
-			if (error) {
-				if (ec_port->ec_nvlans-- == 1)
-					ec_port->ec_capenable &=
-					    ~ETHERCAP_VLAN_MTU;
-				return (error);
-			}
-		}
+	if (ec->ec_nvlans > 0) {
+		error = agr_vlan_add(port, NULL);
+		if (error != 0)
+			return error;
 	}
 	/* XXX ETHERCAP_JUMBO_MTU */
 
@@ -225,16 +212,9 @@ agrether_portfini(struct agr_softc *sc, 
 	}
 
 	if (ec_port->ec_nvlans > 0) {
+		bool force = true;
 		/* Disable vlan support */
-		ec_port->ec_nvlans = 0;
-		/*
-		 * Disable Tx/Rx of VLAN-sized frames.
-		 */
-		ec_port->ec_capenable &= ~ETHERCAP_VLAN_MTU;
-		if (port->port_ifp->if_flags & IFF_UP) {
-			(void)if_flags_set(port->port_ifp,
-			    port->port_ifp->if_flags);
-		}
+		agr_vlan_del(port, &force);
 	}
 
 	memset(&ifr, 0, sizeof(ifr));

Index: src/sys/net/agr/if_agrsubr.c
diff -u src/sys/net/agr/if_agrsubr.c:1.10 src/sys/net/agr/if_agrsubr.c:1.10.10.1
--- src/sys/net/agr/if_agrsubr.c:1.10	Mon Aug 24 22:21:26 2015
+++ src/sys/net/agr/if_agrsubr.c	Mon Feb  5 14:55:15 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_agrsubr.c,v 1.10 2015/08/24 22:21:26 pooka Exp $	*/
+/*	$NetBSD: if_agrsubr.c,v 1.10.10.1 2018/02/05 14:55:15 martin Exp $	*/
 
 /*-
  * Copyright (c)2005 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_agrsubr.c,v 1.10 2015/08/24 22:21:26 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_agrsubr.c,v 1.10.10.1 2018/02/05 14:55:15 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_agrsubr.c
 #include <sys/sockio.h>
 
 #include <net/if.h>
+#include <net/if_ether.h>
 
 #include <net/agr/if_agrvar_impl.h>
 #include <net/agr/if_agrsubr.h>
@@ -272,3 +273,69 @@ agr_port_getmedia(struct agr_port *port,
 
 	return error;
 }
+
+/* ==================== */
+
+/*
+ * Enable vlan hardware assist for the specified port.
+ */
+int
+agr_vlan_add(struct agr_port *port, void *arg)
+{
+	struct ifnet *ifp = port->port_ifp;
+	struct ethercom *ec_port = (void *)ifp;
+	int error=0;
+
+	if (ec_port->ec_nvlans++ == 0 &&
+	    (ec_port->ec_capabilities & ETHERCAP_VLAN_MTU) != 0) {
+		struct ifnet *p = port->port_ifp;
+		/*
+		 * Enable Tx/Rx of VLAN-sized frames.
+		 */
+		ec_port->ec_capenable |= ETHERCAP_VLAN_MTU;
+		if (p->if_flags & IFF_UP) {
+			IFNET_LOCK(p);
+			error = if_flags_set(p, p->if_flags);
+			IFNET_UNLOCK(p);
+			if (error) {
+				if (ec_port->ec_nvlans-- == 1)
+					ec_port->ec_capenable &=
+					    ~ETHERCAP_VLAN_MTU;
+				return (error);
+			}
+		}
+	}
+
+	return error;
+}
+
+/*
+ * Disable vlan hardware assist for the specified port.
+ */
+int
+agr_vlan_del(struct agr_port *port, void *arg)
+{
+	struct ethercom *ec_port = (void *)port->port_ifp;
+	bool *force_zero = (bool *)arg;
+
+	KASSERT(force_zero != NULL);
+
+	/* Disable vlan support */
+	if ((*force_zero && ec_port->ec_nvlans > 0) ||
+	    ec_port->ec_nvlans-- == 1) {
+		struct ifnet *p = port->port_ifp;
+		if (*force_zero)
+			ec_port->ec_nvlans = 0;
+		/*
+		 * Disable Tx/Rx of VLAN-sized frames.
+		 */
+		ec_port->ec_capenable &= ~ETHERCAP_VLAN_MTU;
+		if (p->if_flags & IFF_UP) {
+			IFNET_LOCK(p);
+			(void)if_flags_set(p, p->if_flags);
+			IFNET_UNLOCK(p);
+		}
+	}
+
+	return 0;
+}

Index: src/sys/net/agr/if_agrsubr.h
diff -u src/sys/net/agr/if_agrsubr.h:1.4 src/sys/net/agr/if_agrsubr.h:1.4.124.1
--- src/sys/net/agr/if_agrsubr.h:1.4	Wed Feb 21 23:00:07 2007
+++ src/sys/net/agr/if_agrsubr.h	Mon Feb  5 14:55:15 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_agrsubr.h,v 1.4 2007/02/21 23:00:07 thorpej Exp $	*/
+/*	$NetBSD: if_agrsubr.h,v 1.4.124.1 2018/02/05 14:55:15 martin Exp $	*/
 
 /*-
  * Copyright (c)2005 YAMAMOTO Takashi,
@@ -51,4 +51,7 @@ int agr_configmulti_ifreq(struct agr_sof
 
 int agr_port_getmedia(struct agr_port *, u_int *, u_int *);
 
+int agr_vlan_add(struct agr_port *, void *);
+int agr_vlan_del(struct agr_port *, void *);
+
 #endif /* !_NET_AGR_IF_AGRSUBR_H_ */

Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.232.2.5 src/sys/netinet6/nd6.c:1.232.2.6
--- src/sys/netinet6/nd6.c:1.232.2.5	Tue Jan  2 10:20:34 2018
+++ src/sys/netinet6/nd6.c	Mon Feb  5 14:55:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.232.2.5 2018/01/02 10:20:34 snj Exp $	*/
+/*	$NetBSD: nd6.c,v 1.232.2.6 2018/02/05 14:55:16 martin Exp $	*/
 /*	$KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.232.2.5 2018/01/02 10:20:34 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.232.2.6 2018/02/05 14:55:16 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -124,8 +124,8 @@ static callout_t nd6_timer_ch;
 static struct workqueue	*nd6_timer_wq;
 static struct work	nd6_timer_wk;
 
-static int fill_drlist(void *, size_t *, size_t);
-static int fill_prlist(void *, size_t *, size_t);
+static int fill_drlist(void *, size_t *);
+static int fill_prlist(void *, size_t *);
 
 static struct ifnet *nd6_defifp;
 static int nd6_defifindex;
@@ -2487,52 +2487,55 @@ nd6_sysctl(
     size_t newlen
 )
 {
-	void *p;
-	size_t ol;
-	int error;
-	size_t bufsize = 0;
-
-	error = 0;
+	int (*fill_func)(void *, size_t *);
 
 	if (newp)
 		return EPERM;
-	if (oldp && !oldlenp)
-		return EINVAL;
-	ol = oldlenp ? *oldlenp : 0;
 
-	if (oldp && *oldlenp > 0) {
-		p = kmem_alloc(*oldlenp, KM_SLEEP);
-		bufsize = *oldlenp;
-	} else
-		p = NULL;
 	switch (name) {
 	case ICMPV6CTL_ND6_DRLIST:
-		error = fill_drlist(p, oldlenp, ol);
-		if (!error && p != NULL && oldp != NULL)
-			error = copyout(p, oldp, *oldlenp);
+		fill_func = fill_drlist;
 		break;
 
 	case ICMPV6CTL_ND6_PRLIST:
-		error = fill_prlist(p, oldlenp, ol);
-		if (!error && p != NULL && oldp != NULL)
-			error = copyout(p, oldp, *oldlenp);
+		fill_func = fill_prlist;
 		break;
 
 	case ICMPV6CTL_ND6_MAXQLEN:
-		break;
+		return 0;
 
 	default:
-		error = ENOPROTOOPT;
-		break;
+		return ENOPROTOOPT;
 	}
-	if (p)
-		kmem_free(p, bufsize);
+
+	if (oldlenp == NULL)
+		return EINVAL;
+
+	size_t ol;
+	int error = (*fill_func)(NULL, &ol);	/* calc len needed */
+	if (error)
+		return error;
+
+	if (oldp == NULL) {
+		*oldlenp = ol;
+		return 0;
+	}
+
+	ol = *oldlenp = min(ol, *oldlenp);
+	if (ol == 0)
+		return 0;
+
+	void *p = kmem_alloc(ol, KM_SLEEP);
+	error = (*fill_func)(p, oldlenp);
+	if (!error)
+		error = copyout(p, oldp, *oldlenp);
+	kmem_free(p, ol);
 
 	return error;
 }
 
 static int
-fill_drlist(void *oldp, size_t *oldlenp, size_t ol)
+fill_drlist(void *oldp, size_t *oldlenp)
 {
 	int error = 0;
 	struct in6_defrouter *d = NULL, *de = NULL;
@@ -2571,18 +2574,13 @@ fill_drlist(void *oldp, size_t *oldlenp,
 	}
 	ND6_UNLOCK();
 
-	if (oldp) {
-		if (l > ol)
-			error = ENOMEM;
-	}
-	if (oldlenp)
-		*oldlenp = l;	/* (void *)d - (void *)oldp */
+	*oldlenp = l;	/* (void *)d - (void *)oldp */
 
 	return error;
 }
 
 static int
-fill_prlist(void *oldp, size_t *oldlenp, size_t ol)
+fill_prlist(void *oldp, size_t *oldlenp)
 {
 	int error = 0;
 	struct nd_prefix *pr;
@@ -2678,12 +2676,7 @@ fill_prlist(void *oldp, size_t *oldlenp,
 	}
 	ND6_UNLOCK();
 
-	if (oldp) {
-		*oldlenp = l;	/* (void *)d - (void *)oldp */
-		if (l > ol)
-			error = ENOMEM;
-	} else
-		*oldlenp = l;
+	*oldlenp = l;
 
 	return error;
 }

Index: src/sys/netinet6/nd6_rtr.c
diff -u src/sys/netinet6/nd6_rtr.c:1.135.6.1 src/sys/netinet6/nd6_rtr.c:1.135.6.2
--- src/sys/netinet6/nd6_rtr.c:1.135.6.1	Tue Jan  2 10:20:34 2018
+++ src/sys/netinet6/nd6_rtr.c	Mon Feb  5 14:55:15 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_rtr.c,v 1.135.6.1 2018/01/02 10:20:34 snj Exp $	*/
+/*	$NetBSD: nd6_rtr.c,v 1.135.6.2 2018/02/05 14:55:15 martin Exp $	*/
 /*	$KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.135.6.1 2018/01/02 10:20:34 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.135.6.2 2018/02/05 14:55:15 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -469,6 +469,9 @@ defrouter_addreq(struct nd_defrouter *ne
 		struct sockaddr_in6 sin6;
 		struct sockaddr sa;
 	} def, mask, gate;
+#ifndef NET_MPSAFE
+	int s;
+#endif
 	int error;
 
 	memset(&def, 0, sizeof(def));
@@ -484,7 +487,7 @@ defrouter_addreq(struct nd_defrouter *ne
 #endif
 
 #ifndef NET_MPSAFE
-	KASSERT(mutex_owned(softnet_lock));
+	s = splsoftnet();
 #endif
 	error = rtrequest_newmsg(RTM_ADD, &def.sa, &gate.sa, &mask.sa,
 	    RTF_GATEWAY);
@@ -492,6 +495,9 @@ defrouter_addreq(struct nd_defrouter *ne
 		nd6_numroutes++;
 		newdr->installed = 1;
 	}
+#ifndef NET_MPSAFE
+	splx(s);
+#endif
 	return;
 }
 
@@ -2218,16 +2224,21 @@ in6_init_address_ltimes(struct nd_prefix
 void
 nd6_rt_flush(struct in6_addr *gateway, struct ifnet *ifp)
 {
-
 #ifndef NET_MPSAFE
-	KASSERT(mutex_owned(softnet_lock));
+	int s = splsoftnet();
 #endif
 
 	/* We'll care only link-local addresses */
 	if (!IN6_IS_ADDR_LINKLOCAL(gateway))
-		return;
+		goto out;
 
 	rt_delete_matched_entries(AF_INET6, rt6_deleteroute_matcher, gateway);
+
+out:
+#ifndef NET_MPSAFE
+	splx(s);
+#endif
+	return; /* XXX gcc */
 }
 
 static int

Index: src/sys/netipsec/ipsec.c
diff -u src/sys/netipsec/ipsec.c:1.99.2.2 src/sys/netipsec/ipsec.c:1.99.2.3
--- src/sys/netipsec/ipsec.c:1.99.2.2	Thu Nov 30 14:57:34 2017
+++ src/sys/netipsec/ipsec.c	Mon Feb  5 14:55:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec.c,v 1.99.2.2 2017/11/30 14:57:34 martin Exp $	*/
+/*	$NetBSD: ipsec.c,v 1.99.2.3 2018/02/05 14:55:16 martin Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $	*/
 /*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.99.2.2 2017/11/30 14:57:34 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.99.2.3 2018/02/05 14:55:16 martin Exp $");
 
 /*
  * IPsec controller part.
@@ -1444,11 +1444,10 @@ ipsec4_set_policy(struct inpcb *inp, int
 	struct secpolicy **policy;
 
 	KASSERT(!cpu_softintr_p());
+	KASSERT(inp != NULL);
 	KASSERT(inp_locked(inp));
+	KASSERT(request != NULL);
 
-	/* sanity check. */
-	if (inp == NULL || request == NULL)
-		return EINVAL;
 	if (len < sizeof(*xpl))
 		return EINVAL;
 	xpl = (const struct sadb_x_policy *)request;

Index: src/sys/netipsec/ipsec_input.c
diff -u src/sys/netipsec/ipsec_input.c:1.43.2.1 src/sys/netipsec/ipsec_input.c:1.43.2.2
--- src/sys/netipsec/ipsec_input.c:1.43.2.1	Sat Oct 21 19:43:54 2017
+++ src/sys/netipsec/ipsec_input.c	Mon Feb  5 14:55:16 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipsec_input.c,v 1.43.2.1 2017/10/21 19:43:54 snj Exp $	*/
+/*	$NetBSD: ipsec_input.c,v 1.43.2.2 2018/02/05 14:55:16 martin Exp $	*/
 /*	$FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $	*/
 /*	$OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $	*/
 
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.43.2.1 2017/10/21 19:43:54 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsec_input.c,v 1.43.2.2 2018/02/05 14:55:16 martin Exp $");
 
 /*
  * IPsec input processing.
@@ -127,49 +127,52 @@ do {									\
 static struct mbuf *
 ipsec4_fixup_checksum(struct mbuf *m)
 {
-       struct ip *ip;
-       struct tcphdr *th;
-       struct udphdr *uh;
-       int poff, off;
-       int plen;
-
-       if (m->m_len < sizeof(*ip))
-               m = m_pullup(m, sizeof(*ip));
-       ip = mtod(m, struct ip *); 
-       poff = ip->ip_hl << 2;
-       plen = ntohs(ip->ip_len) - poff;
-
-       switch (ip->ip_p) {
-       case IPPROTO_TCP:
-               IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
-               if (th == NULL)
-                       return NULL;
-               off = th->th_off << 2;
-               if (off < sizeof(*th) || off > plen) {
-                       m_freem(m);
-                       return NULL;
-               }
-               th->th_sum = 0;
-               th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
-               break;
-       case IPPROTO_UDP:
-               IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
-               if (uh == NULL)
-                       return NULL;
-               off = sizeof(*uh); 
-               if (off > plen) {  
-                       m_freem(m);
-                       return NULL;
-               }
-               uh->uh_sum = 0;
-               uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
-               break;
-       default:
-               /* no checksum */  
-               return m;
-       }
+	struct ip *ip;
+	struct tcphdr *th;
+	struct udphdr *uh;
+	int poff, off;
+	int plen;
+
+	if (m->m_len < sizeof(*ip)) {
+		m = m_pullup(m, sizeof(*ip));
+		if (m == NULL)
+			return NULL;
+	}
+	ip = mtod(m, struct ip *); 
+	poff = ip->ip_hl << 2;
+	plen = ntohs(ip->ip_len) - poff;
+
+	switch (ip->ip_p) {
+	case IPPROTO_TCP:
+		IP6_EXTHDR_GET(th, struct tcphdr *, m, poff, sizeof(*th));
+		if (th == NULL)
+			return NULL;
+		off = th->th_off << 2;
+		if (off < sizeof(*th) || off > plen) {
+			m_freem(m);
+			return NULL;
+		}
+		th->th_sum = 0;
+		th->th_sum = in4_cksum(m, IPPROTO_TCP, poff, plen);
+		break;
+	case IPPROTO_UDP:
+		IP6_EXTHDR_GET(uh, struct udphdr *, m, poff, sizeof(*uh));
+		if (uh == NULL)
+			return NULL;
+		off = sizeof(*uh); 
+		if (off > plen) {  
+			m_freem(m);
+			return NULL;
+		}
+		uh->uh_sum = 0;
+		uh->uh_sum = in4_cksum(m, IPPROTO_UDP, poff, plen);
+		break;
+	default:
+		/* no checksum */  
+		return m;
+	}
 
-       return m;
+	return m;
 }
 
 /*

Reply via email to