When if_input_process() will pass a mbuf to pseudo-interface handlers, they will change the `rcvif` pointer in the packet header. That's why we should not pass a ifp pointer to the handlers and instead let them look at the value of `rcvif`.
Diff below change if_input() and ether_input() to no longer take an ifp as argument. Ok? Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.325 diff -u -p -r1.325 if.c --- net/if.c 1 Apr 2015 04:00:55 -0000 1.325 +++ net/if.c 1 Apr 2015 14:09:39 -0000 @@ -496,7 +496,7 @@ if_input_process(void *xmq) ifp = m->m_pkthdr.rcvif; SLIST_FOREACH(ifih, &ifp->if_inputs, ifih_next) { - if ((*ifih->ifih_input)(ifp, NULL, m)) + if ((*ifih->ifih_input)(m, NULL)) break; } } Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v retrieving revision 1.232 diff -u -p -r1.232 if_bridge.c --- net/if_bridge.c 6 Feb 2015 22:10:43 -0000 1.232 +++ net/if_bridge.c 1 Apr 2015 14:11:00 -0000 @@ -1391,7 +1391,7 @@ bridge_input(struct ifnet *ifp, struct e BPF_DIRECTION_IN); #endif m->m_flags |= M_PROTO1; - ether_input(ifl->ifp, eh, m); + ether_input(m, eh); ifl->ifp->if_ipackets++; m = NULL; } @@ -1448,7 +1448,7 @@ bridge_input(struct ifnet *ifp, struct e m->m_pkthdr.ph_rtableid = ifl->ifp->if_rdomain; if (ifp->if_type == IFT_GIF) { m->m_flags |= M_PROTO1; - ether_input(ifl->ifp, eh, m); + ether_input(m, eh); m = NULL; } return (m); @@ -1624,7 +1624,7 @@ bridge_localbroadcast(struct bridge_soft BPF_DIRECTION_IN); #endif - ether_input(ifp, NULL, m1); + ether_input(m1, NULL); ifp->if_ipackets++; } Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.190 diff -u -p -r1.190 if_ethersubr.c --- net/if_ethersubr.c 17 Mar 2015 14:51:27 -0000 1.190 +++ net/if_ethersubr.c 1 Apr 2015 14:11:13 -0000 @@ -454,15 +454,15 @@ bad: * the ether header, which is provided separately. */ int -ether_input(struct ifnet *ifp0, void *hdr, struct mbuf *m) +ether_input(struct mbuf *m, void *hdr) { + struct ifnet *ifp0, *ifp; struct ether_header *eh = hdr; struct ifqueue *inq; u_int16_t etype; int s, llcfound = 0; struct llc *l; struct arpcom *ac; - struct ifnet *ifp = ifp0; #if NTRUNK > 0 int i = 0; #endif @@ -470,7 +470,9 @@ ether_input(struct ifnet *ifp0, void *hd struct ether_header *eh_tmp; #endif + /* mark incoming routing table */ + ifp = ifp0 = m->m_pkthdr.rcvif; m->m_pkthdr.ph_rtableid = ifp->if_rdomain; if (eh == NULL) { Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.113 diff -u -p -r1.113 if_vlan.c --- net/if_vlan.c 31 Mar 2015 11:47:09 -0000 1.113 +++ net/if_vlan.c 1 Apr 2015 14:05:23 -0000 @@ -352,7 +352,7 @@ vlan_input(struct ether_header *eh, stru } ifv->ifv_if.if_ipackets++; - ether_input(&ifv->ifv_if, eh, m); + ether_input(m, eh); return (0); } Index: net/if_vxlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vxlan.c,v retrieving revision 1.22 diff -u -p -r1.22 if_vxlan.c --- net/if_vxlan.c 14 Mar 2015 03:38:51 -0000 1.22 +++ net/if_vxlan.c 1 Apr 2015 14:05:36 -0000 @@ -537,7 +537,7 @@ vxlan_lookup(struct mbuf *m, struct udph #endif ifp->if_ipackets++; - ether_input(ifp, eh, m); + ether_input(m, eh); /* success */ return (1); Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.23 diff -u -p -r1.23 if_var.h --- net/if_var.h 1 Apr 2015 04:00:55 -0000 1.23 +++ net/if_var.h 1 Apr 2015 14:09:30 -0000 @@ -114,7 +114,7 @@ struct ifqueue { */ struct ifih { SLIST_ENTRY(ifih) ifih_next; - int (*ifih_input)(struct ifnet *, void *, struct mbuf *); + int (*ifih_input)(struct mbuf *, void *); }; /* @@ -422,7 +422,7 @@ void ether_input_mbuf(struct ifnet *, st void ether_ifattach(struct ifnet *); void ether_ifdetach(struct ifnet *); int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t); -int ether_input(struct ifnet *, void *, struct mbuf *); +int ether_input(struct mbuf *, void *); int ether_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); char *ether_sprintf(u_char *); Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.248 diff -u -p -r1.248 ip_carp.c --- netinet/ip_carp.c 14 Mar 2015 03:38:51 -0000 1.248 +++ netinet/ip_carp.c 1 Apr 2015 14:06:56 -0000 @@ -1463,7 +1463,7 @@ carp_input(struct ifnet *ifp0, struct et ETHER_HDR_LEN, m0, BPF_DIRECTION_IN, NULL); #endif vh->sc_if.if_ipackets++; - ether_input(&vh->sc_if, &eh, m0); + ether_input(m0, &eh); } return (1); } @@ -1479,7 +1479,7 @@ carp_input(struct ifnet *ifp0, struct et BPF_DIRECTION_IN, NULL); #endif ifp->if_ipackets++; - ether_input(ifp, &eh, m); + ether_input(m, &eh); return (0); } Index: arch/sparc/dev/if_ie.c =================================================================== RCS file: /cvs/src/sys/arch/sparc/dev/if_ie.c,v retrieving revision 1.50 diff -u -p -r1.50 if_ie.c --- arch/sparc/dev/if_ie.c 11 Jan 2015 15:35:38 -0000 1.50 +++ arch/sparc/dev/if_ie.c 1 Apr 2015 14:12:45 -0000 @@ -1354,7 +1354,7 @@ ie_readframe(sc, num) /* * Finally pass this packet up to higher layers. */ - ether_input(&sc->sc_arpcom.ac_if, &eh, m); + ether_input(m, &eh); } static void