After auditing all the pr_input() functions, the only missing bits
for taking them out of the KERNEL_LOCK() are: ``etheripstat''.  I
leave such counter conversions for somebody else (8

In the meantime I annotated globals used in these functions.  Most
of the pseudo-interfaces have a global list that is currently protected
by the NET_LOCK().

PCB tables are also currently protected by the NET_LOCK().

carp(4) and IGMP inputs need some love, so they grab the KERNEL_LOCK()
for now.

inet{,6}ctlerrmap are read-only so they get turned into 'const'.

With this diff in we should be able to have a mostly KERNEL_LOCK()-free
softnet taskq.

ok?

Index: net/if_etherip.c
===================================================================
RCS file: /cvs/src/sys/net/if_etherip.c,v
retrieving revision 1.21
diff -u -p -r1.21 if_etherip.c
--- net/if_etherip.c    25 Oct 2017 09:24:09 -0000      1.21
+++ net/if_etherip.c    8 Nov 2017 14:41:29 -0000
@@ -434,6 +434,7 @@ ip_etherip_input(struct mbuf **mp, int *
                return IPPROTO_DONE;
        }
 
+       NET_ASSERT_LOCKED();
        LIST_FOREACH(sc, &etherip_softc_list, sc_entry) {
                if (sc->sc_src.ss_family != AF_INET ||
                    sc->sc_dst.ss_family != AF_INET)
@@ -598,6 +599,7 @@ ip6_etherip_input(struct mbuf **mp, int 
        in6_recoverscope(&ipsrc, &ip6->ip6_src);
        in6_recoverscope(&ipdst, &ip6->ip6_dst);
 
+       NET_ASSERT_LOCKED();
        LIST_FOREACH(sc, &etherip_softc_list, sc_entry) {
                if (sc->sc_src.ss_family != AF_INET6 ||
                    sc->sc_dst.ss_family != AF_INET6)
Index: net/if_gif.c
===================================================================
RCS file: /cvs/src/sys/net/if_gif.c,v
retrieving revision 1.101
diff -u -p -r1.101 if_gif.c
--- net/if_gif.c        25 Oct 2017 09:24:09 -0000      1.101
+++ net/if_gif.c        8 Nov 2017 14:40:26 -0000
@@ -622,6 +622,7 @@ in_gif_input(struct mbuf **mp, int *offp
 
        ip = mtod(m, struct ip *);
 
+       NET_ASSERT_LOCKED();
        /* this code will be soon improved. */
        LIST_FOREACH(sc, &gif_softc_list, gif_list) {
                if (sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
@@ -730,7 +731,8 @@ in6_gif_output(struct ifnet *ifp, int fa
        return 0;
 }
 
-int in6_gif_input(struct mbuf **mp, int *offp, int proto, int af)
+int
+in6_gif_input(struct mbuf **mp, int *offp, int proto, int af)
 {
        struct mbuf *m = *mp;
        struct gif_softc *sc;
@@ -747,6 +749,7 @@ int in6_gif_input(struct mbuf **mp, int 
        in6_recoverscope(&src, &ip6->ip6_src);
        in6_recoverscope(&dst, &ip6->ip6_dst);
 
+       NET_ASSERT_LOCKED();
        LIST_FOREACH(sc, &gif_softc_list, gif_list) {
                if (sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
                    sc->gif_psrc->sa_family != AF_INET6 ||
Index: net/if_pfsync.c
===================================================================
RCS file: /cvs/src/sys/net/if_pfsync.c,v
retrieving revision 1.254
diff -u -p -r1.254 if_pfsync.c
--- net/if_pfsync.c     11 Aug 2017 21:24:19 -0000      1.254
+++ net/if_pfsync.c     8 Nov 2017 14:42:49 -0000
@@ -659,6 +659,8 @@ pfsync_input(struct mbuf **mp, int *offp
        int offset, noff, len, count, mlen, flags = 0;
        int e;
 
+       NET_ASSERT_LOCKED();
+
        pfsyncstat_inc(pfsyncs_ipackets);
 
        /* verify that we have a sync interface configured */
Index: net/if_vxlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vxlan.c,v
retrieving revision 1.63
diff -u -p -r1.63 if_vxlan.c
--- net/if_vxlan.c      25 Oct 2017 09:24:09 -0000      1.63
+++ net/if_vxlan.c      8 Nov 2017 14:49:58 -0000
@@ -611,6 +611,7 @@ vxlan_lookup(struct mbuf *m, struct udph
                vni = VXLAN_VNI_UNSET;
        }
 
+       NET_ASSERT_LOCKED();
        /* First search for a vxlan(4) interface with the packet's VNI */
        LIST_FOREACH(sc, &vxlan_tagh[VXLAN_TAGHASH(vni)], sc_entry) {
                if ((uh->uh_dport == sc->sc_dstport) &&
Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.1043
diff -u -p -r1.1043 pf.c
--- net/pf.c    31 Oct 2017 22:05:12 -0000      1.1043
+++ net/pf.c    8 Nov 2017 15:03:35 -0000
@@ -3184,12 +3184,14 @@ pf_socket_lookup(struct pf_pdesc *pd)
                sport = pd->hdr.tcp.th_sport;
                dport = pd->hdr.tcp.th_dport;
                PF_ASSERT_LOCKED();
+               NET_ASSERT_LOCKED();
                tb = &tcbtable;
                break;
        case IPPROTO_UDP:
                sport = pd->hdr.udp.uh_sport;
                dport = pd->hdr.udp.uh_dport;
                PF_ASSERT_LOCKED();
+               NET_ASSERT_LOCKED();
                tb = &udbtable;
                break;
        default:
Index: net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.105
diff -u -p -r1.105 pipex.c
--- net/pipex.c 11 Aug 2017 21:24:19 -0000      1.105
+++ net/pipex.c 8 Nov 2017 15:08:06 -0000
@@ -637,6 +637,7 @@ pipex_lookup_by_session_id(int protocol,
        struct pipex_hash_head *list;
        struct pipex_session *session;
 
+       NET_ASSERT_LOCKED();
        list = PIPEX_ID_HASHTABLE(session_id);
        LIST_FOREACH(session, list, id_chain) {
                if (session->protocol == protocol &&
Index: netinet/igmp.c
===================================================================
RCS file: /cvs/src/sys/netinet/igmp.c,v
retrieving revision 1.71
diff -u -p -r1.71 igmp.c
--- netinet/igmp.c      29 Oct 2017 14:56:36 -0000      1.71
+++ netinet/igmp.c      8 Nov 2017 14:37:06 -0000
@@ -177,6 +177,7 @@ rti_find(struct ifnet *ifp)
 {
        struct router_info *rti;
 
+       KERNEL_ASSERT_LOCKED();
        for (rti = rti_head; rti != 0; rti = rti->rti_next) {
                if (rti->rti_ifidx == ifp->if_index)
                        return (rti);
@@ -221,7 +222,9 @@ igmp_input(struct mbuf **mp, int *offp, 
                return IPPROTO_DONE;
        }
 
+       KERNEL_LOCK();
        proto = igmp_input_if(ifp, mp, offp, proto, af);
+       KERNEL_UNLOCK();
        if_put(ifp);
        return proto;
 }
Index: netinet/in.h
===================================================================
RCS file: /cvs/src/sys/netinet/in.h,v
retrieving revision 1.125
diff -u -p -r1.125 in.h
--- netinet/in.h        6 Oct 2017 21:14:55 -0000       1.125
+++ netinet/in.h        8 Nov 2017 15:14:23 -0000
@@ -794,7 +794,7 @@ __END_DECLS
 #endif /* !_KERNEL */
 
 #ifdef _KERNEL
-extern    int inetctlerrmap[];
+extern    const int inetctlerrmap[];
 extern    struct in_addr zeroin_addr;
 
 struct mbuf;
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.317
diff -u -p -r1.317 ip_carp.c
--- netinet/ip_carp.c   16 Oct 2017 13:20:20 -0000      1.317
+++ netinet/ip_carp.c   8 Nov 2017 14:30:24 -0000
@@ -505,7 +505,9 @@ carp_proto_input_if(struct ifnet *ifp, s
        }
        m->m_data -= iplen;
 
+       KERNEL_LOCK();
        carp_proto_input_c(ifp, m, ch, ismulti, AF_INET);
+       KERNEL_UNLOCK();
        return IPPROTO_DONE;
 }
 
@@ -580,7 +582,9 @@ carp6_proto_input_if(struct ifnet *ifp, 
        }
        m->m_data -= *offp;
 
+       KERNEL_LOCK();
        carp_proto_input_c(ifp, m, ch, 1, AF_INET6);
+       KERNEL_UNLOCK();
        return IPPROTO_DONE;
 }
 #endif /* INET6 */
@@ -1514,7 +1518,7 @@ carp_lsdrop(struct mbuf *m, sa_family_t 
                m_tag_delete(m, mtag);
                m->m_flags &= ~M_MCAST;
        }
-       
+
        /*
         * Return without making a drop decision. This allows to clear the
         * M_MCAST flag and do nothing else.
Index: netinet/ip_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ether.c,v
retrieving revision 1.88
diff -u -p -r1.88 ip_ether.c
--- netinet/ip_ether.c  6 Nov 2017 15:12:43 -0000       1.88
+++ netinet/ip_ether.c  8 Nov 2017 14:24:56 -0000
@@ -296,6 +296,7 @@ etherip_getgif(struct mbuf *m)
                return NULL;
        }
 
+       NET_ASSERT_LOCKED();
        /* Find appropriate gif(4) interface */
        LIST_FOREACH(sc, &gif_softc_list, gif_list) {
                if ((sc->gif_psrc == NULL) ||
Index: netinet/ip_gre.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_gre.c,v
retrieving revision 1.67
diff -u -p -r1.67 ip_gre.c
--- netinet/ip_gre.c    9 Oct 2017 08:35:38 -0000       1.67
+++ netinet/ip_gre.c    8 Nov 2017 14:28:25 -0000
@@ -356,6 +356,7 @@ gre_lookup(struct mbuf *m, u_int8_t prot
        struct ip *ip = mtod(m, struct ip *);
        struct gre_softc *sc;
 
+       NET_ASSERT_LOCKED();
        LIST_FOREACH(sc, &gre_softc_list, sc_list) {
                if ((sc->g_dst.s_addr == ip->ip_src.s_addr) &&
                    (sc->g_src.s_addr == ip->ip_dst.s_addr) &&
Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.329
diff -u -p -r1.329 ip_input.c
--- netinet/ip_input.c  5 Nov 2017 13:19:59 -0000       1.329
+++ netinet/ip_input.c  8 Nov 2017 15:14:10 -0000
@@ -1402,7 +1402,7 @@ ip_stripoptions(struct mbuf *m)
        ip->ip_len = htons(ntohs(ip->ip_len) - olen);
 }
 
-int inetctlerrmap[PRC_NCMDS] = {
+const int inetctlerrmap[PRC_NCMDS] = {
        0,              0,              0,              0,
        0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
        EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
Index: netinet/ipsec_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.158
diff -u -p -r1.158 ipsec_input.c
--- netinet/ipsec_input.c       6 Nov 2017 15:12:43 -0000       1.158
+++ netinet/ipsec_input.c       8 Nov 2017 15:17:25 -0000
@@ -779,6 +779,7 @@ ipsec_common_ctlinput(u_int rdomain, int
                        return;
 
                /* Walk the chain backwards to the first tdb */
+               NET_ASSERT_LOCKED();
                for (; tdbp; tdbp = tdbp->tdb_inext) {
                        if (tdbp->tdb_flags & TDBF_INVALID ||
                            (adjust = ipsec_hdrsz(tdbp)) == -1)
Index: netinet/raw_ip.c
===================================================================
RCS file: /cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.105
diff -u -p -r1.105 raw_ip.c
--- netinet/raw_ip.c    2 Nov 2017 14:01:18 -0000       1.105
+++ netinet/raw_ip.c    8 Nov 2017 15:02:19 -0000
@@ -128,6 +128,7 @@ rip_input(struct mbuf **mp, int *offp, i
        KASSERT(af == AF_INET);
 
        ripsrc.sin_addr = ip->ip_src;
+       NET_ASSERT_LOCKED();
        TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) {
                if (inp->inp_socket->so_state & SS_CANTRCVMORE)
                        continue;
@@ -512,10 +513,11 @@ rip_attach(struct socket *so, int proto)
        if (proto < 0 || proto >= IPPROTO_MAX)
                return EPROTONOSUPPORT;
 
-       if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
-           (error = in_pcballoc(so, &rawcbtable))) {
+       if ((error = soreserve(so, rip_sendspace, rip_recvspace)))
+               return error;
+       NET_ASSERT_LOCKED();
+       if ((error = in_pcballoc(so, &rawcbtable)))
                return error;
-       }
        inp = sotoinpcb(so);
        inp->inp_ip.ip_p = proto;
        return 0;
Index: netinet/tcp_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.350
diff -u -p -r1.350 tcp_input.c
--- netinet/tcp_input.c 25 Oct 2017 12:38:21 -0000      1.350
+++ netinet/tcp_input.c 8 Nov 2017 14:54:07 -0000
@@ -579,6 +579,7 @@ findpcb:
        }
        KASSERT(sotoinpcb(inp->inp_socket) == inp);
        KASSERT(intotcpcb(inp) == NULL || intotcpcb(inp)->t_inpcb == inp);
+       soassertlocked(inp->inp_socket);
 
        /* Check the minimum TTL for socket. */
        switch (af) {
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.159
diff -u -p -r1.159 tcp_usrreq.c
--- netinet/tcp_usrreq.c        2 Nov 2017 14:01:18 -0000       1.159
+++ netinet/tcp_usrreq.c        8 Nov 2017 15:21:16 -0000
@@ -576,6 +576,7 @@ tcp_attach(struct socket *so, int proto)
                        return (error);
        }
 
+       NET_ASSERT_LOCKED();
        error = in_pcballoc(so, &tcbtable);
        if (error)
                return (error);
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.242
diff -u -p -r1.242 udp_usrreq.c
--- netinet/udp_usrreq.c        2 Nov 2017 14:01:18 -0000       1.242
+++ netinet/udp_usrreq.c        8 Nov 2017 15:04:19 -0000
@@ -383,6 +383,7 @@ udp_input(struct mbuf **mp, int *offp, i
                 * (Algorithm copied from raw_intr().)
                 */
                last = NULL;
+               NET_ASSERT_LOCKED();
                TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) {
                        if (inp->inp_socket->so_state & SS_CANTRCVMORE)
                                continue;
@@ -564,6 +565,7 @@ udp_input(struct mbuf **mp, int *offp, i
                }
        }
        KASSERT(sotoinpcb(inp->inp_socket) == inp);
+       soassertlocked(inp->inp_socket);
 
 #ifdef INET6
        if (ip6 && inp->inp_ip6_minhlim &&
@@ -1254,8 +1256,11 @@ udp_attach(struct socket *so, int proto)
        if (so->so_pcb != NULL)
                return EINVAL;
 
-       if ((error = soreserve(so, udp_sendspace, udp_recvspace)) ||
-           (error = in_pcballoc(so, &udbtable)))
+       if ((error = soreserve(so, udp_sendspace, udp_recvspace)))
+               return error;
+
+       NET_ASSERT_LOCKED();
+       if ((error = in_pcballoc(so, &udbtable)))
                return error;
 #ifdef INET6
        if (sotoinpcb(so)->inp_flags & INP_IPV6)
Index: netinet6/in6.h
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.h,v
retrieving revision 1.99
diff -u -p -r1.99 in6.h
--- netinet6/in6.h      1 Sep 2017 16:48:27 -0000       1.99
+++ netinet6/in6.h      8 Nov 2017 15:18:51 -0000
@@ -404,7 +404,7 @@ typedef     __socklen_t     socklen_t;      /* length
 #endif /* __BSD_VISIBLE */
 
 #ifdef _KERNEL
-extern u_char inet6ctlerrmap[];
+extern const u_char inet6ctlerrmap[];
 extern struct in6_addr zeroin6_addr;
 
 struct mbuf;
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.207
diff -u -p -r1.207 ip6_input.c
--- netinet6/ip6_input.c        1 Nov 2017 06:35:38 -0000       1.207
+++ netinet6/ip6_input.c        8 Nov 2017 15:19:09 -0000
@@ -1344,7 +1344,7 @@ ip6_lasthdr(struct mbuf *m, int off, int
  * System control for IP6
  */
 
-u_char inet6ctlerrmap[PRC_NCMDS] = {
+const u_char inet6ctlerrmap[PRC_NCMDS] = {
        0,              0,              0,              0,
        0,              EMSGSIZE,       EHOSTDOWN,      EHOSTUNREACH,
        EHOSTUNREACH,   EHOSTUNREACH,   ECONNREFUSED,   ECONNREFUSED,
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.122
diff -u -p -r1.122 raw_ip6.c
--- netinet6/raw_ip6.c  2 Nov 2017 14:01:18 -0000       1.122
+++ netinet6/raw_ip6.c  8 Nov 2017 15:02:04 -0000
@@ -136,6 +136,7 @@ rip6_input(struct mbuf **mp, int *offp, 
        /* KAME hack: recover scopeid */
        in6_recoverscope(&rip6src, &ip6->ip6_src);
 
+       NET_ASSERT_LOCKED();
        TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) {
                if (in6p->inp_socket->so_state & SS_CANTRCVMORE)
                        continue;
@@ -695,8 +696,10 @@ rip6_attach(struct socket *so, int proto
        if (proto < 0 || proto >= IPPROTO_MAX)
                return EPROTONOSUPPORT;
 
-       if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
-           (error = in_pcballoc(so, &rawin6pcbtable)))
+       if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)))
+               return error;
+       NET_ASSERT_LOCKED();
+       if ((error = in_pcballoc(so, &rawin6pcbtable)))
                return error;
 
        in6p = sotoinpcb(so);

Reply via email to