Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net Protect packet input routines with KERNEL_LOCK and s...



details:   https://anonhg.NetBSD.org/src/rev/55750fcaca48
branches:  trunk
changeset: 322716:55750fcaca48
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon May 14 02:55:03 2018 +0000

description:
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@

diffstat:

 sys/net/bpf.c       |  12 ++++++++----
 sys/net/if.c        |  10 ++++++----
 sys/net/if_bridge.c |  10 ++++------
 3 files changed, 18 insertions(+), 14 deletions(-)

diffs (102 lines):

diff -r c6cd72d55ef8 -r 55750fcaca48 sys/net/bpf.c
--- a/sys/net/bpf.c     Mon May 14 02:53:29 2018 +0000
+++ b/sys/net/bpf.c     Mon May 14 02:55:03 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.c,v 1.223 2018/01/25 02:45:02 ozaki-r Exp $        */
+/*     $NetBSD: bpf.c,v 1.224 2018/05/14 02:55:03 ozaki-r Exp $        */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.223 2018/01/25 02:45:02 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.224 2018/05/14 02:55:03 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -837,9 +837,13 @@
        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);
        }
        /*
diff -r c6cd72d55ef8 -r 55750fcaca48 sys/net/if.c
--- a/sys/net/if.c      Mon May 14 02:53:29 2018 +0000
+++ b/sys/net/if.c      Mon May 14 02:55:03 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.421 2018/05/14 02:53:29 ozaki-r Exp $ */
+/*     $NetBSD: if.c,v 1.422 2018/05/14 02:55:03 ozaki-r 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.421 2018/05/14 02:53:29 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.422 2018/05/14 02:55:03 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -821,11 +821,13 @@
 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);
 
diff -r c6cd72d55ef8 -r 55750fcaca48 sys/net/if_bridge.c
--- a/sys/net/if_bridge.c       Mon May 14 02:53:29 2018 +0000
+++ b/sys/net/if_bridge.c       Mon May 14 02:55:03 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bridge.c,v 1.154 2018/04/18 06:37:17 ozaki-r Exp $  */
+/*     $NetBSD: if_bridge.c,v 1.155 2018/05/14 02:55:03 ozaki-r Exp $  */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.154 2018/04/18 06:37:17 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.155 2018/05/14 02:55:03 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_bridge_ipf.h"
@@ -1575,13 +1575,11 @@
                                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:



Home | Main Index | Thread Index | Old Index