Module Name:    src
Committed By:   msaitoh
Date:           Mon Oct 23 09:21:20 UTC 2017

Modified Files:
        src/sys/net: if.c if.h

Log Message:
 if_initalize() and if_attach() failed when resource allocation failed
(e.g. allocating softint). Without this change, it panics. It's bad because
resource shortage really occured when a lot of pseudo interface is created.
To avoid this problem, don't panic and change return value of if_initialize()
and if_attach() to int. Caller fanction will be recover from error cleanly by
checking the return value.


To generate a diff of this commit:
cvs rdiff -u -r1.395 -r1.396 src/sys/net/if.c
cvs rdiff -u -r1.240 -r1.241 src/sys/net/if.h

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.395 src/sys/net/if.c:1.396
--- src/sys/net/if.c:1.395	Tue Jun 27 12:17:27 2017
+++ src/sys/net/if.c	Mon Oct 23 09:21:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.395 2017/06/27 12:17:27 roy Exp $	*/
+/*	$NetBSD: if.c,v 1.396 2017/10/23 09:21:20 msaitoh 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.395 2017/06/27 12:17:27 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.396 2017/10/23 09:21:20 msaitoh Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -670,9 +670,11 @@ skip:
  *     ether_ifattach(ifp, enaddr);
  *     if_register(ifp);
  */
-void
+int
 if_initialize(ifnet_t *ifp)
 {
+	int rv = 0;
+
 	KASSERT(if_indexlim > 0);
 	TAILQ_INIT(&ifp->if_addrlist);
 
@@ -711,8 +713,10 @@ if_initialize(ifnet_t *ifp)
 	if (if_is_link_state_changeable(ifp)) {
 		ifp->if_link_si = softint_establish(SOFTINT_NET,
 		    if_link_state_change_si, ifp);
-		if (ifp->if_link_si == NULL)
-			panic("%s: softint_establish() failed", __func__);
+		if (ifp->if_link_si == NULL) {
+			rv = ENOMEM;
+			goto fail;
+		}
 	}
 
 	PSLIST_ENTRY_INIT(ifp, if_pslist_entry);
@@ -724,6 +728,18 @@ if_initialize(ifnet_t *ifp)
 	IFNET_LOCK();
 	if_getindex(ifp);
 	IFNET_UNLOCK();
+
+	return 0;
+
+fail:
+	IF_AFDATA_LOCK_DESTROY(ifp);
+
+	pfil_run_ifhooks(if_pfil, PFIL_IFNET_DETACH, ifp);
+	(void)pfil_head_destroy(ifp->if_pfil);
+
+	IFQ_LOCK_DESTROY(&ifp->if_snd);
+
+	return rv;
 }
 
 /*
@@ -1094,13 +1110,19 @@ if_input(struct ifnet *ifp, struct mbuf 
  * migrate softint-based if_input without much changes. If you don't
  * want to enable it, use if_initialize instead.
  */
-void
+int
 if_attach(ifnet_t *ifp)
 {
+	int rv;
+
+	rv = if_initialize(ifp);
+	if (rv != 0)
+		return rv;
 
-	if_initialize(ifp);
 	ifp->if_percpuq = if_percpuq_create(ifp);
 	if_register(ifp);
+
+	return 0;
 }
 
 void

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.240 src/sys/net/if.h:1.241
--- src/sys/net/if.h:1.240	Tue Jun 27 12:17:27 2017
+++ src/sys/net/if.h	Mon Oct 23 09:21:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.240 2017/06/27 12:17:27 roy Exp $	*/
+/*	$NetBSD: if.h,v 1.241 2017/10/23 09:21:20 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -923,6 +923,7 @@ do {									\
 
 #define IFQ_LOCK_INIT(ifq)	(ifq)->ifq_lock =			\
 	    mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET)
+#define IFQ_LOCK_DESTROY(ifq)	mutex_obj_free((ifq)->ifq_lock)
 #define IFQ_LOCK(ifq)		mutex_enter((ifq)->ifq_lock)
 #define IFQ_UNLOCK(ifq)		mutex_exit((ifq)->ifq_lock)
 
@@ -946,9 +947,9 @@ void if_activate_sadl(struct ifnet *, st
     const struct sockaddr_dl *);
 void	if_set_sadl(struct ifnet *, const void *, u_char, bool);
 void	if_alloc_sadl(struct ifnet *);
-void	if_initialize(struct ifnet *);
+int	if_initialize(struct ifnet *);
 void	if_register(struct ifnet *);
-void	if_attach(struct ifnet *); /* Deprecated. Use if_initialize and if_register */
+int	if_attach(struct ifnet *); /* Deprecated. Use if_initialize and if_register */
 void	if_attachdomain(void);
 void	if_deactivate(struct ifnet *);
 bool	if_is_deactivated(const struct ifnet *);

Reply via email to