diff --git a/sys/dev/usb/if_upl.c b/sys/dev/usb/if_upl.c index 2b480ddd..7e0f97a 100644 --- a/sys/dev/usb/if_upl.c +++ b/sys/dev/usb/if_upl.c @@ -987,7 +987,7 @@ Static int upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, struct rtentry *rt0) { - int s, len, error; + int error; DPRINTFN(10,("%s: %s: enter\n", device_xname(((struct upl_softc *)ifp->if_softc)->sc_dev), @@ -999,24 +999,13 @@ upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, */ IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); - len = m->m_pkthdr.len; - s = splnet(); /* * Queue message on interface, and start output if interface * not yet active. */ - IFQ_ENQUEUE(&ifp->if_snd, m, error); - if (error) { - /* mbuf is already freed */ - splx(s); - return error; - } - ifp->if_obytes += len; - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); - splx(s); + error = (*ifp->if_transmit)(ifp, m); - return 0; + return error; } Static void diff --git a/sys/net/if.c b/sys/net/if.c index 4f6beb5..48e799e 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -329,6 +329,13 @@ if_nullstart(struct ifnet *ifp) } int +if_nulltransmit(struct ifnet *ifp, struct mbuf *m) +{ + + return ENXIO; +} + +int if_nullioctl(struct ifnet *ifp, u_long cmd, void *data) { @@ -665,6 +672,9 @@ if_register(ifnet_t *ifp) if_slowtimo(ifp); } + if (ifp->if_transmit == NULL || ifp->if_transmit == if_nulltransmit) + ifp->if_transmit = if_transmit; + TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list); } @@ -959,6 +969,7 @@ if_deactivate(struct ifnet *ifp) ifp->if_output = if_nulloutput; ifp->_if_input = if_nullinput; ifp->if_start = if_nullstart; + ifp->if_transmit = if_nulltransmit; ifp->if_ioctl = if_nullioctl; ifp->if_init = if_nullinit; ifp->if_stop = if_nullstop; @@ -2667,31 +2678,45 @@ ifreq_setaddr(u_long cmd, struct ifreq *ifr, const struct sockaddr *sa) } /* - * Queue message on interface, and start output if interface - * not yet active. + * wrapper function for the drivers which doesn't have if_transmit(). */ int -ifq_enqueue(struct ifnet *ifp, struct mbuf *m) +if_transmit(struct ifnet *ifp, struct mbuf *m) { - int len = m->m_pkthdr.len; - int mflags = m->m_flags; - int s = splnet(); - int error; + int s, error; + + s = splnet(); IFQ_ENQUEUE(&ifp->if_snd, m, error); - if (error != 0) + if (error != 0) { + /* mbuf is already freed */ goto out; - ifp->if_obytes += len; - if (mflags & M_MCAST) + } + + ifp->if_obytes += m->m_pkthdr.len;; + if (m->m_flags & M_MCAST) ifp->if_omcasts++; + if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); out: splx(s); + return error; } /* + * Queue message on interface, and start output if interface + * not yet active. + */ +int +ifq_enqueue(struct ifnet *ifp, struct mbuf *m) +{ + + return (*ifp->if_transmit)(ifp, m); +} + +/* * Queue message on interface, possibly using a second fast queue */ int diff --git a/sys/net/if.h b/sys/net/if.h index 12c3d72..1881476 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -272,6 +272,8 @@ typedef struct ifnet { (struct ifnet *, struct mbuf *); void (*if_start) /* initiate output routine */ (struct ifnet *); + int (*if_transmit) /* output routine (direct) */ + (struct ifnet *, struct mbuf *); int (*if_ioctl) /* ioctl routine */ (struct ifnet *, u_long, void *); int (*if_init) /* init routine */ @@ -939,6 +941,8 @@ void p2p_rtrequest(int, struct rtentry *, const struct rt_addrinfo *); void if_clone_attach(struct if_clone *); void if_clone_detach(struct if_clone *); +int if_transmit(struct ifnet *, struct mbuf *); + int ifq_enqueue(struct ifnet *, struct mbuf *); int ifq_enqueue2(struct ifnet *, struct ifqueue *, struct mbuf *); @@ -956,6 +960,7 @@ int if_nulloutput(struct ifnet *, struct mbuf *, const struct sockaddr *, struct rtentry *); void if_nullinput(struct ifnet *, struct mbuf *); void if_nullstart(struct ifnet *); +int if_nulltransmit(struct ifnet *, struct mbuf *); int if_nullioctl(struct ifnet *, u_long, void *); int if_nullinit(struct ifnet *); void if_nullstop(struct ifnet *, int); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 153348f..9512123 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1381,8 +1381,7 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, len = m->m_pkthdr.len; mflags = m->m_flags; - IFQ_ENQUEUE(&dst_ifp->if_snd, m, error); - + error = (*dst_ifp->if_transmit)(dst_ifp, m); if (error) { /* mbuf is already freed */ sc->sc_if.if_oerrors++; @@ -1391,16 +1390,8 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, sc->sc_if.if_opackets++; sc->sc_if.if_obytes += len; - - dst_ifp->if_obytes += len; - - if (mflags & M_MCAST) { + if (mflags & M_MCAST) sc->sc_if.if_omcasts++; - dst_ifp->if_omcasts++; - } - - if ((dst_ifp->if_flags & IFF_OACTIVE) == 0) - (*dst_ifp->if_start)(dst_ifp); } /* diff --git a/sys/net/if_ieee1394subr.c b/sys/net/if_ieee1394subr.c index b3402b9..e4ce8a8 100644 --- a/sys/net/if_ieee1394subr.c +++ b/sys/net/if_ieee1394subr.c @@ -88,7 +88,7 @@ ieee1394_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, { uint16_t etype = 0; struct mbuf *m; - int s, hdrlen, error = 0; + int hdrlen, error = 0; struct mbuf *mcopy = NULL; struct ieee1394_hwaddr *hwdst, baddr; const struct ieee1394_hwaddr *myaddr; @@ -218,26 +218,15 @@ ieee1394_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, if (m0 == NULL) senderr(ENOBUFS); - s = splnet(); - ifp->if_obytes += m0->m_pkthdr.len; - if (m0->m_flags & M_MCAST) - ifp->if_omcasts++; while ((m = m0) != NULL) { m0 = m->m_nextpkt; - if (m == NULL) { - splx(s); - senderr(ENOBUFS); - } - IFQ_ENQUEUE(&ifp->if_snd, m, error); + + error = (*ifp->if_transmit)(ifp, m); if (error) { /* mbuf is already freed */ - splx(s); goto bad; } } - if ((ifp->if_flags & IFF_OACTIVE) == 0) - (*ifp->if_start)(ifp); - splx(s); return 0; bad: diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 5c6e893..cc26462 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -254,10 +254,7 @@ looutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, return (ENOBUFS); *(mtod(m, uint32_t *)) = dst->sa_family; - s = splnet(); - IFQ_ENQUEUE(&ifp->if_snd, m, error); - (*ifp->if_start)(ifp); - splx(s); + error = ifp->if_transmit(ifp, m); return (error); } #endif /* ALTQ */ diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index fd29994..7229fc8 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -807,20 +807,16 @@ vlan_start(struct ifnet *ifp) * Send it, precisely as the parent's output routine * would have. We are already running at splnet. */ - IFQ_ENQUEUE(&p->if_snd, m, error); - if (error) { - /* mbuf is already freed */ - ifp->if_oerrors++; - continue; + if ((p->if_flags & IFF_RUNNING) != 0) { + error = (*p->if_transmit)(p, m); + if (error) { + /* mbuf is already freed */ + ifp->if_oerrors++; + continue; + } } ifp->if_opackets++; - - p->if_obytes += m->m_pkthdr.len; - if (m->m_flags & M_MCAST) - p->if_omcasts++; - if ((p->if_flags & (IFF_RUNNING|IFF_OACTIVE)) == IFF_RUNNING) - (*p->if_start)(p); } ifp->if_flags &= ~IFF_OACTIVE; diff --git a/sys/netipsec/ipsec_osdep.h b/sys/netipsec/ipsec_osdep.h index 9bba141..78f17c3 100644 --- a/sys/netipsec/ipsec_osdep.h +++ b/sys/netipsec/ipsec_osdep.h @@ -141,7 +141,6 @@ read_random(void *bufp, u_int len) static __inline int if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) { - int need_if_start = 0; int s = splnet(); KERNEL_LOCK(1, NULL); @@ -152,15 +151,9 @@ if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) m_freem(m); return (0); } - if (ifp != NULL) { - ifp->if_obytes += m->m_pkthdr.len + adjust; - if (m->m_flags & M_MCAST) - ifp->if_omcasts++; - need_if_start = !(ifp->if_flags & IFF_OACTIVE); - } - IF_ENQUEUE(ifq, m); - if (need_if_start) - (*ifp->if_start)(ifp); + if (ifp != NULL) + (void)(*ifp->if_transmit)(ifp, m); + KERNEL_UNLOCK_ONE(NULL); splx(s); return (1);