Module Name: src Committed By: martin Date: Tue May 15 13:48:37 UTC 2018
Modified Files: src/sys/net [netbsd-8]: bpf.c if.c if_bridge.c Log Message: Pull up following revision(s) (requested by ozaki-r in ticket #826): sys/net/if_bridge.c: revision 1.155 sys/net/if.c: revision 1.421 sys/net/bpf.c: revision 1.224 sys/net/if.c: revision 1.422 sys/net/if.c: revision 1.423 Use if_is_mpsafe (NFC) Protect packet input routines with KERNEL_LOCK and splsoftnet if_input, i.e, ether_input and friends, now runs in softint without any protections. It's ok for ether_input itself because it's already MP-safe, however, subsequent routines called from it such as carp_input and agr_input aren't safe because they're not MP-safe. Protect if_input with KERNEL_LOCK. if_input can be called from a normal LWP context. In that case we need to prevent interrupts (softint) from running by splsoftnet to protect non-MP-safe codes (e.g., carp_input and agr_input). Pointed out by mlelstv@ Protect if_deferred_start_softint with KERNEL_LOCK if the interface isn't MP-safe To generate a diff of this commit: cvs rdiff -u -r1.216.6.5 -r1.216.6.6 src/sys/net/bpf.c cvs rdiff -u -r1.394.2.9 -r1.394.2.10 src/sys/net/if.c cvs rdiff -u -r1.134.6.9 -r1.134.6.10 src/sys/net/if_bridge.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/bpf.c diff -u src/sys/net/bpf.c:1.216.6.5 src/sys/net/bpf.c:1.216.6.6 --- src/sys/net/bpf.c:1.216.6.5 Mon Feb 5 14:18:00 2018 +++ src/sys/net/bpf.c Tue May 15 13:48:37 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: bpf.c,v 1.216.6.5 2018/02/05 14:18:00 martin Exp $ */ +/* $NetBSD: bpf.c,v 1.216.6.6 2018/05/15 13:48:37 martin Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.216.6.5 2018/02/05 14:18:00 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.216.6.6 2018/05/15 13:48:37 martin Exp $"); #if defined(_KERNEL_OPT) #include "opt_bpf.h" @@ -836,9 +836,13 @@ bpf_write(struct file *fp, off_t *offp, error = if_output_lock(ifp, ifp, m, (struct sockaddr *) &dst, NULL); if (mc != NULL) { - if (error == 0) + if (error == 0) { + int s = splsoftnet(); + KERNEL_LOCK_UNLESS_IFP_MPSAFE(ifp); ifp->_if_input(ifp, mc); - else + KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(ifp); + splx(s); + } else m_freem(mc); } /* Index: src/sys/net/if.c diff -u src/sys/net/if.c:1.394.2.9 src/sys/net/if.c:1.394.2.10 --- src/sys/net/if.c:1.394.2.9 Wed Feb 28 18:54:43 2018 +++ src/sys/net/if.c Tue May 15 13:48:37 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.394.2.9 2018/02/28 18:54:43 martin Exp $ */ +/* $NetBSD: if.c,v 1.394.2.10 2018/05/15 13:48:37 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.9 2018/02/28 18:54:43 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.394.2.10 2018/05/15 13:48:37 martin Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -716,8 +716,7 @@ if_initialize(ifnet_t *ifp) if (if_is_link_state_changeable(ifp)) { u_int flags = SOFTINT_NET; - flags |= ISSET(ifp->if_extflags, IFEF_MPSAFE) ? - SOFTINT_MPSAFE : 0; + flags |= if_is_mpsafe(ifp) ? SOFTINT_MPSAFE : 0; ifp->if_link_si = softint_establish(flags, if_link_state_change_si, ifp); if (ifp->if_link_si == NULL) { @@ -834,11 +833,13 @@ struct if_percpuq * if_percpuq_create(struct ifnet *ifp) { struct if_percpuq *ipq; + u_int flags = SOFTINT_NET; + + flags |= if_is_mpsafe(ifp) ? SOFTINT_MPSAFE : 0; ipq = kmem_zalloc(sizeof(*ipq), KM_SLEEP); ipq->ipq_ifp = ifp; - ipq->ipq_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, - if_percpuq_softint, ipq); + ipq->ipq_si = softint_establish(flags, if_percpuq_softint, ipq); ipq->ipq_ifqs = percpu_alloc(sizeof(struct ifqueue)); percpu_foreach(ipq->ipq_ifqs, &if_percpuq_init_ifq, NULL); @@ -1066,11 +1067,13 @@ void if_deferred_start_init(struct ifnet *ifp, void (*func)(struct ifnet *)) { struct if_deferred_start *ids; + u_int flags = SOFTINT_NET; + + flags |= if_is_mpsafe(ifp) ? SOFTINT_MPSAFE : 0; ids = kmem_zalloc(sizeof(*ids), KM_SLEEP); ids->ids_ifp = ifp; - ids->ids_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, - if_deferred_start_softint, ids); + ids->ids_si = softint_establish(flags, if_deferred_start_softint, ids); if (func != NULL) ids->ids_if_start = func; else Index: src/sys/net/if_bridge.c diff -u src/sys/net/if_bridge.c:1.134.6.9 src/sys/net/if_bridge.c:1.134.6.10 --- src/sys/net/if_bridge.c:1.134.6.9 Wed Apr 18 14:11:42 2018 +++ src/sys/net/if_bridge.c Tue May 15 13:48:37 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_bridge.c,v 1.134.6.9 2018/04/18 14:11:42 martin Exp $ */ +/* $NetBSD: if_bridge.c,v 1.134.6.10 2018/05/15 13:48:37 martin Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -80,7 +80,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.134.6.9 2018/04/18 14:11:42 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.134.6.10 2018/05/15 13:48:37 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_bridge_ipf.h" @@ -1575,13 +1575,11 @@ bridge_output(struct ifnet *ifp, struct m_set_rcvif(mc, dst_if); mc->m_flags &= ~M_PROMISC; -#ifndef NET_MPSAFE s = splsoftnet(); -#endif + KERNEL_LOCK_UNLESS_IFP_MPSAFE(dst_if); ether_input(dst_if, mc); -#ifndef NET_MPSAFE + KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(dst_if); splx(s); -#endif } next: