Here's a simple refactoring diff to simplify the next one. The upcoming diff will be unlocking IP forwarding paths, so I want to keep it as small as possible.
The idea of the refactoring below is to introduce two wrappers functions around IP queues. In the next iteration they will call the protocol function directly. ok? Index: dev/usb/if_umb.c =================================================================== RCS file: /cvs/src/sys/dev/usb/if_umb.c,v retrieving revision 1.13 diff -u -p -r1.13 if_umb.c --- dev/usb/if_umb.c 18 May 2017 14:48:27 -0000 1.13 +++ dev/usb/if_umb.c 30 May 2017 07:23:02 -0000 @@ -768,7 +768,6 @@ umb_output(struct ifnet *ifp, struct mbu int umb_input(struct ifnet *ifp, struct mbuf *m, void *cookie) { - struct niqueue *inq; uint8_t ipv; if ((ifp->if_flags & IFF_UP) == 0) { @@ -789,12 +788,12 @@ umb_input(struct ifnet *ifp, struct mbuf ifp->if_ibytes += m->m_pkthdr.len; switch (ipv) { case 4: - inq = &ipintrq; - break; + ipv4_input(ifp, m); + return 1; #ifdef INET6 case 6: - inq = &ip6intrq; - break; + ipv6_input(ifp, m); + return 1; #endif /* INET6 */ default: ifp->if_ierrors++; @@ -803,7 +802,6 @@ umb_input(struct ifnet *ifp, struct mbuf m_freem(m); return 1; } - niq_enqueue(inq, m); return 1; } Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.501 diff -u -p -r1.501 if.c --- net/if.c 30 May 2017 06:42:13 -0000 1.501 +++ net/if.c 30 May 2017 07:23:02 -0000 @@ -734,8 +734,6 @@ if_input(struct ifnet *ifp, struct mbuf_ int if_input_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af) { - struct niqueue *ifq = NULL; - #if NBPFILTER > 0 /* * Only send packets to bpf if they are destinated to local @@ -758,33 +756,28 @@ if_input_local(struct ifnet *ifp, struct ifp->if_opackets++; ifp->if_obytes += m->m_pkthdr.len; + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + switch (af) { case AF_INET: - ifq = &ipintrq; + ipv4_input(ifp, m); break; #ifdef INET6 case AF_INET6: - ifq = &ip6intrq; + ipv6_input(ifp, m); break; #endif /* INET6 */ #ifdef MPLS case AF_MPLS: - ifp->if_ipackets++; - ifp->if_ibytes += m->m_pkthdr.len; mpls_input(m); - return (0); + break; #endif /* MPLS */ default: printf("%s: can't handle af%d\n", ifp->if_xname, af); m_freem(m); return (EAFNOSUPPORT); } - - if (niq_enqueue(ifq, m) != 0) - return (ENOBUFS); - - ifp->if_ipackets++; - ifp->if_ibytes += m->m_pkthdr.len; return (0); } Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.244 diff -u -p -r1.244 if_ethersubr.c --- net/if_ethersubr.c 28 May 2017 12:51:34 -0000 1.244 +++ net/if_ethersubr.c 30 May 2017 07:23:02 -0000 @@ -374,8 +374,8 @@ ether_input(struct ifnet *ifp, struct mb decapsulate: switch (etype) { case ETHERTYPE_IP: - inq = &ipintrq; - break; + ipv4_input(ifp, m); + return (1); case ETHERTYPE_ARP: if (ifp->if_flags & IFF_NOARP) @@ -394,8 +394,8 @@ decapsulate: * Schedule IPv6 software interrupt for incoming IPv6 packet. */ case ETHERTYPE_IPV6: - inq = &ip6intrq; - break; + ipv6_input(ifp, m); + return (1); #endif /* INET6 */ #if NPPPOE > 0 || defined(PIPEX) case ETHERTYPE_PPPOEDISC: Index: net/if_mpe.c =================================================================== RCS file: /cvs/src/sys/net/if_mpe.c,v retrieving revision 1.59 diff -u -p -r1.59 if_mpe.c --- net/if_mpe.c 4 May 2017 15:00:24 -0000 1.59 +++ net/if_mpe.c 30 May 2017 07:23:02 -0000 @@ -396,7 +396,7 @@ mpe_input(struct mbuf *m, struct ifnet * bpf_mtap_af(ifp->if_bpf, AF_INET, m, BPF_DIRECTION_IN); #endif - niq_enqueue(&ipintrq, m); + ipv4_input(ifp, m); } #ifdef INET6 @@ -428,6 +428,6 @@ mpe_input6(struct mbuf *m, struct ifnet bpf_mtap_af(ifp->if_bpf, AF_INET6, m, BPF_DIRECTION_IN); #endif - niq_enqueue(&ip6intrq, m); + ipv6_input(ifp, m); } #endif /* INET6 */ Index: net/if_ppp.c =================================================================== RCS file: /cvs/src/sys/net/if_ppp.c,v retrieving revision 1.107 diff -u -p -r1.107 if_ppp.c --- net/if_ppp.c 27 May 2017 18:39:17 -0000 1.107 +++ net/if_ppp.c 30 May 2017 07:23:02 -0000 @@ -1396,10 +1396,8 @@ ppp_inproc(struct ppp_softc *sc, struct m->m_data += PPP_HDRLEN; m->m_len -= PPP_HDRLEN; - if (niq_enqueue(&ipintrq, m) != 0) - rv = 0; /* failure */ - else - rv = 1; /* ipintrq success */ + ipv4_input(ifp, m); + rv = 1; break; default: Index: net/if_pppx.c =================================================================== RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.60 diff -u -p -r1.60 if_pppx.c --- net/if_pppx.c 28 May 2017 18:43:51 -0000 1.60 +++ net/if_pppx.c 30 May 2017 07:23:03 -0000 @@ -318,7 +318,6 @@ pppxwrite(dev_t dev, struct uio *uio, in struct pppx_if *pxi; uint32_t proto; struct mbuf *top, **mp, *m; - struct niqueue *ifq; int tlen; int error = 0; size_t mlen; @@ -396,20 +395,17 @@ pppxwrite(dev_t dev, struct uio *uio, in switch (proto) { case AF_INET: - ifq = &ipintrq; + ipv4_input(&pxi->pxi_if, top); break; #ifdef INET6 case AF_INET6: - ifq = &ip6intrq; + ipv6_input(&pxi->pxi_if, top); break; #endif default: m_freem(top); return (EAFNOSUPPORT); } - - if (niq_enqueue(ifq, top) != 0) - return (ENOBUFS); return (error); } Index: net/if_spppsubr.c =================================================================== RCS file: /cvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.163 diff -u -p -r1.163 if_spppsubr.c --- net/if_spppsubr.c 14 Apr 2017 15:11:31 -0000 1.163 +++ net/if_spppsubr.c 30 May 2017 07:23:03 -0000 @@ -58,8 +58,6 @@ #include <netinet/in.h> #include <netinet/in_var.h> #include <netinet/ip.h> -#include <netinet/tcp.h> -#include <netinet/if_ether.h> #ifdef INET6 #include <netinet6/in6_ifattach.h> @@ -417,7 +415,6 @@ void sppp_input(struct ifnet *ifp, struct mbuf *m) { struct ppp_header ht; - struct niqueue *inq = NULL; struct sppp *sp = (struct sppp *)ifp; struct timeval tv; int debug = ifp->if_flags & IFF_DEBUG; @@ -438,7 +435,6 @@ sppp_input(struct ifnet *ifp, struct mbu SPP_ARGS(ifp), m->m_pkthdr.len); drop: m_freem (m); - dropped: ++ifp->if_ierrors; ++ifp->if_iqdrops; return; @@ -503,8 +499,11 @@ sppp_input(struct ifnet *ifp, struct mbu return; case PPP_IP: if (sp->state[IDX_IPCP] == STATE_OPENED) { - inq = &ipintrq; sp->pp_last_activity = tv.tv_sec; + if (ifp->if_flags & IFF_UP) { + ipv4_input(ifp, m); + return; + } } break; #ifdef INET6 @@ -515,8 +514,11 @@ sppp_input(struct ifnet *ifp, struct mbu return; case PPP_IPV6: if (sp->state[IDX_IPV6CP] == STATE_OPENED) { - inq = &ip6intrq; sp->pp_last_activity = tv.tv_sec; + if (ifp->if_flags & IFF_UP) { + ipv6_input(ifp, m); + return; + } } break; #endif @@ -533,16 +535,7 @@ sppp_input(struct ifnet *ifp, struct mbu goto drop; } - if (! (ifp->if_flags & IFF_UP) || ! inq) - goto drop; - - if (niq_enqueue(inq, m) != 0) { - /* Queue overflow. */ - if (debug) - log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", - SPP_ARGS(ifp)); - goto dropped; - } + goto drop; } /* Index: net/if_tun.c =================================================================== RCS file: /cvs/src/sys/net/if_tun.c,v retrieving revision 1.174 diff -u -p -r1.174 if_tun.c --- net/if_tun.c 27 May 2017 06:44:14 -0000 1.174 +++ net/if_tun.c 30 May 2017 07:23:03 -0000 @@ -835,7 +835,6 @@ int tun_dev_write(struct tun_softc *tp, struct uio *uio, int ioflag) { struct ifnet *ifp; - struct niqueue *ifq; u_int32_t *th; struct mbuf *top, **mp, *m; int error = 0, tlen; @@ -928,27 +927,22 @@ tun_dev_write(struct tun_softc *tp, stru top->m_pkthdr.ph_rtableid = ifp->if_rdomain; top->m_pkthdr.ph_ifidx = ifp->if_index; + ifp->if_ipackets++; + ifp->if_ibytes += top->m_pkthdr.len; + switch (ntohl(*th)) { case AF_INET: - ifq = &ipintrq; + ipv4_input(ifp, top); break; #ifdef INET6 case AF_INET6: - ifq = &ip6intrq; + ipv6_input(ifp, top); break; #endif default: m_freem(top); return (EAFNOSUPPORT); } - - if (niq_enqueue(ifq, top) != 0) { - ifp->if_collisions++; - return (ENOBUFS); - } - - ifp->if_ipackets++; - ifp->if_ibytes += top->m_pkthdr.len; return (error); } Index: net/pipex.c =================================================================== RCS file: /cvs/src/sys/net/pipex.c,v retrieving revision 1.100 diff -u -p -r1.100 pipex.c --- net/pipex.c 28 May 2017 20:48:29 -0000 1.100 +++ net/pipex.c 30 May 2017 07:23:03 -0000 @@ -1096,20 +1096,15 @@ pipex_ip_input(struct mbuf *m0, struct p bpf_mtap_af(ifp->if_bpf, AF_INET, m0, BPF_DIRECTION_IN); #endif - if (niq_enqueue(&ipintrq, m0) != 0) { - ifp->if_collisions++; - goto dropped; - } - ifp->if_ipackets++; ifp->if_ibytes += len; session->stat.ipackets++; session->stat.ibytes += len; + ipv4_input(ifp, m0); return; drop: m_freem(m0); -dropped: session->stat.ierrors++; } @@ -1147,19 +1142,11 @@ pipex_ip6_input(struct mbuf *m0, struct bpf_mtap_af(ifp->if_bpf, AF_INET6, m0, BPF_DIRECTION_IN); #endif - if (niq_enqueue(&ip6intrq, m0) != 0) { - ifp->if_collisions++; - goto dropped; - } - ifp->if_ipackets++; ifp->if_ibytes += len; session->stat.ipackets++; session->stat.ibytes += len; - - return; -dropped: - session->stat.ierrors++; + ipv6_input(ifp, m0); } #endif Index: netinet/in.h =================================================================== RCS file: /cvs/src/sys/netinet/in.h,v retrieving revision 1.122 diff -u -p -r1.122 in.h --- netinet/in.h 4 May 2017 15:00:24 -0000 1.122 +++ netinet/in.h 30 May 2017 07:23:03 -0000 @@ -800,7 +800,6 @@ __END_DECLS #ifdef _KERNEL extern int inetctlerrmap[]; -extern struct niqueue ipintrq; /* ip packet input queue */ extern struct in_addr zeroin_addr; struct mbuf; @@ -808,6 +807,8 @@ struct sockaddr; struct sockaddr_in; struct ifaddr; struct in_ifaddr; + +void ipv4_input(struct ifnet *, struct mbuf *); int in_broadcast(struct in_addr, u_int); int in_canforward(struct in_addr); Index: netinet/ip_divert.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_divert.c,v retrieving revision 1.46 diff -u -p -r1.46 ip_divert.c --- netinet/ip_divert.c 5 Apr 2017 13:35:18 -0000 1.46 +++ netinet/ip_divert.c 30 May 2017 07:23:03 -0000 @@ -134,6 +134,7 @@ divert_output(struct inpcb *inp, struct if (dir == PF_IN) { ipaddr.sin_addr = sin->sin_addr; + /* XXXSMP ifa_ifwithaddr() is not safe. */ ifa = ifa_ifwithaddr(sintosa(&ipaddr), m->m_pkthdr.ph_rtableid); if (ifa == NULL) { error = EADDRNOTAVAIL; @@ -150,7 +151,8 @@ divert_output(struct inpcb *inp, struct ip->ip_sum = in_cksum(m, off); in_proto_cksum_out(m, NULL); - niq_enqueue(&ipintrq, m); + /* XXXSMP ``ifa'' is not reference counted. */ + ipv4_input(ifa->ifa_ifp, m); } else { error = ip_output(m, NULL, &inp->inp_route, IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL, 0); Index: netinet/ip_gre.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_gre.c,v retrieving revision 1.64 diff -u -p -r1.64 ip_gre.c --- netinet/ip_gre.c 4 May 2017 17:58:46 -0000 1.64 +++ netinet/ip_gre.c 30 May 2017 07:23:03 -0000 @@ -93,7 +93,6 @@ int gre_input2(struct mbuf *m, int hlen, int proto) { struct greip *gip; - struct niqueue *ifq; struct gre_softc *sc; u_short flags; u_int af; @@ -160,13 +159,11 @@ gre_input2(struct mbuf *m, int hlen, int */ if (gre_wccp == 2) hlen += 4; - case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */ - ifq = &ipintrq; /* we are in ip_input */ + case ETHERTYPE_IP: af = AF_INET; break; #ifdef INET6 case ETHERTYPE_IPV6: - ifq = &ip6intrq; af = AF_INET6; break; #endif @@ -205,7 +202,19 @@ gre_input2(struct mbuf *m, int hlen, int pf_pkt_addr_changed(m); #endif - niq_enqueue(ifq, m); + switch (af) { + case AF_INET: + ipv4_input(&sc->sc_if, m); + break; +#ifdef INET6 + case AF_INET6: + ipv6_input(&sc->sc_if, m); + break; +#endif + default: + return (0); + } + return (1); /* packet is done, no further processing needed */ } @@ -334,7 +343,7 @@ gre_mobile_input(struct mbuf **mp, int * pf_pkt_addr_changed(m); #endif - niq_enqueue(&ipintrq, m); + ipv4_input(&sc->sc_if, m); return IPPROTO_DONE; } Index: netinet/ip_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.307 diff -u -p -r1.307 ip_input.c --- netinet/ip_input.c 29 May 2017 14:36:22 -0000 1.307 +++ netinet/ip_input.c 30 May 2017 07:23:03 -0000 @@ -208,6 +208,12 @@ ip_init(void) } void +ipv4_input(struct ifnet *ifp, struct mbuf *m) +{ + niq_enqueue(&ipintrq, m); +} + +void ipintr(void) { struct mbuf *m; @@ -221,7 +227,7 @@ ipintr(void) if ((m->m_flags & M_PKTHDR) == 0) panic("ipintr no HDR"); #endif - ipv4_input(m); + ip_input(m); } } @@ -231,7 +237,7 @@ ipintr(void) * Checksum and byte swap header. Process options. Forward or deliver. */ void -ipv4_input(struct mbuf *m) +ip_input(struct mbuf *m) { struct ifnet *ifp; struct rtentry *rt = NULL; Index: netinet/ip_ipip.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ipip.c,v retrieving revision 1.81 diff -u -p -r1.81 ip_ipip.c --- netinet/ip_ipip.c 28 May 2017 13:59:05 -0000 1.81 +++ netinet/ip_ipip.c 30 May 2017 07:23:03 -0000 @@ -122,7 +122,6 @@ ipip_input_gif(struct mbuf **mp, int *of struct mbuf *m = *mp; struct sockaddr_in *sin; struct ifnet *ifp; - struct niqueue *ifq = NULL; struct ip *ip; #ifdef INET6 struct sockaddr_in6 *sin6; @@ -319,22 +318,17 @@ ipip_input_gif(struct mbuf **mp, int *of switch (proto) { case IPPROTO_IPV4: - ifq = &ipintrq; + ipv4_input(ifp, m); break; #ifdef INET6 case IPPROTO_IPV6: - ifq = &ip6intrq; + ipv6_input(ifp, m); break; #endif default: panic("%s: should never reach here", __func__); } - if (niq_enqueue(ifq, m) != 0) { - ipipstat_inc(ipips_qfull); - DPRINTF(("%s: packet dropped because of full queue\n", - __func__)); - } return IPPROTO_DONE; } Index: netinet/ip_var.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_var.h,v retrieving revision 1.76 diff -u -p -r1.76 ip_var.h --- netinet/ip_var.h 28 May 2017 09:25:51 -0000 1.76 +++ netinet/ip_var.h 30 May 2017 07:23:04 -0000 @@ -248,7 +248,7 @@ int ip_sysctl(int *, u_int, void *, siz void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *, struct mbuf *); void ipintr(void); -void ipv4_input(struct mbuf *); +void ip_input(struct mbuf *); void ip_deliver(struct mbuf **, int *, int, int); void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int); int rip_ctloutput(int, struct socket *, int, int, struct mbuf *); Index: netinet6/in6.h =================================================================== RCS file: /cvs/src/sys/netinet6/in6.h,v retrieving revision 1.94 diff -u -p -r1.94 in6.h --- netinet6/in6.h 4 May 2017 15:00:24 -0000 1.94 +++ netinet6/in6.h 30 May 2017 07:23:04 -0000 @@ -405,7 +405,6 @@ typedef __socklen_t socklen_t; /* length #ifdef _KERNEL extern u_char inet6ctlerrmap[]; -extern struct niqueue ip6intrq; /* IP6 packet input queue */ extern struct in6_addr zeroin6_addr; struct mbuf; @@ -712,6 +711,8 @@ ifatoia6(struct ifaddr *ifa) __BEGIN_DECLS struct cmsghdr; + +void ipv6_input(struct ifnet *, struct mbuf *); extern int inet6_opt_init(void *, socklen_t); extern int inet6_opt_append(void *, socklen_t, int, u_int8_t, Index: netinet6/ip6_divert.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v retrieving revision 1.46 diff -u -p -r1.46 ip6_divert.c --- netinet6/ip6_divert.c 13 Mar 2017 20:18:21 -0000 1.46 +++ netinet6/ip6_divert.c 30 May 2017 07:23:04 -0000 @@ -139,6 +139,7 @@ divert6_output(struct inpcb *inp, struct if (dir == PF_IN) { ip6addr.sin6_addr = sin6->sin6_addr; + /* XXXSMP ``ifa'' is not reference counted. */ ifa = ifa_ifwithaddr(sin6tosa(&ip6addr), m->m_pkthdr.ph_rtableid); if (ifa == NULL) { @@ -154,7 +155,8 @@ divert6_output(struct inpcb *inp, struct */ in6_proto_cksum_out(m, NULL); - niq_enqueue(&ip6intrq, m); /* return error on q full? */ + /* XXXSMP ``ifa'' is not reference counted. */ + ipv6_input(ifa->ifa_ifp, m); } else { error = ip6_output(m, NULL, &inp->inp_route6, IP_ALLOWBROADCAST | IP_RAWOUTPUT, NULL, NULL); Index: netinet6/ip6_input.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.191 diff -u -p -r1.191 ip6_input.c --- netinet6/ip6_input.c 29 May 2017 14:36:22 -0000 1.191 +++ netinet6/ip6_input.c 30 May 2017 07:23:04 -0000 @@ -160,6 +160,12 @@ ip6_init(void) ip6counters = counters_alloc(ip6s_ncounters); } +void +ipv6_input(struct ifnet *ifp, struct mbuf *m) +{ + niq_enqueue(&ip6intrq, m); +} + /* * IP6 input interrupt handling. Just pass the packet to ip6_input. */ Index: netmpls/mpls_input.c =================================================================== RCS file: /cvs/src/sys/netmpls/mpls_input.c,v retrieving revision 1.59 diff -u -p -r1.59 mpls_input.c --- netmpls/mpls_input.c 2 Mar 2017 03:09:50 -0000 1.59 +++ netmpls/mpls_input.c 30 May 2017 07:23:04 -0000 @@ -121,14 +121,26 @@ mpls_input(struct mbuf *m) do_v4: if (mpls_ip_adjttl(m, ttl)) return; - niq_enqueue(&ipintrq, m); + ifp = if_get(m->m_pkthdr.ph_ifidx); + if (ifp == NULL) { + m_freem(m); + return; + } + ipv4_input(ifp, m); + if_put(ifp); return; #ifdef INET6 case MPLS_LABEL_IPV6NULL: do_v6: if (mpls_ip6_adjttl(m, ttl)) return; - niq_enqueue(&ip6intrq, m); + ifp = if_get(m->m_pkthdr.ph_ifidx); + if (ifp == NULL) { + m_freem(m); + return; + } + ipv6_input(ifp, m); + if_put(ifp); return; #endif /* INET6 */ case MPLS_LABEL_IMPLNULL: