Index: if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.603 diff -u -p -r1.603 if.c --- if.c 12 Apr 2020 07:04:03 -0000 1.603 +++ if.c 7 May 2020 01:47:12 -0000 @@ -1589,6 +1649,33 @@ p2p_rtrequest(struct ifnet *ifp, int req } } +int +l3_input(struct ifnet *ifp, struct mbuf *m, void *cookie) +{ + void (*input)(struct ifnet *, struct mbuf *); + + switch (m->m_pkthdr.ph_family) { + case AF_INET: + input = ipv4_input; + break; +#ifdef INET6 + case AF_INET6: + input = ipv6_input; + break; +#endif +#ifdef MPLS + case AF_MPLS: + input = mpls_input; + break; +#endif + default: + m_freem(m); + return (1); + } + + (*input)(ifp, m); + return (1); +} /* * Bring down all interfaces Index: if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.104 diff -u -p -r1.104 if_var.h --- if_var.h 12 Apr 2020 07:02:43 -0000 1.104 +++ if_var.h 7 May 2020 01:47:12 -0000 @@ -348,6 +351,7 @@ int if_input_local(struct ifnet *, struc int if_output_local(struct ifnet *, struct mbuf *, sa_family_t); void if_rtrequest_dummy(struct ifnet *, int, struct rtentry *); void p2p_rtrequest(struct ifnet *, int, struct rtentry *); +int l3_input(struct ifnet *, struct mbuf *, void *); struct ifaddr *ifa_ifwithaddr(struct sockaddr *, u_int); struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *, u_int); Index: if_gif.c =================================================================== RCS file: /cvs/src/sys/net/if_gif.c,v retrieving revision 1.128 diff -u -p -r1.128 if_gif.c --- if_gif.c 4 Oct 2019 05:00:49 -0000 1.128 +++ if_gif.c 7 May 2020 01:47:12 -0000 @@ -180,6 +180,8 @@ gif_clone_create(struct if_clone *ifc, i bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t)); #endif + if_ih_insert(ifp, l3_input, NULL); + NET_LOCK(); TAILQ_INSERT_TAIL(&gif_list, &sc->sc_tunnel, t_entry); NET_UNLOCK(); @@ -199,6 +201,8 @@ gif_clone_destroy(struct ifnet *ifp) TAILQ_REMOVE(&gif_list, &sc->sc_tunnel, t_entry); NET_UNLOCK(); + if_ih_remove(ifp, l3_input, NULL); + if_detach(ifp); free(sc, M_DEVBUF, sizeof(*sc)); @@ -390,7 +394,6 @@ int gif_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt) { - struct m_tag *mtag; int error = 0; if (!ISSET(ifp->if_flags, IFF_RUNNING)) { @@ -788,8 +777,8 @@ gif_input(struct gif_tunnel *key, struct struct mbuf *m = *mp; struct gif_softc *sc; struct ifnet *ifp; - void (*input)(struct ifnet *, struct mbuf *); uint8_t itos; + uint8_t family; int rxhprio; /* IP-in-IP header is caused by tunnel mode, so skip gif lookup */ @@ -830,8 +819,7 @@ gif_input(struct gif_tunnel *key, struct if (itos != ip->ip_tos) ip_tos_patch(ip, itos); - m->m_pkthdr.ph_family = AF_INET; - input = ipv4_input; + family = AF_INET; break; } #ifdef INET6 @@ -851,8 +839,7 @@ gif_input(struct gif_tunnel *key, struct CLR(ip6->ip6_flow, htonl(0xff << 20)); SET(ip6->ip6_flow, htonl(itos << 20)); - m->m_pkthdr.ph_family = AF_INET6; - input = ipv6_input; + family = AF_INET6; break; } #endif /* INET6 */ @@ -865,9 +852,8 @@ gif_input(struct gif_tunnel *key, struct shim = *mtod(m, uint32_t *) & MPLS_EXP_MASK; itos = (ntohl(shim) >> MPLS_EXP_OFFSET) << 5; - - m->m_pkthdr.ph_family = AF_MPLS; - input = mpls_input; + + family = AF_MPLS; break; } #endif /* MPLS */ @@ -904,15 +890,16 @@ gif_input(struct gif_tunnel *key, struct #if NBPFILTER > 0 { caddr_t if_bpf = ifp->if_bpf; - if (if_bpf) { - bpf_mtap_af(ifp->if_bpf, m->m_pkthdr.ph_family, - m, BPF_DIRECTION_IN); - } + if (if_bpf) + bpf_mtap_af(ifp->if_bpf, family, m, BPF_DIRECTION_IN); } #endif *mp = NULL; - (*input)(ifp, m); + + m->m_pkthdr.ph_family = family; + ifiq_enqueue(&ifp->if_rcv, m); + return (IPPROTO_DONE); drop: Index: if_gre.c =================================================================== RCS file: /cvs/src/sys/net/if_gre.c,v retrieving revision 1.155 diff -u -p -r1.155 if_gre.c --- if_gre.c 10 Nov 2019 11:44:10 -0000 1.155 +++ if_gre.c 7 May 2020 01:47:12 -0000 @@ -605,6 +605,8 @@ gre_clone_create(struct if_clone *ifc, i timeout_set_proc(&sc->sc_ka_hold, gre_keepalive_hold, sc); sc->sc_ka_state = GRE_KA_NONE; + if_ih_insert(ifp, l3_input, NULL); + if_counters_alloc(ifp); if_attach(ifp); if_alloc_sadl(ifp); @@ -634,6 +636,8 @@ gre_clone_destroy(struct ifnet *ifp) TAILQ_REMOVE(&gre_list, sc, sc_entry); NET_UNLOCK(); + if_ih_remove(ifp, l3_input, NULL); + if_detach(ifp); free(sc, M_DEVBUF, sizeof(*sc)); @@ -670,6 +674,8 @@ mgre_clone_create(struct if_clone *ifc, sc->sc_tunnel.t_df = htons(0); sc->sc_tunnel.t_ecn = ECN_ALLOWED; + if_ih_insert(ifp, l3_input, NULL); + if_counters_alloc(ifp); if_attach(ifp); if_alloc_sadl(ifp); @@ -691,6 +697,8 @@ mgre_clone_destroy(struct ifnet *ifp) mgre_down(sc); NET_UNLOCK(); + if_ih_remove(ifp, l3_input, NULL); + if_detach(ifp); free(sc, M_DEVBUF, sizeof(*sc)); @@ -1009,10 +1020,9 @@ gre_input_key(struct mbuf **mp, int *off caddr_t buf; struct gre_header *gh; struct gre_h_key *gkh; - void (*input)(struct ifnet *, struct mbuf *); struct mbuf *(*patch)(const struct gre_tunnel *, struct mbuf *, uint8_t *, uint8_t); - int bpf_af = AF_UNSPEC; /* bpf */ + uint8_t family = AF_UNSPEC; int mcast = 0; uint8_t itos; @@ -1115,19 +1125,13 @@ gre_input_key(struct mbuf **mp, int *off /* FALLTHROUGH */ } case htons(ETHERTYPE_IP): -#if NBPFILTER > 0 - bpf_af = AF_INET; -#endif + family = AF_INET; patch = gre_ipv4_patch; - input = ipv4_input; break; #ifdef INET6 case htons(ETHERTYPE_IPV6): -#if NBPFILTER > 0 - bpf_af = AF_INET6; -#endif + family = AF_INET6; patch = gre_ipv6_patch; - input = ipv6_input; break; #endif #ifdef MPLS @@ -1135,11 +1139,8 @@ gre_input_key(struct mbuf **mp, int *off mcast = M_MCAST|M_BCAST; /* fallthrough */ case htons(ETHERTYPE_MPLS): -#if NBPFILTER > 0 - bpf_af = AF_MPLS; -#endif + family = AF_MPLS; patch = gre_mpls_patch; - input = mpls_input; break; #endif case htons(0): @@ -1201,10 +1202,11 @@ gre_input_key(struct mbuf **mp, int *off #if NBPFILTER > 0 if (ifp->if_bpf) - bpf_mtap_af(ifp->if_bpf, bpf_af, m, BPF_DIRECTION_IN); + bpf_mtap_af(ifp->if_bpf, family, m, BPF_DIRECTION_IN); #endif - (*input)(ifp, m); + m->m_pkthdr.ph_family = family; + ifiq_enqueue(&ifp->if_rcv, m); return (IPPROTO_DONE); decline: *mp = m;