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