Module Name:    src
Committed By:   knakahara
Date:           Mon Jul  4 04:35:09 UTC 2016

Modified Files:
        src/sys/net: if.c if_gif.c if_stf.c
        src/sys/netinet: ip_encap.c ip_encap.h ip_mroute.c
        src/sys/netipsec: xform_ipip.c

Log Message:
make encap_lock_{enter,exit} interruptable.


To generate a diff of this commit:
cvs rdiff -u -r1.351 -r1.352 src/sys/net/if.c
cvs rdiff -u -r1.116 -r1.117 src/sys/net/if_gif.c
cvs rdiff -u -r1.92 -r1.93 src/sys/net/if_stf.c
cvs rdiff -u -r1.58 -r1.59 src/sys/netinet/ip_encap.c
cvs rdiff -u -r1.21 -r1.22 src/sys/netinet/ip_encap.h
cvs rdiff -u -r1.142 -r1.143 src/sys/netinet/ip_mroute.c
cvs rdiff -u -r1.40 -r1.41 src/sys/netipsec/xform_ipip.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/net/if.c
diff -u src/sys/net/if.c:1.351 src/sys/net/if.c:1.352
--- src/sys/net/if.c:1.351	Mon Jul  4 01:36:06 2016
+++ src/sys/net/if.c	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.351 2016/07/04 01:36:06 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.352 2016/07/04 04:35:09 knakahara Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,10 +90,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.351 2016/07/04 01:36:06 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.352 2016/07/04 04:35:09 knakahara Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
+#include "opt_ipsec.h"
 
 #include "opt_atalk.h"
 #include "opt_natm.h"
@@ -137,6 +138,9 @@ __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.351
 #include <net/pfil.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#ifndef IPSEC
+#include <netinet/ip_encap.h>
+#endif
 
 #ifdef INET6
 #include <netinet6/in6_var.h>
@@ -258,6 +262,10 @@ ifinit(void)
 		sysctl_net_pktq_setup(NULL, PF_INET6);
 #endif
 
+#ifndef IPSEC
+	encapinit();
+#endif
+
 	if_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
 	    if_listener_cb, NULL);
 

Index: src/sys/net/if_gif.c
diff -u src/sys/net/if_gif.c:1.116 src/sys/net/if_gif.c:1.117
--- src/sys/net/if_gif.c:1.116	Mon Jul  4 04:22:47 2016
+++ src/sys/net/if_gif.c	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_gif.c,v 1.116 2016/07/04 04:22:47 knakahara Exp $	*/
+/*	$NetBSD: if_gif.c,v 1.117 2016/07/04 04:35:09 knakahara Exp $	*/
 /*	$KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.116 2016/07/04 04:22:47 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.117 2016/07/04 04:35:09 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -829,7 +829,11 @@ gif_set_tunnel(struct ifnet *ifp, struct
 	int error;
 
 	s = splsoftnet();
-	encap_lock_enter();
+	error = encap_lock_enter();
+	if (error) {
+		splx(s);
+		return error;
+	}
 
 	LIST_FOREACH(sc2, &gif_softc_list, gif_list) {
 		if (sc2 == sc)
@@ -916,9 +920,14 @@ gif_delete_tunnel(struct ifnet *ifp)
 {
 	struct gif_softc *sc = ifp->if_softc;
 	int s;
+	int error;
 
 	s = splsoftnet();
-	encap_lock_enter();
+	error = encap_lock_enter();
+	if (error) {
+		splx(s);
+		return;
+	}
 
 	gif_encap_pause(sc);
 	if (sc->gif_psrc) {

Index: src/sys/net/if_stf.c
diff -u src/sys/net/if_stf.c:1.92 src/sys/net/if_stf.c:1.93
--- src/sys/net/if_stf.c:1.92	Mon Jul  4 04:17:25 2016
+++ src/sys/net/if_stf.c	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_stf.c,v 1.92 2016/07/04 04:17:25 knakahara Exp $	*/
+/*	$NetBSD: if_stf.c,v 1.93 2016/07/04 04:35:09 knakahara Exp $	*/
 /*	$KAME: if_stf.c,v 1.62 2001/06/07 22:32:16 itojun Exp $ */
 
 /*
@@ -75,7 +75,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_stf.c,v 1.92 2016/07/04 04:17:25 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_stf.c,v 1.93 2016/07/04 04:35:09 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -190,11 +190,17 @@ static int
 stf_clone_create(struct if_clone *ifc, int unit)
 {
 	struct stf_softc *sc;
+	int error;
 
 	sc = malloc(sizeof(struct stf_softc), M_DEVBUF, M_WAIT|M_ZERO);
 	if_initname(&sc->sc_if, ifc->ifc_name, unit);
 
-	encap_lock_enter();
+	error = encap_lock_enter();
+	if (error) {
+		free(sc, M_DEVBUF);
+		return error;
+	}
+
 	if (LIST_FIRST(&stf_softc_list) != NULL) {
 		/* Only one stf interface is allowed. */
 		encap_lock_exit();

Index: src/sys/netinet/ip_encap.c
diff -u src/sys/netinet/ip_encap.c:1.58 src/sys/netinet/ip_encap.c:1.59
--- src/sys/netinet/ip_encap.c:1.58	Mon Jul  4 04:32:55 2016
+++ src/sys/netinet/ip_encap.c	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_encap.c,v 1.58 2016/07/04 04:32:55 knakahara Exp $	*/
+/*	$NetBSD: ip_encap.c,v 1.59 2016/07/04 04:35:09 knakahara Exp $	*/
 /*	$KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $	*/
 
 /*
@@ -68,7 +68,7 @@
 #define USE_RADIX
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.58 2016/07/04 04:32:55 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.59 2016/07/04 04:35:09 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mrouting.h"
@@ -85,6 +85,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v
 #include <sys/kmem.h>
 #include <sys/once.h>
 #include <sys/mutex.h>
+#include <sys/condvar.h>
 #include <sys/psref.h>
 #include <sys/pslist.h>
 
@@ -145,6 +146,12 @@ static struct {
 };
 #define encap_table encaptab.list
 
+static struct {
+	kmutex_t	lock;
+	kcondvar_t	cv;
+	struct lwp	*busy;
+} encap_whole __cacheline_aligned;
+
 #ifdef USE_RADIX
 struct radix_node_head *encap_head[2];	/* 0 for AF_INET, 1 for AF_INET6 */
 static bool encap_head_updating = false;
@@ -154,6 +161,18 @@ static ONCE_DECL(encap_init_control);
 
 static int encap_init_once(void);
 
+/*
+ * must be done before other encap interfaces initialization.
+ */
+void
+encapinit(void)
+{
+
+	mutex_init(&encap_whole.lock, MUTEX_DEFAULT, IPL_NONE);
+	cv_init(&encap_whole.cv, "ip_encap cv");
+	encap_whole.busy = NULL;
+}
+
 void
 encap_init(void)
 {
@@ -1081,32 +1100,40 @@ encap_getarg(struct mbuf *m)
 	return p;
 }
 
-void
+int
 encap_lock_enter(void)
 {
+	int error;
 
-	/* XXX future work
-	 * change interruptable lock.
-	 */
-	KERNEL_LOCK(1, NULL);
+	mutex_enter(&encap_whole.lock);
+	while (encap_whole.busy != NULL) {
+		error = cv_wait_sig(&encap_whole.cv, &encap_whole.lock);
+		if (error) {
+			mutex_exit(&encap_whole.lock);
+			return error;
+		}
+	}
+	KASSERT(encap_whole.busy == NULL);
+	encap_whole.busy = curlwp;
+	mutex_exit(&encap_whole.lock);
+
+	return 0;
 }
 
 void
 encap_lock_exit(void)
 {
 
-	/* XXX future work
-	 * change interruptable lock
-	 */
-	KERNEL_UNLOCK_ONE(NULL);
+	mutex_enter(&encap_whole.lock);
+	KASSERT(encap_whole.busy == curlwp);
+	encap_whole.busy = NULL;
+	cv_broadcast(&encap_whole.cv);
+	mutex_exit(&encap_whole.lock);
 }
 
 bool
 encap_lock_held(void)
 {
 
-	/* XXX future work
-	 * should change interruptable lock.
-	 */
-	return KERNEL_LOCKED_P();
+	return (encap_whole.busy == curlwp);
 }

Index: src/sys/netinet/ip_encap.h
diff -u src/sys/netinet/ip_encap.h:1.21 src/sys/netinet/ip_encap.h:1.22
--- src/sys/netinet/ip_encap.h:1.21	Mon Jul  4 04:29:11 2016
+++ src/sys/netinet/ip_encap.h	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_encap.h,v 1.21 2016/07/04 04:29:11 knakahara Exp $	*/
+/*	$NetBSD: ip_encap.h,v 1.22 2016/07/04 04:35:09 knakahara Exp $	*/
 /*	$KAME: ip_encap.h,v 1.7 2000/03/25 07:23:37 sumikawa Exp $	*/
 
 /*
@@ -97,6 +97,8 @@ struct ip_pack6 {
 	struct sockaddr_in6 yours;
 };
 
+void	encapinit(void);
+
 void	encap_init(void);
 void	encap4_input(struct mbuf *, ...);
 int	encap6_input(struct mbuf **, int *, int);
@@ -110,7 +112,7 @@ void	*encap6_ctlinput(int, const struct 
 int	encap_detach(const struct encaptab *);
 void	*encap_getarg(struct mbuf *);
 
-void	encap_lock_enter(void);
+int	encap_lock_enter(void);
 void	encap_lock_exit(void);
 bool	encap_lock_held(void);
 

Index: src/sys/netinet/ip_mroute.c
diff -u src/sys/netinet/ip_mroute.c:1.142 src/sys/netinet/ip_mroute.c:1.143
--- src/sys/netinet/ip_mroute.c:1.142	Mon Jul  4 04:17:25 2016
+++ src/sys/netinet/ip_mroute.c	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_mroute.c,v 1.142 2016/07/04 04:17:25 knakahara Exp $	*/
+/*	$NetBSD: ip_mroute.c,v 1.143 2016/07/04 04:35:09 knakahara Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.142 2016/07/04 04:17:25 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.143 2016/07/04 04:35:09 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -832,7 +832,9 @@ add_vif(struct vifctl *vifcp)
 		 * this requires both radix tree lookup and then a
 		 * function to check, and this is not supported yet.
 		 */
-		encap_lock_enter();
+		error = encap_lock_enter();
+		if (error)
+			return error;
 		vifp->v_encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV4,
 		    vif_encapcheck, &vif_encapsw, vifp);
 		encap_lock_exit();

Index: src/sys/netipsec/xform_ipip.c
diff -u src/sys/netipsec/xform_ipip.c:1.40 src/sys/netipsec/xform_ipip.c:1.41
--- src/sys/netipsec/xform_ipip.c:1.40	Mon Jul  4 04:17:25 2016
+++ src/sys/netipsec/xform_ipip.c	Mon Jul  4 04:35:09 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ipip.c,v 1.40 2016/07/04 04:17:25 knakahara Exp $	*/
+/*	$NetBSD: xform_ipip.c,v 1.41 2016/07/04 04:35:09 knakahara Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
 
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.40 2016/07/04 04:17:25 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.41 2016/07/04 04:35:09 knakahara Exp $");
 
 /*
  * IP-inside-IP processing
@@ -725,7 +725,10 @@ ipe4_attach(void)
 	xform_register(&ipe4_xformsw);
 	/* attach to encapsulation framework */
 	/* XXX save return cookie for detach on module remove */
-	encap_lock_enter();
+
+	encapinit();
+	/* This function is called before ifinit(). Who else gets lock? */
+	(void)encap_lock_enter();
 	/* ipe4_encapsw and ipe4_encapsw must be added atomically */
 #ifdef INET
 	(void) encap_attach_func(AF_INET, -1,

Reply via email to