Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.611 diff -u -p -r1.611 if.c --- net/if.c 30 Jun 2020 09:31:38 -0000 1.611 +++ net/if.c 9 Jul 2020 02:28:19 -0000 @@ -631,8 +631,6 @@ if_attach_common(struct ifnet *ifp) if (ifp->if_enqueue == NULL) ifp->if_enqueue = if_enqueue_ifq; ifp->if_llprio = IFQ_DEFPRIO; - - SRPL_INIT(&ifp->if_inputs); } void @@ -805,109 +803,6 @@ if_output_local(struct ifnet *ifp, struc return (ifiq_enqueue(ifiq, m) == 0 ? 0 : ENOBUFS); } -struct ifih { - SRPL_ENTRY(ifih) ifih_next; - int (*ifih_input)(struct ifnet *, struct mbuf *, - void *); - void *ifih_cookie; - int ifih_refcnt; - struct refcnt ifih_srpcnt; -}; - -void if_ih_ref(void *, void *); -void if_ih_unref(void *, void *); - -struct srpl_rc ifih_rc = SRPL_RC_INITIALIZER(if_ih_ref, if_ih_unref, NULL); - -void -if_ih_insert(struct ifnet *ifp, int (*input)(struct ifnet *, struct mbuf *, - void *), void *cookie) -{ - struct ifih *ifih; - - /* the kernel lock guarantees serialised modifications to if_inputs */ - KERNEL_ASSERT_LOCKED(); - - SRPL_FOREACH_LOCKED(ifih, &ifp->if_inputs, ifih_next) { - if (ifih->ifih_input == input && ifih->ifih_cookie == cookie) { - ifih->ifih_refcnt++; - break; - } - } - - if (ifih == NULL) { - ifih = malloc(sizeof(*ifih), M_DEVBUF, M_WAITOK); - - ifih->ifih_input = input; - ifih->ifih_cookie = cookie; - ifih->ifih_refcnt = 1; - refcnt_init(&ifih->ifih_srpcnt); - SRPL_INSERT_HEAD_LOCKED(&ifih_rc, &ifp->if_inputs, - ifih, ifih_next); - } -} - -void -if_ih_ref(void *null, void *i) -{ - struct ifih *ifih = i; - - refcnt_take(&ifih->ifih_srpcnt); -} - -void -if_ih_unref(void *null, void *i) -{ - struct ifih *ifih = i; - - refcnt_rele_wake(&ifih->ifih_srpcnt); -} - -void -if_ih_remove(struct ifnet *ifp, int (*input)(struct ifnet *, struct mbuf *, - void *), void *cookie) -{ - struct ifih *ifih; - - /* the kernel lock guarantees serialised modifications to if_inputs */ - KERNEL_ASSERT_LOCKED(); - - SRPL_FOREACH_LOCKED(ifih, &ifp->if_inputs, ifih_next) { - if (ifih->ifih_input == input && ifih->ifih_cookie == cookie) - break; - } - - KASSERT(ifih != NULL); - - if (--ifih->ifih_refcnt == 0) { - SRPL_REMOVE_LOCKED(&ifih_rc, &ifp->if_inputs, ifih, - ifih, ifih_next); - - refcnt_finalize(&ifih->ifih_srpcnt, "ifihrm"); - free(ifih, M_DEVBUF, sizeof(*ifih)); - } -} - -static void -if_ih_input(struct ifnet *ifp, struct mbuf *m) -{ - struct ifih *ifih; - struct srp_ref sr; - - /* - * Pass this mbuf to all input handlers of its - * interface until it is consumed. - */ - SRPL_FOREACH(ifih, &sr, &ifp->if_inputs, ifih_next) { - if ((*ifih->ifih_input)(ifp, m, ifih->ifih_cookie)) - break; - } - SRPL_LEAVE(&sr); - - if (ifih == NULL) - m_freem(m); -} - void if_input_process(struct ifnet *ifp, struct mbuf_list *ml) { @@ -933,7 +828,7 @@ if_input_process(struct ifnet *ifp, stru */ NET_LOCK(); while ((m = ml_dequeue(ml)) != NULL) - if_ih_input(ifp, m); + (*ifp->if_input)(ifp, m); NET_UNLOCK(); } @@ -960,7 +855,7 @@ if_vinput(struct ifnet *ifp, struct mbuf } #endif - if_ih_input(ifp, m); + (*ifp->if_input)(ifp, m); } void Index: net/if_aggr.c =================================================================== RCS file: /cvs/src/sys/net/if_aggr.c,v retrieving revision 1.31 diff -u -p -r1.31 if_aggr.c --- net/if_aggr.c 17 Jun 2020 06:45:22 -0000 1.31 +++ net/if_aggr.c 9 Jul 2020 02:28:19 -0000 @@ -332,6 +332,7 @@ struct aggr_port { uint32_t p_mtu; int (*p_ioctl)(struct ifnet *, u_long, caddr_t); + void (*p_input)(struct ifnet *, struct mbuf *); int (*p_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); @@ -723,13 +724,14 @@ aggr_eh_is_slow(const struct ether_heade eh->ether_type == htons(ETHERTYPE_SLOW)); } -static int -aggr_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) +static void +aggr_input(struct ifnet *ifp0, struct mbuf *m) { - struct ether_header *eh; - struct aggr_port *p = cookie; + struct arpcom *ac0 = (struct arpcom *)ifp0; + struct aggr_port *p = ac0->ac_trunkport; struct aggr_softc *sc = p->p_aggr; struct ifnet *ifp = &sc->sc_if; + struct ether_header *eh; int hlen = sizeof(*eh); if (!ISSET(ifp->if_flags, IFF_RUNNING)) @@ -745,7 +747,7 @@ aggr_input(struct ifnet *ifp0, struct mb m = m_pullup(m, hlen); if (m == NULL) { /* short++ */ - return (1); + return; } eh = mtod(m, struct ether_header *); } @@ -756,7 +758,7 @@ aggr_input(struct ifnet *ifp0, struct mb case SLOWPROTOCOLS_SUBTYPE_LACP_MARKER: if (mq_enqueue(&p->p_rxm_mq, m) == 0) task_add(systq, &p->p_rxm_task); - return (1); + return; default: break; } @@ -770,11 +772,10 @@ aggr_input(struct ifnet *ifp0, struct mb if_vinput(ifp, m); - return (1); + return; drop: m_freem(m); - return (1); } static int @@ -1072,6 +1073,10 @@ aggr_add_port(struct aggr_softc *sc, con if (ifp0->if_type != IFT_ETHER) return (EPROTONOSUPPORT); + error = ether_is_brport(ifp0); + if (error != 0) + return (error); + if (ifp0->if_hardmtu < ifp->if_mtu) return (ENOBUFS); @@ -1161,12 +1166,18 @@ aggr_add_port(struct aggr_softc *sc, con aggr_update_capabilities(sc); + /* + * use (and modification) of ifp->if_input and ac->ac_trunkport + * is protected by NET_LOCK. + */ + ac0->ac_trunkport = p; + ifp0->if_input = aggr_input; + /* make sure p is visible before handlers can run */ membar_producer(); ifp0->if_ioctl = aggr_p_ioctl; ifp0->if_output = aggr_p_output; - if_ih_insert(ifp0, aggr_input, p); aggr_mux(sc, p, LACP_MUX_E_BEGIN); aggr_rxm(sc, p, LACP_RXM_E_BEGIN); @@ -1385,10 +1396,13 @@ aggr_p_dtor(struct aggr_softc *sc, struc timeout_del(&p->p_current_while_timer); timeout_del(&p->p_wait_while_timer); - if_ih_remove(ifp0, aggr_input, p); + /* + * use (and modification) of ifp->if_input and ac->ac_trunkport + * is protected by NET_LOCK. + */ ac0->ac_trunkport = NULL; - + ifp0->if_input = p->p_input; ifp0->if_ioctl = p->p_ioctl; ifp0->if_output = p->p_output; Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v retrieving revision 1.340 diff -u -p -r1.340 if_bridge.c --- net/if_bridge.c 24 Jun 2020 22:03:42 -0000 1.340 +++ net/if_bridge.c 9 Jul 2020 02:28:19 -0000 @@ -109,7 +109,8 @@ void bridge_ifdetach(void *); void bridge_spandetach(void *); int bridge_ifremove(struct bridge_iflist *); void bridge_spanremove(struct bridge_iflist *); -int bridge_input(struct ifnet *, struct mbuf *, void *); +struct mbuf * + bridge_input(struct ifnet *, struct mbuf *, void *); void bridge_process(struct ifnet *, struct mbuf *); void bridgeintr_frame(struct ifnet *, struct ifnet *, struct mbuf *); void bridge_bifgetstp(struct bridge_softc *, struct bridge_iflist *, @@ -149,6 +150,11 @@ struct niqueue bridgeintrq = NIQUEUE_INI struct if_clone bridge_cloner = IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); +const struct ether_brport bridge_brport = { + bridge_input, + NULL, +}; + void bridgeattach(int n) { @@ -198,8 +204,6 @@ bridge_clone_create(struct if_clone *ifc DLT_EN10MB, ETHER_HDR_LEN); #endif - if_ih_insert(ifp, ether_input, NULL); - return (0); } @@ -236,10 +240,6 @@ bridge_clone_destroy(struct ifnet *ifp) /* Undo pseudo-driver changes. */ if_deactivate(ifp); - if_ih_remove(ifp, ether_input, NULL); - - KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs)); - if_detach(ifp); free(sc, M_DEVBUF, sizeof *sc); @@ -296,6 +296,9 @@ bridge_ioctl(struct ifnet *ifp, u_long c error = EBUSY; break; } + error = ether_is_brport(ifp); + if (error != 0) + break; /* If it's in the span list, it can't be a member. */ SMR_SLIST_FOREACH_LOCKED(bif, &sc->sc_spanlist, bif_next) { @@ -329,7 +332,7 @@ bridge_ioctl(struct ifnet *ifp, u_long c ifs->if_bridgeidx = ifp->if_index; task_set(&bif->bif_dtask, bridge_ifdetach, bif); if_detachhook_add(ifs, &bif->bif_dtask); - if_ih_insert(bif->ifp, bridge_input, NULL); + ether_set_brport(bif->ifp, &bridge_brport); SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_iflist, bif, bif_next); break; case SIOCBRDGDEL: @@ -550,7 +553,7 @@ bridge_ifremove(struct bridge_iflist *bi SMR_SLIST_REMOVE_LOCKED(&sc->sc_iflist, bif, bridge_iflist, bif_next); if_detachhook_del(bif->ifp, &bif->bif_dtask); - if_ih_remove(bif->ifp, bridge_input, NULL); + ether_clr_brport(bif->ifp); smr_barrier(); @@ -1095,19 +1098,19 @@ bridge_ourether(struct ifnet *ifp, uint8 * Receive input from an interface. Queue the packet for bridging if its * not for us, and schedule an interrupt. */ -int -bridge_input(struct ifnet *ifp, struct mbuf *m, void *cookie) +struct mbuf * +bridge_input(struct ifnet *ifp, struct mbuf *m, void *null) { KASSERT(m->m_flags & M_PKTHDR); if (m->m_flags & M_PROTO1) { m->m_flags &= ~M_PROTO1; - return (0); + return (m); } niq_enqueue(&bridgeintrq, m); - return (1); + return (NULL); } void Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.261 diff -u -p -r1.261 if_ethersubr.c --- net/if_ethersubr.c 24 Nov 2019 07:50:55 -0000 1.261 +++ net/if_ethersubr.c 9 Jul 2020 02:28:19 -0000 @@ -86,6 +86,7 @@ didn't get a copy, you may request one f #include #include #include +#include #include #include @@ -343,32 +344,160 @@ ether_output(struct ifnet *ifp, struct m return (if_enqueue(ifp, m)); } +int +ether_is_brport(struct ifnet *ifp) +{ + struct arpcom *ac = (struct arpcom *)ifp; + + NET_ASSERT_LOCKED(); + if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL) + return (EBUSY); + + return (0); +} + +void +ether_set_brport(struct ifnet *ifp, const struct ether_brport *eb) +{ + struct arpcom *ac = (struct arpcom *)ifp; + + NET_ASSERT_LOCKED(); + KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL, + "%s setting an already set brport", ifp->if_xname); + + SMR_PTR_SET_LOCKED(&ac->ac_brport, eb); +} + +void +ether_clr_brport(struct ifnet *ifp) +{ + struct arpcom *ac = (struct arpcom *)ifp; + + NET_ASSERT_LOCKED(); + KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL, + "%s clearing an already clear brport", ifp->if_xname); + + SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL); +} + /* - * Process a received Ethernet packet; - * the packet is in the mbuf chain m without - * the ether header, which is provided separately. + * Process a received Ethernet packet. + * + * Ethernet input has several "phases" of filtering packets to + * support virtual/pseudo interfaces before actual layer 3 protocol + * handling. + * + * First phase: + * + * The first phase supports drivers that aggregate multiple Ethernet + * ports into a single logical interface, ie, aggr(4) and trunk(4). + * These drivers intercept packets by swapping out the if_input handler + * on the "port" interfaces to steal the packets before they get here + * to ether_input(). */ -int -ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie) + +void +ether_input(struct ifnet *ifp, struct mbuf *m) { - struct ether_header *eh; void (*input)(struct ifnet *, struct mbuf *); + struct ether_header *eh; u_int16_t etype; struct arpcom *ac; + const struct ether_brport *eb; + unsigned int sdelim = 0; /* Drop short frames */ - if (m->m_len < ETHER_HDR_LEN) - goto dropanyway; + if (m->m_len < sizeof(*eh)) + goto drop; + + /* + * Second phase: service delimited packet filtering. + * + * Let vlan(4) and svlan(4) look at "service delimited" + * packets. If a virtual interface does not exist to take + * those packets, they're returned to ether_input() so a + * bridge can have a go at forwarding them. + */ + + eh = mtod(m, struct ether_header *); + etype = ntohs(eh->ether_type); + +#if NVLAN > 0 + if (ISSET(m->m_flags, M_VLANTAG)) { + m = vlan_input(ifp, m); + if (m == NULL) + return; + + sdelim = 1; + } else /* <-- avoid calling vlan_input again */ +#endif /* NVLAN > 0 */ + if (etype == ETHERTYPE_VLAN || + etype == ETHERTYPE_QINQ) { +#if NVLAN > 0 + m = vlan_input(ifp, m); + if (m == NULL) + return; +#endif /* NVLAN > 0 */ + + sdelim = 1; + } + + /* + * Third phase: bridge processing. + * + * Give the packet to a bridge interface, ie, bridge(4), + * switch(4), and tpmr(4), if it is configured. A bridge + * may take the packet and forward it to another port, or it + * may return it here to ether_input() to support local + * delivery to this port. + */ ac = (struct arpcom *)ifp; + + smr_read_enter(); + eb = SMR_PTR_GET(&ac->ac_brport); + if (eb != NULL) { + m = (*eb->eb_input)(ifp, m, eb->eb_port); + if (m == NULL) + return; + } + smr_read_leave(); + + /* + * Fourth phase: drop service delimited packets. + * + * If the packet has a tag, and a bridge didn't want it, + * it's not for this port. + */ + + if (sdelim) + goto drop; + eh = mtod(m, struct ether_header *); - /* Is the packet for us? */ + /* + * Fifth phase: destination address check. + * + * Is the packet specifically addressed to this port? + */ if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) { +#if NCARP > 0 + /* + * If it's not for this port, it could be for carp(4). + */ + if (ifp->if_type != IFT_CARP && + !SRPL_EMPTY_LOCKED(&ifp->if_carp)) { + m = carp_input(ifp, m); + if (m == NULL) + return; + } +#endif - /* If not, it must be multicast or broadcast to go further */ + /* + * If not, it must be multicast or broadcast to go further. + */ if (!ETHER_IS_MULTICAST(eh->ether_dhost)) - goto dropanyway; + goto drop; /* * If this is not a simplex interface, drop the packet @@ -377,24 +506,21 @@ ether_input(struct ifnet *ifp, struct mb if ((ifp->if_flags & IFF_SIMPLEX) == 0) { if (memcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0) - goto dropanyway; + goto drop; } if (ETHER_IS_BROADCAST(eh->ether_dhost)) m->m_flags |= M_BCAST; else m->m_flags |= M_MCAST; - ifp->if_imcasts++; } /* - * HW vlan tagged packets that were not collected by vlan(4) must - * be dropped now. + * Sixth phase: protocol demux. + * + * At this point it is known that the packet is destined + * for layer 3 protocol handling on the local port. */ - if (m->m_flags & M_VLANTAG) - goto dropanyway; - - etype = ntohs(eh->ether_type); switch (etype) { case ETHERTYPE_IP: @@ -403,20 +529,17 @@ ether_input(struct ifnet *ifp, struct mb case ETHERTYPE_ARP: if (ifp->if_flags & IFF_NOARP) - goto dropanyway; + goto drop; input = arpinput; break; case ETHERTYPE_REVARP: if (ifp->if_flags & IFF_NOARP) - goto dropanyway; + goto drop; input = revarpinput; break; #ifdef INET6 - /* - * Schedule IPv6 software interrupt for incoming IPv6 packet. - */ case ETHERTYPE_IPV6: input = ipv6_input; break; @@ -425,14 +548,14 @@ ether_input(struct ifnet *ifp, struct mb case ETHERTYPE_PPPOEDISC: case ETHERTYPE_PPPOE: if (m->m_flags & (M_MCAST | M_BCAST)) - goto dropanyway; + goto drop; #ifdef PIPEX if (pipex_enable) { struct pipex_session *session; if ((session = pipex_pppoe_lookup_session(m)) != NULL) { pipex_pppoe_input(m, session); - return (1); + return; } } #endif @@ -440,7 +563,7 @@ ether_input(struct ifnet *ifp, struct mb niq_enqueue(&pppoediscinq, m); else niq_enqueue(&pppoeinq, m); - return (1); + return; #endif #ifdef MPLS case ETHERTYPE_MPLS: @@ -451,18 +574,17 @@ ether_input(struct ifnet *ifp, struct mb #if NBPE > 0 case ETHERTYPE_PBB: bpe_input(ifp, m); - return (1); + return; #endif default: - goto dropanyway; + goto drop; } m_adj(m, sizeof(*eh)); (*input)(ifp, m); - return (1); -dropanyway: + return; +drop: m_freem(m); - return (1); } /* @@ -522,12 +644,11 @@ ether_ifattach(struct ifnet *ifp) ifp->if_addrlen = ETHER_ADDR_LEN; ifp->if_hdrlen = ETHER_HDR_LEN; ifp->if_mtu = ETHERMTU; + ifp->if_input = ether_input; if (ifp->if_output == NULL) ifp->if_output = ether_output; ifp->if_rtrequest = ether_rtrequest; - if_ih_insert(ifp, ether_input, NULL); - if (ifp->if_hardmtu == 0) ifp->if_hardmtu = ETHERMTU; @@ -547,10 +668,6 @@ ether_ifdetach(struct ifnet *ifp) /* Undo pseudo-driver changes. */ if_deactivate(ifp); - - if_ih_remove(ifp, ether_input, NULL); - - KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs)); for (enm = LIST_FIRST(&ac->ac_multiaddrs); enm != NULL; Index: net/if_loop.c =================================================================== RCS file: /cvs/src/sys/net/if_loop.c,v retrieving revision 1.90 diff -u -p -r1.90 if_loop.c --- net/if_loop.c 8 Jan 2020 09:09:10 -0000 1.90 +++ net/if_loop.c 9 Jul 2020 02:28:19 -0000 @@ -143,7 +143,7 @@ int loioctl(struct ifnet *, u_long, caddr_t); void loopattach(int); void lortrequest(struct ifnet *, int, struct rtentry *); -int loinput(struct ifnet *, struct mbuf *, void *); +void loinput(struct ifnet *, struct mbuf *); int looutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); @@ -175,6 +175,7 @@ loop_clone_create(struct if_clone *ifc, ifp->if_xflags = IFXF_CLONED; ifp->if_rtrequest = lortrequest; ifp->if_ioctl = loioctl; + ifp->if_input = loinput; ifp->if_output = looutput; ifp->if_type = IFT_LOOP; ifp->if_hdrlen = sizeof(u_int32_t); @@ -188,7 +189,6 @@ loop_clone_create(struct if_clone *ifc, #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif - if_ih_insert(ifp, loinput, NULL); return (0); } @@ -218,7 +218,6 @@ loop_clone_destroy(struct ifnet *ifp) rdomain = ifp->if_rdomain; } - if_ih_remove(ifp, loinput, NULL); if_detach(ifp); free(ifp, M_DEVBUF, sizeof(*ifp)); @@ -228,8 +227,8 @@ loop_clone_destroy(struct ifnet *ifp) return (0); } -int -loinput(struct ifnet *ifp, struct mbuf *m, void *cookie) +void +loinput(struct ifnet *ifp, struct mbuf *m) { int error; @@ -239,8 +238,6 @@ loinput(struct ifnet *ifp, struct mbuf * error = if_input_local(ifp, m, m->m_pkthdr.ph_family); if (error) ifp->if_ierrors++; - - return (1); } int Index: net/if_switch.c =================================================================== RCS file: /cvs/src/sys/net/if_switch.c,v retrieving revision 1.30 diff -u -p -r1.30 if_switch.c --- net/if_switch.c 6 Nov 2019 03:51:26 -0000 1.30 +++ net/if_switch.c 9 Jul 2020 02:28:19 -0000 @@ -68,7 +68,8 @@ int switch_port_add(struct switch_softc void switch_port_detach(void *); int switch_port_del(struct switch_softc *, struct ifbreq *); int switch_port_list(struct switch_softc *, struct ifbifconf *); -int switch_input(struct ifnet *, struct mbuf *, void *); +struct mbuf * + switch_input(struct ifnet *, struct mbuf *, void *); struct mbuf *switch_port_ingress(struct switch_softc *, struct ifnet *, struct mbuf *); @@ -119,6 +120,11 @@ struct rwlock switch_ifs_lk = RWLOCK_INI struct pool swfcl_pool; +const struct ether_brport switch_brport = { + switch_input, + NULL, +}; + void switchattach(int n) { @@ -506,8 +512,12 @@ switch_port_add(struct switch_softc *sc, if ((ifs = ifunit(req->ifbr_ifsname)) == NULL) return (ENOENT); - if (ifs->if_bridgeidx != 0) - return (EBUSY); + if (ifs->if_type != IFT_ETHER) + return (EPROTONOSUPPORT); + + error = ether_is_brport(ifs); + if (error != 0) + return (error); if (ifs->if_switchport != NULL) { swpo = (struct switch_port *)ifs->if_switchport; @@ -517,21 +527,18 @@ switch_port_add(struct switch_softc *sc, return (EBUSY); } - if (ifs->if_type == IFT_ETHER) { - if ((error = ifpromisc(ifs, 1)) != 0) - return (error); - } + if ((error = ifpromisc(ifs, 1)) != 0) + return (error); swpo = malloc(sizeof(*swpo), M_DEVBUF, M_NOWAIT|M_ZERO); if (swpo == NULL) { - if (ifs->if_type == IFT_ETHER) - ifpromisc(ifs, 0); + ifpromisc(ifs, 0); return (ENOMEM); } swpo->swpo_switch = sc; swpo->swpo_ifindex = ifs->if_index; ifs->if_switchport = (caddr_t)swpo; - if_ih_insert(ifs, switch_input, NULL); + ether_set_brport(ifs, &switch_brport); swpo->swpo_port_no = swofp_assign_portno(sc, ifs->if_index); task_set(&swpo->swpo_dtask, switch_port_detach, ifs); if_detachhook_add(ifs, &swpo->swpo_dtask); @@ -603,7 +610,7 @@ switch_port_detach(void *arg) ifp->if_switchport = NULL; if_detachhook_del(ifp, &swpo->swpo_dtask); ifpromisc(ifp, 0); - if_ih_remove(ifp, switch_input, NULL); + ether_clr_brport(ifp); TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); free(swpo, M_DEVBUF, sizeof(*swpo)); } @@ -633,19 +640,19 @@ switch_port_del(struct switch_softc *sc, return (error); } -int -switch_input(struct ifnet *ifp, struct mbuf *m, void *cookie) +struct mbuf * +switch_input(struct ifnet *ifp, struct mbuf *m, void *null) { KASSERT(m->m_flags & M_PKTHDR); if (m->m_flags & M_PROTO1) { m->m_flags &= ~M_PROTO1; - return (0); + return (m); } niq_enqueue(&switchintrq, m); - return (1); + return (NULL); } Index: net/if_tpmr.c =================================================================== RCS file: /cvs/src/sys/net/if_tpmr.c,v retrieving revision 1.10 diff -u -p -r1.10 if_tpmr.c --- net/if_tpmr.c 12 Apr 2020 06:56:37 -0000 1.10 +++ net/if_tpmr.c 9 Jul 2020 02:28:19 -0000 @@ -91,6 +91,8 @@ struct tpmr_port { struct tpmr_softc *p_tpmr; unsigned int p_slot; + + struct ether_brport p_brport; }; struct tpmr_softc { @@ -281,10 +283,10 @@ tpmr_pf(struct ifnet *ifp0, int dir, str } #endif /* NPF > 0 */ -static int -tpmr_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) +static struct mbuf * +tpmr_input(struct ifnet *ifp0, struct mbuf *m, void *brport) { - struct tpmr_port *p = cookie; + struct tpmr_port *p = brport; struct tpmr_softc *sc = p->p_tpmr; struct ifnet *ifp = &sc->sc_if; struct tpmr_port *pn; @@ -317,7 +319,7 @@ tpmr_input(struct ifnet *ifp0, struct mb #if NPF > 0 if (!ISSET(ifp->if_flags, IFF_LINK1) && (m = tpmr_pf(ifp0, PF_IN, m)) == NULL) - return (1); + return (NULL); #endif len = m->m_pkthdr.len; @@ -353,11 +355,11 @@ tpmr_input(struct ifnet *ifp0, struct mb } smr_read_leave(); - return (1); + return (NULL); drop: m_freem(m); - return (1); + return (NULL); } static int @@ -520,7 +522,6 @@ tpmr_add_port(struct tpmr_softc *sc, con { struct ifnet *ifp = &sc->sc_if; struct ifnet *ifp0; - struct arpcom *ac0; struct tpmr_port **pp; struct tpmr_port *p; int i; @@ -537,9 +538,9 @@ tpmr_add_port(struct tpmr_softc *sc, con if (ifp0->if_type != IFT_ETHER) return (EPROTONOSUPPORT); - ac0 = (struct arpcom *)ifp0; - if (ac0->ac_trunkport != NULL) - return (EBUSY); + error = ether_is_brport(ifp0); + if (error != 0) + return (error); /* let's try */ @@ -571,6 +572,9 @@ tpmr_add_port(struct tpmr_softc *sc, con task_set(&p->p_dtask, tpmr_p_detach, p); if_detachhook_add(ifp0, &p->p_dtask); + p->p_brport.eb_input = tpmr_input; + p->p_brport.eb_port = p; + /* commit */ DPRINTF(sc, "%s %s trunkport: creating port\n", ifp->if_xname, ifp0->if_xname); @@ -584,12 +588,9 @@ tpmr_add_port(struct tpmr_softc *sc, con p->p_slot = i; - ac0->ac_trunkport = p; - /* make sure p is visible before handlers can run */ - membar_producer(); + ether_set_brport(ifp0, &p->p_brport); ifp0->if_ioctl = tpmr_p_ioctl; ifp0->if_output = tpmr_p_output; - if_ih_insert(ifp0, tpmr_input, p); SMR_PTR_SET_LOCKED(pp, p); @@ -706,18 +707,14 @@ tpmr_p_dtor(struct tpmr_softc *sc, struc { struct ifnet *ifp = &sc->sc_if; struct ifnet *ifp0 = p->p_ifp0; - struct arpcom *ac0 = (struct arpcom *)ifp0; DPRINTF(sc, "%s %s: destroying port\n", ifp->if_xname, ifp0->if_xname); - if_ih_remove(ifp0, tpmr_input, p); - ifp0->if_ioctl = p->p_ioctl; ifp0->if_output = p->p_output; - membar_producer(); - ac0->ac_trunkport = NULL; + ether_clr_brport(ifp0); sc->sc_nports--; SMR_PTR_SET_LOCKED(&sc->sc_ports[p->p_slot], NULL); Index: net/if_trunk.c =================================================================== RCS file: /cvs/src/sys/net/if_trunk.c,v retrieving revision 1.146 diff -u -p -r1.146 if_trunk.c --- net/if_trunk.c 17 Jun 2020 06:45:22 -0000 1.146 +++ net/if_trunk.c 9 Jul 2020 02:28:19 -0000 @@ -76,7 +76,7 @@ int trunk_ether_delmulti(struct trunk_s void trunk_ether_purgemulti(struct trunk_softc *); int trunk_ether_cmdmulti(struct trunk_port *, u_long); int trunk_ioctl_allports(struct trunk_softc *, u_long, caddr_t); -int trunk_input(struct ifnet *, struct mbuf *, void *); +void trunk_input(struct ifnet *, struct mbuf *); void trunk_start(struct ifnet *); void trunk_init(struct ifnet *); void trunk_stop(struct ifnet *); @@ -380,9 +380,11 @@ trunk_port_create(struct trunk_softc *tr if (tr->tr_port_create != NULL) error = (*tr->tr_port_create)(tp); - ac0->ac_trunkport = tp; /* Change input handler of the physical interface. */ - if_ih_insert(ifp, trunk_input, tp); + tp->tp_input = ifp->if_input; + NET_ASSERT_LOCKED(); + ac0->ac_trunkport = tp; + ifp->if_input = trunk_input; return (error); } @@ -413,7 +415,8 @@ trunk_port_destroy(struct trunk_port *tp struct arpcom *ac0 = (struct arpcom *)ifp; /* Restore previous input handler. */ - if_ih_remove(ifp, trunk_input, tp); + NET_ASSERT_LOCKED(); + ifp->if_input = tp->tp_input; ac0->ac_trunkport = NULL; /* Remove multicast addresses from this port */ @@ -649,15 +652,24 @@ trunk_ioctl(struct ifnet *ifp, u_long cm error = EPROTONOSUPPORT; break; } + /* + * Use of ifp->if_input and ac->ac_trunkport is + * protected by NET_LOCK, but that may not be true + * in the future. The below comment and code flow is + * maintained to help in that future. + * * Serialize modifications to the trunk and trunk * ports via the ifih SRP: detaching trunk_input * from the trunk port will require all currently * running trunk_input's on this port to finish * granting us an exclusive access to it. */ - SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) - if_ih_remove(tp->tp_if, trunk_input, tp); + NET_ASSERT_LOCKED(); + SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) { + /* if_ih_remove(tp->tp_if, trunk_input, tp); */ + tp->tp_if->if_input = tp->tp_input; + } if (tr->tr_proto != TRUNK_PROTO_NONE) error = tr->tr_detach(tr); if (error != 0) @@ -671,9 +683,11 @@ trunk_ioctl(struct ifnet *ifp, u_long cm tr->tr_proto = trunk_protos[i].ti_proto; if (tr->tr_proto != TRUNK_PROTO_NONE) error = trunk_protos[i].ti_attach(tr); - SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) - if_ih_insert(tp->tp_if, - trunk_input, tp); + SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) { + /* if_ih_insert(tp->tp_if, + trunk_input, tp); */ + tp->tp_if->if_input = trunk_input; + } /* Update trunk capabilities */ tr->tr_capabilities = trunk_capabilities(tr); goto out; @@ -1118,14 +1132,18 @@ trunk_stop(struct ifnet *ifp) (*tr->tr_stop)(tr); } -int -trunk_input(struct ifnet *ifp, struct mbuf *m, void *cookie) +void +trunk_input(struct ifnet *ifp, struct mbuf *m) { - struct trunk_softc *tr; + struct arpcom *ac0 = (struct arpcom *)ifp; struct trunk_port *tp; + struct trunk_softc *tr; struct ifnet *trifp = NULL; struct ether_header *eh; + if (m->m_len < sizeof(*eh)) + goto bad; + eh = mtod(m, struct ether_header *); if (ETHER_IS_MULTICAST(eh->ether_dhost)) ifp->if_imcasts++; @@ -1134,7 +1152,7 @@ trunk_input(struct ifnet *ifp, struct mb if (ifp->if_type != IFT_IEEE8023ADLAG) goto bad; - tp = (struct trunk_port *)cookie; + tp = (struct trunk_port *)ac0->ac_trunkport; if ((tr = (struct trunk_softc *)tp->tp_trunk) == NULL) goto bad; @@ -1147,7 +1165,7 @@ trunk_input(struct ifnet *ifp, struct mb * We stop here if the packet has been consumed * by the protocol routine. */ - return (1); + return; } if ((trifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) @@ -1163,19 +1181,18 @@ trunk_input(struct ifnet *ifp, struct mb if (bcmp(&tr->tr_ac.ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN)) { m_freem(m); - return (1); + return; } } if_vinput(trifp, m); - return (1); + return; bad: if (trifp != NULL) trifp->if_ierrors++; m_freem(m); - return (1); } int Index: net/if_trunk.h =================================================================== RCS file: /cvs/src/sys/net/if_trunk.h,v retrieving revision 1.29 diff -u -p -r1.29 if_trunk.h --- net/if_trunk.h 7 Nov 2019 07:36:32 -0000 1.29 +++ net/if_trunk.h 9 Jul 2020 02:28:19 -0000 @@ -172,6 +172,7 @@ struct trunk_port { int (*tp_ioctl)(struct ifnet *, u_long, caddr_t); int (*tp_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); + void (*tp_input)(struct ifnet *, struct mbuf *); SLIST_ENTRY(trunk_port) tp_entries; }; Index: net/if_tun.c =================================================================== RCS file: /cvs/src/sys/net/if_tun.c,v retrieving revision 1.222 diff -u -p -r1.222 if_tun.c --- net/if_tun.c 13 May 2020 00:48:06 -0000 1.222 +++ net/if_tun.c 9 Jul 2020 02:28:19 -0000 @@ -115,7 +115,7 @@ int tun_dev_poll(dev_t, int, struct proc int tun_dev_kqfilter(dev_t, struct knote *); int tun_ioctl(struct ifnet *, u_long, caddr_t); -int tun_input(struct ifnet *, struct mbuf *, void *); +void tun_input(struct ifnet *, struct mbuf *); int tun_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int tun_enqueue(struct ifnet *, struct mbuf *); @@ -240,6 +240,7 @@ tun_create(struct if_clone *ifc, int uni if_counters_alloc(ifp); if ((flags & TUN_LAYER2) == 0) { + ifp->if_input = tun_input; ifp->if_output = tun_output; ifp->if_mtu = ETHERMTU; ifp->if_flags = (IFF_POINTOPOINT|IFF_MULTICAST); @@ -253,8 +254,6 @@ tun_create(struct if_clone *ifc, int uni #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif - - if_ih_insert(ifp, tun_input, NULL); } else { sc->sc_flags |= TUN_LAYER2; ether_fakeaddr(ifp); @@ -320,9 +319,7 @@ tun_clone_destroy(struct ifnet *ifp) klist_invalidate(&sc->sc_wsel.si_note); splx(s); - if (!ISSET(sc->sc_flags, TUN_LAYER2)) - if_ih_remove(ifp, tun_input, NULL); - else + if (ISSET(sc->sc_flags, TUN_LAYER2)) ether_ifdetach(ifp); if_detach(ifp); @@ -880,8 +877,8 @@ put: return (error); } -int -tun_input(struct ifnet *ifp, struct mbuf *m0, void *cookie) +void +tun_input(struct ifnet *ifp, struct mbuf *m0) { uint32_t af; @@ -909,8 +906,6 @@ tun_input(struct ifnet *ifp, struct mbuf m_freem(m0); break; } - - return (1); } /* Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.106 diff -u -p -r1.106 if_var.h --- net/if_var.h 4 Jul 2020 08:06:08 -0000 1.106 +++ net/if_var.h 9 Jul 2020 02:28:19 -0000 @@ -159,7 +159,7 @@ struct ifnet { /* and the entries */ struct task if_linkstatetask; /* [I] task to do route updates */ /* procedure handles */ - SRPL_HEAD(, ifih) if_inputs; /* [K] input routines (dequeue) */ + void (*if_input)(struct ifnet *, struct mbuf *); int (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); /* output routine (enqueue) */ /* link level output function */ @@ -368,11 +368,6 @@ void ifa_add(struct ifnet *, struct ifad void ifa_del(struct ifnet *, struct ifaddr *); void ifa_update_broadaddr(struct ifnet *, struct ifaddr *, struct sockaddr *); - -void if_ih_insert(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, - void *), void *); -void if_ih_remove(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, - void *), void *); void if_addrhook_add(struct ifnet *, struct task *); void if_addrhook_del(struct ifnet *, struct task *); Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.203 diff -u -p -r1.203 if_vlan.c --- net/if_vlan.c 1 Feb 2020 10:27:40 -0000 1.203 +++ net/if_vlan.c 9 Jul 2020 02:28:19 -0000 @@ -119,7 +119,6 @@ void vlanattach(int count); int vlan_clone_create(struct if_clone *, int); int vlan_clone_destroy(struct ifnet *); -int vlan_input(struct ifnet *, struct mbuf *, void *); int vlan_enqueue(struct ifnet *, struct mbuf *); void vlan_start(struct ifqueue *ifq); int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); @@ -358,44 +357,45 @@ vlan_inject(struct mbuf *m, uint16_t typ return (m); } -/* - * vlan_input() returns 1 if it has consumed the packet, 0 otherwise. - */ -int -vlan_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) +struct mbuf * +vlan_input(struct ifnet *ifp0, struct mbuf *m) { struct vlan_softc *sc; + struct ifnet *ifp; struct ether_vlan_header *evl; - struct ether_header *eh; struct vlan_list *tagh, *list; - uint16_t tag; + uint16_t vtag, tag; uint16_t etype; int rxprio; - eh = mtod(m, struct ether_header *); - etype = ntohs(eh->ether_type); - if (m->m_flags & M_VLANTAG) { + vtag = m->m_pkthdr.ether_vtag; etype = ETHERTYPE_VLAN; tagh = vlan_tagh; - } else if ((etype == ETHERTYPE_VLAN) || (etype == ETHERTYPE_QINQ)) { - if (m->m_len < sizeof(*evl) && - (m = m_pullup(m, sizeof(*evl))) == NULL) { - ifp0->if_ierrors++; - return (1); + } else { + if (m->m_len < sizeof(*evl)) { + m = m_pullup(m, sizeof(*evl)); + if (m == NULL) + return (NULL); } evl = mtod(m, struct ether_vlan_header *); - m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag); - tagh = etype == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; - } else { - /* Skip non-VLAN packets. */ - return (0); + vtag = bemtoh16(&evl->evl_tag); + etype = bemtoh16(&evl->evl_encap_proto); + switch (etype) { + case ETHERTYPE_VLAN: + tagh = vlan_tagh; + break; + case ETHERTYPE_QINQ: + tagh = svlan_tagh; + break; + default: + panic("%s: unexpected etype 0x%04x", __func__, etype); + /* NOTREACHED */ + } } - /* From now on ether_vtag is fine */ - tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); - + tag = EVL_VLANOFTAG(vtag); list = &tagh[TAG_HASH(tag)]; smr_read_enter(); SMR_SLIST_FOREACH(sc, list, sc_list) { @@ -407,7 +407,11 @@ vlan_input(struct ifnet *ifp0, struct mb } smr_read_leave(); - if (sc == NULL || !ISSET(sc->sc_if.if_flags, IFF_RUNNING)) { + if (sc == NULL) + return (m); /* decline, let bridge have a go */ + + ifp = &sc->sc_if; + if (!ISSET(ifp->if_flags, IFF_RUNNING)) { m_freem(m); goto leave; } @@ -417,11 +421,11 @@ vlan_input(struct ifnet *ifp0, struct mb * the given source interface and vlan tag, remove the * encapsulation. */ - if (m->m_flags & M_VLANTAG) { - m->m_flags &= ~M_VLANTAG; + if (ISSET(m->m_flags, M_VLANTAG)) { + CLR(m->m_flags, M_VLANTAG); } else { - eh->ether_type = evl->evl_proto; - memmove((char *)eh + EVL_ENCAPLEN, eh, sizeof(*eh)); + memmove((caddr_t)evl + EVL_ENCAPLEN, evl, + offsetof(struct ether_vlan_header, evl_encap_proto)); m_adj(m, EVL_ENCAPLEN); } @@ -440,11 +444,10 @@ vlan_input(struct ifnet *ifp0, struct mb break; } - if_vinput(&sc->sc_if, m); + if_vinput(ifp, m); leave: - if (sc != NULL) - refcnt_rele_wake(&sc->sc_refcnt); - return (1); + refcnt_rele_wake(&sc->sc_refcnt); + return (NULL); } int @@ -530,8 +533,6 @@ vlan_up(struct vlan_softc *sc) /* configure the parent to handle packets for this vlan */ vlan_multi_apply(sc, ifp0, SIOCADDMULTI); - if_ih_insert(ifp0, vlan_input, NULL); - /* we're running now */ SET(ifp->if_flags, IFF_RUNNING); vlan_link_state(sc, ifp0->if_link_state, ifp0->if_baudrate); @@ -574,7 +575,6 @@ vlan_down(struct vlan_softc *sc) ifp0 = if_get(sc->sc_ifidx0); if (ifp0 != NULL) { - if_ih_remove(ifp0, vlan_input, NULL); if (ISSET(sc->sc_flags, IFVF_PROMISC)) ifpromisc(ifp0, 0); vlan_multi_apply(sc, ifp0, SIOCDELMULTI); Index: net/if_vlan_var.h =================================================================== RCS file: /cvs/src/sys/net/if_vlan_var.h,v retrieving revision 1.41 diff -u -p -r1.41 if_vlan_var.h --- net/if_vlan_var.h 27 Apr 2019 04:46:03 -0000 1.41 +++ net/if_vlan_var.h 9 Jul 2020 02:28:19 -0000 @@ -47,6 +47,7 @@ struct vlanreq { }; #ifdef _KERNEL +struct mbuf *vlan_input(struct ifnet *, struct mbuf *); struct mbuf *vlan_inject(struct mbuf *, uint16_t, uint16_t); #endif /* _KERNEL */ Index: netinet/if_ether.h =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.h,v retrieving revision 1.76 diff -u -p -r1.76 if_ether.h --- netinet/if_ether.h 17 Jul 2019 16:46:18 -0000 1.76 +++ netinet/if_ether.h 9 Jul 2020 02:28:19 -0000 @@ -199,6 +199,11 @@ do { \ #include /* for "struct ifnet" */ +struct ether_brport { + struct mbuf *(*eb_input)(struct ifnet *, struct mbuf *, void *); + void *eb_port; +}; + /* * Structure shared between the ethernet driver modules and * the address resolution code. For example, each ec_softc or il_softc @@ -213,6 +218,7 @@ struct arpcom { int ac_multirangecnt; /* number of mcast ranges */ void *ac_trunkport; + const struct ether_brport *ac_brport; }; extern int arpt_keep; /* arp resolved cache expire */ @@ -247,7 +253,7 @@ int ether_multiaddr(struct sockaddr *, u 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 *, struct mbuf *, void *); +void ether_input(struct ifnet *, struct mbuf *); int ether_resolve(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *, struct ether_header *); struct mbuf * @@ -258,6 +264,9 @@ int ether_output(struct ifnet *, struct void ether_rtrequest(struct ifnet *, int, struct rtentry *); char *ether_sprintf(u_char *); +int ether_is_brport(struct ifnet *); +void ether_set_brport(struct ifnet *, const struct ether_brport *); +void ether_clr_brport(struct ifnet *); /* * Ethernet multicast address structure. There is one of these for each Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.345 diff -u -p -r1.345 ip_carp.c --- netinet/ip_carp.c 21 May 2020 05:24:59 -0000 1.345 +++ netinet/ip_carp.c 9 Jul 2020 02:28:19 -0000 @@ -208,7 +208,6 @@ void carp_hmac_generate(struct carp_vhos unsigned char *, u_int8_t); int carp_hmac_verify(struct carp_vhost_entry *, u_int32_t *, unsigned char *); -int carp_input(struct ifnet *, struct mbuf *, void *); void carp_proto_input_c(struct ifnet *, struct mbuf *, struct carp_header *, int, sa_family_t); int carp_proto_input_if(struct ifnet *, struct mbuf **, int *, int); @@ -949,9 +948,6 @@ carpdetach(void *arg) cif = &ifp0->if_carp; - /* Restore previous input handler. */ - if_ih_remove(ifp0, carp_input, NULL); - SRPL_REMOVE_LOCKED(&carp_sc_rc, cif, sc, carp_softc, sc_list); sc->sc_carpdev = NULL; @@ -1376,23 +1372,14 @@ carp_vhe_match(struct carp_softc *sc, ui return (match); } -int -carp_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) +struct mbuf * +carp_input(struct ifnet *ifp0, struct mbuf *m) { struct ether_header *eh; struct srpl *cif; struct carp_softc *sc; struct srp_ref sr; -#if NVLAN > 0 - /* - * If the underlying interface removed the VLAN header itself, - * it's not for us. - */ - if (ISSET(m->m_flags, M_VLANTAG)) - return (0); -#endif - eh = mtod(m, struct ether_header *); cif = &ifp0->if_carp; @@ -1426,7 +1413,7 @@ carp_input(struct ifnet *ifp0, struct mb SRPL_LEAVE(&sr); if (!ETHER_IS_MULTICAST(eh->ether_dhost)) - return (0); + return (m); /* * XXX Should really check the list of multicast addresses @@ -1446,14 +1433,14 @@ carp_input(struct ifnet *ifp0, struct mb } SRPL_LEAVE(&sr); - return (0); + return (m); } if_vinput(&sc->sc_if, m); out: SRPL_LEAVE(&sr); - return (1); + return (NULL); } int @@ -1731,9 +1718,6 @@ carp_set_ifp(struct carp_softc *sc, stru if (sc->sc_naddrs || sc->sc_naddrs6) sc->sc_if.if_flags |= IFF_UP; carp_set_enaddr(sc); - - /* Change input handler of the physical interface. */ - if_ih_insert(ifp0, carp_input, NULL); carp_carpdev_state(sc); Index: netinet/ip_carp.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.h,v retrieving revision 1.48 diff -u -p -r1.48 ip_carp.h --- netinet/ip_carp.h 8 Dec 2019 11:08:22 -0000 1.48 +++ netinet/ip_carp.h 9 Jul 2020 02:28:19 -0000 @@ -207,6 +207,8 @@ carp_strict_addr_chk(struct ifnet *ifp_a ifp_a->if_carpdev == ifp_b->if_carpdev)); } +struct mbuf *carp_input(struct ifnet *, struct mbuf *); + int carp_proto_input(struct mbuf **, int *, int, int); void carp_carpdev_state(void *); void carp_group_demote_adj(struct ifnet *, int, char *);