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, ðerip_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, ðerip_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);