diff options
author | Kenjiro Cho <kjc@cvs.openbsd.org> | 2001-06-27 06:07:48 +0000 |
---|---|---|
committer | Kenjiro Cho <kjc@cvs.openbsd.org> | 2001-06-27 06:07:48 +0000 |
commit | 617b9204d0b61c24f1c430d0d271187effbd4db7 (patch) | |
tree | f0298d5992870f173131e355b24266b1167650ca | |
parent | 68127d8aa8be05026092d74eb27663a9fe287c85 (diff) |
introduce the ALTQ queue macros into sys/net files.
the new model removes direct references to the fields in ifp->if_snd,
and defines the following macros to manipulate ifp->if_snd.
IFQ_ENQUEUE(ifq, m, pktattr, err)
IFQ_DEQUEUE(ifq, m)
IFQ_POLL(ifq, m)
IFQ_PURGE(ifq)
IFQ_IS_EMPTY(ifq)
the new model also enforces some rules regarding how to use these macros.
details are descrined in
http://www.csl.sony.co.jp/~kjc/software/altq-new-design.txt
-rw-r--r-- | sys/net/bridgestp.c | 19 | ||||
-rw-r--r-- | sys/net/if_atmsubr.c | 31 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 93 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 115 | ||||
-rw-r--r-- | sys/net/if_fddisubr.c | 29 | ||||
-rw-r--r-- | sys/net/if_loop.c | 122 | ||||
-rw-r--r-- | sys/net/if_ppp.c | 62 | ||||
-rw-r--r-- | sys/net/if_sl.c | 25 | ||||
-rw-r--r-- | sys/net/if_spppsubr.c | 50 | ||||
-rw-r--r-- | sys/net/if_strip.c | 35 | ||||
-rw-r--r-- | sys/net/if_tokensubr.c | 29 | ||||
-rw-r--r-- | sys/net/if_tun.c | 78 | ||||
-rw-r--r-- | sys/net/if_vlan.c | 44 | ||||
-rw-r--r-- | sys/netinet/if_ether.h | 5 |
14 files changed, 571 insertions, 166 deletions
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index f84e8f5016b..49d697068c1 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bridgestp.c,v 1.6 2001/05/30 02:12:23 deraadt Exp $ */ +/* $OpenBSD: bridgestp.c,v 1.7 2001/06/27 06:07:37 kjc Exp $ */ /* * Copyright (c) 2000 Jason L. Wright (jason@thought.net) @@ -224,7 +224,7 @@ bstp_send_config_bpdu(bif, cu) struct mbuf *m; struct ether_header eh; struct bstp_cbpdu bpdu; - int s; + int s, error; s = splimp(); ifp = bif->ifp; @@ -234,6 +234,9 @@ bstp_send_config_bpdu(bif, cu) splx(s); return; } +#ifdef ALTQ + if (!ALTQ_IS_ENABLED(&ifp->if_snd)) +#endif if (IF_QFULL(&ifp->if_snd)) { splx(s); return; @@ -287,8 +290,8 @@ bstp_send_config_bpdu(bif, cu) bcopy(&eh, m->m_data, sizeof(eh)); bcopy(&bpdu, m->m_data + sizeof(eh), sizeof(bpdu)); - IF_ENQUEUE(&ifp->if_snd, m); - if ((ifp->if_flags & IFF_OACTIVE) == 0) + IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); + if (error == 0 && (ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); } @@ -386,7 +389,7 @@ bstp_transmit_tcn(sc) struct arpcom *arp = (struct arpcom *)ifp; struct ether_header *eh; struct mbuf *m; - int s; + int s, error; MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) @@ -410,10 +413,8 @@ bstp_transmit_tcn(sc) s = splimp(); if ((ifp->if_flags & IFF_RUNNING) == 0) goto out; - if (IF_QFULL(&ifp->if_snd)) - goto out; - IF_ENQUEUE(&ifp->if_snd, m); - if ((ifp->if_flags & IFF_OACTIVE) == 0) + IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); + if (error == 0 && (ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); m = NULL; diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c index c9437d5d1aa..10c13bbbb73 100644 --- a/sys/net/if_atmsubr.c +++ b/sys/net/if_atmsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_atmsubr.c,v 1.15 2001/06/15 03:38:33 itojun Exp $ */ +/* $OpenBSD: if_atmsubr.c,v 1.16 2001/06/27 06:07:38 kjc Exp $ */ /* * @@ -107,17 +107,25 @@ atm_output(ifp, m0, dst, rt0) struct rtentry *rt0; { u_int16_t etype = 0; /* if using LLC/SNAP */ - int s, error = 0, sz; + int s, error = 0, sz, len; struct atm_pseudohdr atmdst, *ad; register struct mbuf *m = m0; register struct rtentry *rt; struct atmllc *atmllc; u_int32_t atm_flags; + ALTQ_DECL(struct altq_pktattr pktattr;) if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, + (dst != NULL ? dst->sa_family : AF_UNSPEC), &pktattr); + + /* * check route */ if ((rt = rt0) != NULL) { @@ -160,14 +168,6 @@ atm_output(ifp, m0, dst, rt0) etype = ETHERTYPE_IP; else etype = ETHERTYPE_IPV6; -# ifdef ATM_PVCEXT - if (ifp->if_flags & IFF_POINTOPOINT) { - /* pvc subinterface */ - struct pvcsif *pvcsif = (struct pvcsif *)ifp; - atmdst = pvcsif->sif_aph; - break; - } -# endif if (!atmresolve(rt, m, dst, &atmdst)) { m = NULL; /* XXX: atmresolve already free'd it */ @@ -235,15 +235,14 @@ atm_output(ifp, m0, dst, rt0) * Queue message on interface, and start output if interface * not yet active. */ - + len = m->m_pkthdr.len; s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + if (error) { splx(s); - senderr(ENOBUFS); + return (error); } - ifp->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m); + ifp->if_obytes += len; if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 5690b6c5e76..cd3776b5b67 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.67 2001/06/26 18:17:53 deraadt Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.68 2001/06/27 06:07:39 kjc Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -742,7 +742,9 @@ bridge_output(ifp, m, sa, rt) struct ifnet *dst_if; struct ether_addr *src, *dst; struct bridge_softc *sc; - int s; + int s, error, len; + short mflags; + ALTQ_DECL(struct altq_pktattr pktattr;) #ifdef IPSEC struct m_tag *mtag; #endif /* IPSEC */ @@ -806,6 +808,9 @@ bridge_output(ifp, m, sa, rt) dst_if = p->ifp; if ((dst_if->if_flags & IFF_RUNNING) == 0) continue; +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0) +#endif if (IF_QFULL(&dst_if->if_snd)) { IF_DROP(&dst_if->if_snd); sc->sc_if.if_oerrors++; @@ -821,13 +826,22 @@ bridge_output(ifp, m, sa, rt) continue; } } - + len = mc->m_pkthdr.len; + mflags = mc->m_flags; +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&dst_if->if_snd)) + altq_etherclassify(&dst_if->if_snd, mc, &pktattr); +#endif + IFQ_ENQUEUE(&dst_if->if_snd, mc, &pktattr, error); + if (error) { + sc->sc_if.if_oerrors++; + continue; + } sc->sc_if.if_opackets++; - sc->sc_if.if_obytes += mc->m_pkthdr.len; - dst_if->if_obytes += mc->m_pkthdr.len; - IF_ENQUEUE(&dst_if->if_snd, mc); - if (mc->m_flags & M_MCAST) - ifp->if_omcasts++; + sc->sc_if.if_obytes += len; + dst_if->if_obytes += len; + if (mflags & M_MCAST) + dst_if->if_omcasts++; if ((dst_if->if_flags & IFF_OACTIVE) == 0) (*dst_if->if_start)(dst_if); } @@ -843,18 +857,22 @@ sendunicast: splx(s); return (0); } - if (IF_QFULL(&dst_if->if_snd)) { - IF_DROP(&dst_if->if_snd); + len = m->m_pkthdr.len; + mflags = m->m_flags; +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&dst_if->if_snd)) + altq_etherclassify(&dst_if->if_snd, m, &pktattr); +#endif + IFQ_ENQUEUE(&dst_if->if_snd, m, &pktattr, error); + if (error) { sc->sc_if.if_oerrors++; - m_freem(m); splx(s); return (0); } sc->sc_if.if_opackets++; - sc->sc_if.if_obytes += m->m_pkthdr.len; - dst_if->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&dst_if->if_snd, m); - if (m->m_flags & M_MCAST) + sc->sc_if.if_obytes += len; + dst_if->if_obytes += len; + if (mflags & M_MCAST) dst_if->if_omcasts++; if ((dst_if->if_flags & IFF_OACTIVE) == 0) (*dst_if->if_start)(dst_if); @@ -902,11 +920,13 @@ bridgeintr_frame(sc, m) struct bridge_softc *sc; struct mbuf *m; { - int s; + int s, error, len; struct ifnet *src_if, *dst_if; struct bridge_iflist *ifl; struct ether_addr *dst, *src; struct ether_header eh; + short mflags; + ALTQ_DECL(struct altq_pktattr pktattr;) if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { m_freem(m); @@ -1067,19 +1087,23 @@ bridgeintr_frame(sc, m) m_freem(m); return; } +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&dst_if->if_snd)) + altq_etherclassify(&dst_if->if_snd, m, &pktattr); +#endif + len = m->m_pkthdr.len; + mflags = m->m_flags; s = splimp(); - if (IF_QFULL(&dst_if->if_snd)) { - IF_DROP(&dst_if->if_snd); + IFQ_ENQUEUE(&dst_if->if_snd, m, &pktattr, error); + if (error) { sc->sc_if.if_oerrors++; - m_freem(m); splx(s); return; } sc->sc_if.if_opackets++; - sc->sc_if.if_obytes += m->m_pkthdr.len; - dst_if->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&dst_if->if_snd, m); - if (m->m_flags & M_MCAST) + sc->sc_if.if_obytes += len; + dst_if->if_obytes += len; + if (mflags & M_MCAST) dst_if->if_omcasts++; if ((dst_if->if_flags & IFF_OACTIVE) == 0) (*dst_if->if_start)(dst_if); @@ -1245,7 +1269,9 @@ bridge_broadcast(sc, ifp, eh, m) struct bridge_iflist *p; struct mbuf *mc; struct ifnet *dst_if; - int used = 0; + int error, len, used = 0; + short mflags; + ALTQ_DECL(struct altq_pktattr pktattr;) LIST_FOREACH(p, &sc->sc_iflist, next) { /* @@ -1268,6 +1294,9 @@ bridge_broadcast(sc, ifp, eh, m) if ((dst_if->if_flags & IFF_RUNNING) == 0) continue; +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0) +#endif if (IF_QFULL(&dst_if->if_snd)) { IF_DROP(&dst_if->if_snd); sc->sc_if.if_oerrors++; @@ -1294,11 +1323,19 @@ bridge_broadcast(sc, ifp, eh, m) } } +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&dst_if->if_snd)) + altq_etherclassify(&dst_if->if_snd, mc, &pktattr); +#endif + IFQ_ENQUEUE(&dst_if->if_snd, mc, &pktattr, error); + if (error) { + sc->sc_if.if_oerrors++; + continue; + } sc->sc_if.if_opackets++; - sc->sc_if.if_obytes += mc->m_pkthdr.len; - dst_if->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&dst_if->if_snd, mc); - if (mc->m_flags & M_MCAST) + sc->sc_if.if_obytes += len; + dst_if->if_obytes += len; + if (mflags & M_MCAST) dst_if->if_omcasts++; if ((dst_if->if_flags & IFF_OACTIVE) == 0) (*dst_if->if_start)(dst_if); diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 325a7720cb7..622c73107b9 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.51 2001/06/24 22:34:04 fgsch Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.52 2001/06/27 06:07:40 kjc Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -246,13 +246,15 @@ ether_output(ifp, m0, dst, rt0) struct rtentry *rt0; { u_int16_t etype; - int s, error = 0, hdrcmplt = 0; + int s, len, error = 0, hdrcmplt = 0; u_char edst[6], esrc[6]; register struct mbuf *m = m0; register struct rtentry *rt; struct mbuf *mcopy = (struct mbuf *)0; register struct ether_header *eh; struct arpcom *ac = (struct arpcom *)ifp; + short mflags; + ALTQ_DECL(struct altq_pktattr pktattr;) if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); @@ -278,6 +280,13 @@ ether_output(ifp, m0, dst, rt0) time.tv_sec < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } + + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + switch (dst->sa_family) { #ifdef INET @@ -560,19 +569,21 @@ ether_output(ifp, m0, dst, rt0) } #endif + mflags = m->m_flags; + len = m->m_pkthdr.len; s = splimp(); /* * Queue message on interface, and start output if interface * not yet active. */ - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + if (error) { + /* mbuf is already freed */ splx(s); - senderr(ENOBUFS); + return (error); } - ifp->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m); - if (m->m_flags & M_MCAST) + ifp->if_obytes += len + sizeof (struct ether_header); + if (mflags & M_MCAST) ifp->if_omcasts++; if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); @@ -585,6 +596,94 @@ bad: return (error); } +#ifdef ALTQ +/* + * This routine is a slight hack to allow a packet to be classified + * if the Ethernet headers are present. It will go away when ALTQ's + * classification engine understands link headers. + */ +void +altq_etherclassify(struct ifaltq *ifq, struct mbuf *m, + struct altq_pktattr *pktattr) +{ + struct ether_header *eh; + u_int16_t ether_type; + int hlen, af, hdrsize; + caddr_t hdr; + + hlen = ETHER_HDR_LEN; + eh = mtod(m, struct ether_header *); + + ether_type = htons(eh->ether_type); + + if (ether_type < ETHERMTU) { + /* LLC/SNAP */ + struct llc *llc = (struct llc *)(eh + 1); + hlen += 8; + + if (m->m_len < hlen || + llc->llc_dsap != LLC_SNAP_LSAP || + llc->llc_ssap != LLC_SNAP_LSAP || + llc->llc_control != LLC_UI) { + /* Not SNAP. */ + goto bad; + } + + ether_type = htons(llc->llc_un.type_snap.ether_type); + } + + switch (ether_type) { + case ETHERTYPE_IP: + af = AF_INET; + hdrsize = 20; /* sizeof(struct ip) */ + break; + + case ETHERTYPE_IPV6: + af = AF_INET6; + hdrsize = 40; /* sizeof(struct ip6_hdr) */ + break; + + default: + af = AF_UNSPEC; + hdrsize = 0; + break; + } + + if (m->m_len < (hlen + hdrsize)) { + /* + * Ethernet and protocol header not in a single + * mbuf. We can't cope with this situation right + * now (but it shouldn't ever happen, really, anyhow). + * XXX Should use m_pulldown(). + */ + printf("altq_etherclassify: headers span multiple mbufs: " + "%d < %d\n", m->m_len, (hlen + hdrsize)); + goto bad; + } + + m->m_data += hlen; + m->m_len -= hlen; + + hdr = mtod(m, caddr_t); + + if (ALTQ_NEEDS_CLASSIFY(ifq)) + pktattr->pattr_class = + (*ifq->altq_classify)(ifq->altq_clfier, m, af); + pktattr->pattr_af = af; + pktattr->pattr_hdr = hdr; + + m->m_data -= hlen; + m->m_len += hlen; + + return; + + bad: + pktattr->pattr_class = NULL; + pktattr->pattr_hdr = NULL; + pktattr->pattr_af = AF_UNSPEC; +} +#endif /* ALTQ */ + /* * Temporary function to migrate while * removing ether_header * from ether_input(). diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index e4e9464ad79..3ae884a351c 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_fddisubr.c,v 1.24 2001/06/15 03:38:33 itojun Exp $ */ +/* $OpenBSD: if_fddisubr.c,v 1.25 2001/06/27 06:07:40 kjc Exp $ */ /* $NetBSD: if_fddisubr.c,v 1.5 1996/05/07 23:20:21 christos Exp $ */ /* @@ -150,13 +150,15 @@ fddi_output(ifp, m0, dst, rt0) struct rtentry *rt0; { u_int16_t type; - int s, error = 0, hdrcmplt = 0; + int s, len, error = 0, hdrcmplt = 0; u_char edst[6], esrc[6]; register struct mbuf *m = m0; register struct rtentry *rt; struct mbuf *mcopy = (struct mbuf *)0; register struct fddi_header *fh; struct arpcom *ac = (struct arpcom *)ifp; + ALTQ_DECL(struct altq_pktattr pktattr;) + short mflags; if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); @@ -182,6 +184,13 @@ fddi_output(ifp, m0, dst, rt0) time.tv_sec < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } + + /* + * If the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + switch (dst->sa_family) { #ifdef INET @@ -432,23 +441,25 @@ fddi_output(ifp, m0, dst, rt0) else bcopy((caddr_t)ac->ac_enaddr, (caddr_t)fh->fddi_shost, sizeof(fh->fddi_shost)); + mflags = m->m_flags; + len = m->m_pkthdr.len; s = splimp(); /* * Queue message on interface, and start output if interface * not yet active. */ - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + if (error) { + /* mbuf is already freed */ splx(s); - senderr(ENOBUFS); + return (error); } - ifp->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m); + ifp->if_obytes += len; + if (mflags & M_MCAST) + ifp->if_omcasts++; if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); - if (m->m_flags & M_MCAST) - ifp->if_omcasts++; return (error); bad: diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 3d784315000..9c6d22d4014 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_loop.c,v 1.18 2001/06/15 03:38:34 itojun Exp $ */ +/* $OpenBSD: if_loop.c,v 1.19 2001/06/27 06:07:42 kjc Exp $ */ /* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */ /* @@ -145,6 +145,10 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. #define LOMTU (32768 + MHLEN + MLEN) #endif +#ifdef ALTQ +static void lo_altqstart __P((struct ifnet *)); +#endif + void loopattach(n) int n; @@ -168,6 +172,10 @@ loopattach(n) ifp->if_type = IFT_LOOP; ifp->if_hdrlen = sizeof(u_int32_t); ifp->if_addrlen = 0; + IFQ_SET_READY(&ifp->if_snd); +#ifdef ALTQ + ifp->if_start = lo_altqstart; +#endif if_attachhead(ifp); #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); @@ -221,6 +229,37 @@ looutput(ifp, m, dst, rt) ifp->if_opackets++; ifp->if_obytes += m->m_pkthdr.len; +#ifdef ALTQ + /* + * altq for loop is just for debugging. + * only used when called for loop interface (not for + * a simplex interface). + */ + if ((ALTQ_IS_ENABLED(&ifp->if_snd) || TBR_IS_ENABLED(&ifp->if_snd)) + && ifp->if_start == lo_altqstart) { + struct altq_pktattr pktattr; + int32_t *afp; + int error; + + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + + M_PREPEND(m, sizeof(int32_t), M_DONTWAIT); + if (m == 0) + return(ENOBUFS); + afp = mtod(m, int32_t *); + *afp = (int32_t)dst->sa_family; + + s = splimp(); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + (*ifp->if_start)(ifp); + splx(s); + return (error); + } +#endif /* ALTQ */ switch (dst->sa_family) { #ifdef INET @@ -280,6 +319,87 @@ looutput(ifp, m, dst, rt) return (0); } +#ifdef ALTQ +static void +lo_altqstart(ifp) + struct ifnet *ifp; +{ + struct ifqueue *ifq; + struct mbuf *m; + int32_t af, *afp; + int s, isr; + + while (1) { + s = splimp(); + IFQ_DEQUEUE(&ifp->if_snd, m); + splx(s); + if (m == NULL) + return; + + afp = mtod(m, int32_t *); + af = *afp; + m_adj(m, sizeof(int32_t)); + + switch (af) { +#ifdef INET + case AF_INET: + ifq = &ipintrq; + isr = NETISR_IP; + break; +#endif +#ifdef INET6 + case AF_INET6: + m->m_flags |= M_LOOP; + ifq = &ip6intrq; + isr = NETISR_IPV6; + break; +#endif +#ifdef IPX + case AF_IPX: + ifq = &ipxintrq; + isr = NETISR_IPX; + break; +#endif +#ifdef NS + case AF_NS: + ifq = &nsintrq; + isr = NETISR_NS; + break; +#endif +#ifdef ISO + case AF_ISO: + ifq = &clnlintrq; + isr = NETISR_ISO; + break; +#endif +#ifdef NETATALK + case AF_APPLETALK: + ifq = &atintrq2; + isr = NETISR_ATALK; + break; +#endif NETATALK + default: + printf("lo_altqstart: can't handle af%d\n", af); + m_freem(m); + return; + } + + s = splimp(); + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + splx(s); + return; + } + IF_ENQUEUE(ifq, m); + schednetisr(isr); + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + splx(s); + } +} +#endif /* ALTQ */ + /* ARGSUSED */ void lortrequest(cmd, rt, info) diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 96fbe46d218..b057ba38669 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ppp.c,v 1.22 2001/06/27 03:49:53 angelos Exp $ */ +/* $OpenBSD: if_ppp.c,v 1.23 2001/06/27 06:07:42 kjc Exp $ */ /* $NetBSD: if_ppp.c,v 1.39 1997/05/17 21:11:59 christos Exp $ */ /* @@ -199,10 +199,11 @@ pppattach() sc->sc_if.if_hdrlen = PPP_HDRLEN; sc->sc_if.if_ioctl = pppsioctl; sc->sc_if.if_output = pppoutput; - sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&sc->sc_if.if_snd, IFQ_MAXLEN); sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_READY(&sc->sc_if.if_snd); if_attach(&sc->sc_if); #if NBPFILTER > 0 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN); @@ -636,6 +637,7 @@ pppoutput(ifp, m0, dst, rtp) enum NPmode mode; int len; struct mbuf *m; + ALTQ_DECL(struct altq_pktattr pktattr;) if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0 || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) { @@ -643,6 +645,8 @@ pppoutput(ifp, m0, dst, rtp) goto bad; } + IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr); + /* * Compute PPP header. */ @@ -759,16 +763,29 @@ pppoutput(ifp, m0, dst, rtp) m0->m_nextpkt = NULL; sc->sc_npqtail = &m0->m_nextpkt; } else { - ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd; - if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { - IF_DROP(ifq); + if ((m0->m_flags & M_HIGHPRI) +#ifdef ALTQ + && ALTQ_IS_ENABLED(&sc->sc_if.if_snd) == 0 +#endif + ) { + ifq = &sc->sc_fastq; + if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { + IF_DROP(ifq); + m_freem(m0); + error = ENOBUFS; + } + else { + IF_ENQUEUE(ifq, m0); + error = 0; + } + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m0, &pktattr, error); + if (error) { splx(s); sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; - error = ENOBUFS; - goto bad; + return (error); } - IF_ENQUEUE(ifq, m0); (*sc->sc_start)(sc); } ifp->if_opackets++; @@ -794,6 +811,7 @@ ppp_requeue(sc) struct mbuf *m, **mpp; struct ifqueue *ifq; enum NPmode mode; + int error; for (mpp = &sc->sc_npqueue; (m = *mpp) != NULL; ) { switch (PPP_PROTOCOL(mtod(m, u_char *))) { @@ -811,13 +829,27 @@ ppp_requeue(sc) */ *mpp = m->m_nextpkt; m->m_nextpkt = NULL; - ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd; - if (IF_QFULL(ifq)) { - IF_DROP(ifq); + if ((m->m_flags & M_HIGHPRI) +#ifdef ALTQ + && ALTQ_IS_ENABLED(&sc->sc_if.if_snd) == 0 +#endif + ) { + ifq = &sc->sc_fastq; + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + error = ENOBUFS; + } + else { + IF_ENQUEUE(ifq, m); + error = 0; + } + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m, NULL, error); + if (error) { sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; - } else - IF_ENQUEUE(ifq, m); + } break; case NPMODE_DROP: @@ -869,7 +901,7 @@ ppp_dequeue(sc) */ IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) - IF_DEQUEUE(&sc->sc_if.if_snd, m); + IFQ_DEQUEUE(&sc->sc_if.if_snd, m); if (m == NULL) return NULL; @@ -995,7 +1027,7 @@ pppintr() s = splsoftnet(); for (i = 0; i < NPPP; ++i, ++sc) { if (!(sc->sc_flags & SC_TBUSY) - && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) { + && (IFQ_IS_EMPTY(&sc->sc_if.if_snd) == 0 || sc->sc_fastq.ifq_head)) { s2 = splimp(); sc->sc_flags |= SC_TBUSY; splx(s2); diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 38a24740995..7b7898ac805 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sl.c,v 1.13 2001/06/15 03:38:34 itojun Exp $ */ +/* $OpenBSD: if_sl.c,v 1.14 2001/06/27 06:07:43 kjc Exp $ */ /* $NetBSD: if_sl.c,v 1.39.4.1 1996/06/02 16:26:31 thorpej Exp $ */ /* @@ -214,8 +214,9 @@ slattach(n) sc->sc_if.if_type = IFT_SLIP; sc->sc_if.if_ioctl = slioctl; sc->sc_if.if_output = sloutput; - sc->sc_if.if_snd.ifq_maxlen = 50; + IFQ_SET_MAXLEN(&sc->sc_if.if_snd, 50); sc->sc_fastq.ifq_maxlen = 32; + IFQ_SET_READY(&sc->sc_if.if_snd); if_attach(&sc->sc_if); #if NBPFILTER > 0 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_SLIP, SLIP_HDRLEN); @@ -383,8 +384,10 @@ sloutput(ifp, m, dst, rtp) { register struct sl_softc *sc = ifp->if_softc; register struct ip *ip; - register struct ifqueue *ifq; - int s; + int s, error; + ALTQ_DECL(struct altq_pktattr pktattr;) + + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); /* * `Cannot happen' (see slioctl). Someday we will extend @@ -407,14 +410,11 @@ sloutput(ifp, m, dst, rtp) m_freem(m); return (EHOSTUNREACH); } - ifq = &sc->sc_if.if_snd; ip = mtod(m, struct ip *); if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) { m_freem(m); return (ENETRESET); /* XXX ? */ } - if (ip->ip_tos & IPTOS_LOWDELAY) - ifq = &sc->sc_fastq; s = splimp(); if (sc->sc_oqlen && sc->sc_ttyp->t_outq.c_cc == sc->sc_oqlen) { struct timeval tv; @@ -426,14 +426,13 @@ sloutput(ifp, m, dst, rtp) slstart(sc->sc_ttyp); } } - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + IFQ_ENQUEUE(&sc->sc_if.if_snd, m, &pktattr, error); + if (error) { splx(s); sc->sc_if.if_oerrors++; - return (ENOBUFS); + return (error); } - IF_ENQUEUE(ifq, m); + sc->sc_lastpacket = time; if ((sc->sc_oqlen = sc->sc_ttyp->t_outq.c_cc) == 0) slstart(sc->sc_ttyp); @@ -500,7 +499,7 @@ slstart(tp) if (m) sc->sc_if.if_omcasts++; /* XXX */ else - IF_DEQUEUE(&sc->sc_if.if_snd, m); + IFQ_DEQUEUE(&sc->sc_if.if_snd, m); splx(s); if (m == NULL) return; diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 7a7f30dc6fe..55c69259192 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_spppsubr.c,v 1.8 2001/03/25 02:56:18 csapuntz Exp $ */ +/* $OpenBSD: if_spppsubr.c,v 1.9 2001/06/27 06:07:43 kjc Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. * Keepalive protocol implemented in both Cisco and PPP modes. @@ -639,8 +639,9 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, { struct sppp *sp = (struct sppp*) ifp; struct ppp_header *h; - struct ifqueue *ifq; - int s, rv = 0; + struct ifqueue *ifq = NULL; + int s, len, rv = 0; + ALTQ_DECL(struct altq_pktattr pktattr;) s = splimp(); @@ -662,7 +663,12 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, s = splimp(); } - ifq = &ifp->if_snd; + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + #ifdef INET /* * Put low delay, telnet, rlogin and ftp control packets @@ -782,14 +788,28 @@ nosupport: * Queue message on interface, and start output if interface * not yet active. */ - if (IF_QFULL (ifq)) { - IF_DROP (&ifp->if_snd); - m_freem (m); + len = m->m_pkthdr.len; + if (ifq != NULL +#ifdef ALTQ + && ALTQ_IS_ENABLED(&ifp->if_snd) == 0 +#endif + ) { + if (IF_QFULL (ifq)) { + IF_DROP (&ifp->if_snd); + m_freem (m); + if (rv == 0) + rv = ENOBUFS; + } + IF_ENQUEUE (ifq, m); + } + else + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, rv); + if (rv != 0) { ++ifp->if_oerrors; splx (s); - return (rv? rv: ENOBUFS); + return (rv); } - IF_ENQUEUE (ifq, m); + if (! (ifp->if_flags & IFF_OACTIVE)) (*ifp->if_start) (ifp); @@ -798,7 +818,7 @@ nosupport: * The packet length includes header, FCS and 1 flag, * according to RFC 1333. */ - ifp->if_obytes += m->m_pkthdr.len + 3; + ifp->if_obytes += len + 3; splx (s); return (0); } @@ -823,7 +843,7 @@ sppp_attach(struct ifnet *ifp) sp->pp_if.if_type = IFT_PPP; sp->pp_if.if_output = sppp_output; - sp->pp_if.if_snd.ifq_maxlen = 50; + IFQ_SET_MAXLEN(&sp->pp_if.if_snd, 50); sp->pp_fastq.ifq_maxlen = 50; sp->pp_cpq.ifq_maxlen = 50; sp->pp_loopcnt = 0; @@ -870,7 +890,7 @@ sppp_flush(struct ifnet *ifp) { struct sppp *sp = (struct sppp*) ifp; - sppp_qflush (&sp->pp_if.if_snd); + IFQ_PURGE(&sp->pp_if.if_snd); sppp_qflush (&sp->pp_fastq); sppp_qflush (&sp->pp_cpq); } @@ -886,7 +906,7 @@ sppp_isempty(struct ifnet *ifp) s = splimp(); empty = !sp->pp_fastq.ifq_head && !sp->pp_cpq.ifq_head && - !sp->pp_if.if_snd.ifq_head; + IFQ_IS_EMPTY(&sp->pp_if.if_snd); splx(s); return (empty); } @@ -913,7 +933,7 @@ sppp_dequeue(struct ifnet *ifp) (sppp_ncp_check(sp) || (sp->pp_flags & PP_CISCO) != 0)) { IF_DEQUEUE(&sp->pp_fastq, m); if (m == NULL) - IF_DEQUEUE (&sp->pp_if.if_snd, m); + IFQ_DEQUEUE (&sp->pp_if.if_snd, m); } splx(s); return m; @@ -936,7 +956,7 @@ sppp_pick(struct ifnet *ifp) (sp->pp_phase == PHASE_NETWORK || (sp->pp_flags & PP_CISCO) != 0)) if ((m = sp->pp_fastq.ifq_head) == NULL) - m = sp->pp_if.if_snd.ifq_head; + IFQ_POLL(&sp->pp_if.if_snd, m); splx (s); return (m); } diff --git a/sys/net/if_strip.c b/sys/net/if_strip.c index ccf994ce912..6b3d1c8a484 100644 --- a/sys/net/if_strip.c +++ b/sys/net/if_strip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_strip.c,v 1.14 2001/06/15 03:38:34 itojun Exp $ */ +/* $OpenBSD: if_strip.c,v 1.15 2001/06/27 06:07:44 kjc Exp $ */ /* $NetBSD: if_strip.c,v 1.2.4.3 1996/08/03 00:58:32 jtc Exp $ */ /* from: NetBSD: if_sl.c,v 1.38 1996/02/13 22:00:23 christos Exp $ */ @@ -362,11 +362,12 @@ stripattach(n) sc->sc_if.if_type = IFT_SLIP; sc->sc_if.if_ioctl = stripioctl; sc->sc_if.if_output = stripoutput; - sc->sc_if.if_snd.ifq_maxlen = 50; + IFQ_SET_MAXLEN(&sc->sc_if.if_snd, 50); sc->sc_fastq.ifq_maxlen = 32; sc->sc_if.if_watchdog = strip_watchdog; sc->sc_if.if_timer = STRIP_WATCHDOG_INTERVAL; + IFQ_SET_READY(&sc->sc_if.if_snd); if_attach(&sc->sc_if); #if NBPFILTER > 0 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_SLIP, SLIP_HDRLEN); @@ -715,7 +716,7 @@ stripoutput(ifp, m, dst, rt) register u_char *dldst; /* link-level next-hop */ int s; u_char dl_addrbuf[STARMODE_ADDR_LEN+1]; - + ALTQ_DECL(struct altq_pktattr pktattr;) /* * Verify tty line is up and alive. @@ -779,13 +780,17 @@ stripoutput(ifp, m, dst, rt) return (EAFNOSUPPORT); } - ifq = &sc->sc_if.if_snd; + ifq = NULL; ip = mtod(m, struct ip *); if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) { m_freem(m); return (ENETRESET); /* XXX ? */ } - if (ip->ip_tos & IPTOS_LOWDELAY) + if ((ip->ip_tos & IPTOS_LOWDELAY) +#ifdef ALTQ + && ALTQ_IS_ENABLED(&sc->sc_if.if_snd) == 0 +#endif + ) ifq = &sc->sc_fastq; /* @@ -843,14 +848,22 @@ stripoutput(ifp, m, dst, rt) stripstart(sc->sc_ttyp); } } - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - m_freem(m); + if (ifq != NULL) { + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + m_freem(m); + error = ENOBUFS; + } else { + IF_ENQUEUE(ifq, m); + error = 0; + } + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m, &pktattr, error); + if (error) { splx(s); sc->sc_if.if_oerrors++; - return (ENOBUFS); + return (error); } - IF_ENQUEUE(ifq, m); sc->sc_lastpacket = time; if ((sc->sc_oqlen = sc->sc_ttyp->t_outq.c_cc) == 0) { stripstart(sc->sc_ttyp); @@ -940,7 +953,7 @@ stripstart(tp) if (m) sc->sc_if.if_omcasts++; /* XXX */ else - IF_DEQUEUE(&sc->sc_if.if_snd, m); + IFQ_DEQUEUE(&sc->sc_if.if_snd, m); splx(s); if (m == NULL) { return; diff --git a/sys/net/if_tokensubr.c b/sys/net/if_tokensubr.c index d0b85026f85..8b745ca24e6 100644 --- a/sys/net/if_tokensubr.c +++ b/sys/net/if_tokensubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tokensubr.c,v 1.3 2001/06/15 03:38:34 itojun Exp $ */ +/* $OpenBSD: if_tokensubr.c,v 1.4 2001/06/27 06:07:45 kjc Exp $ */ /* $NetBSD: if_tokensubr.c,v 1.7 1999/05/30 00:39:07 bad Exp $ */ /* @@ -140,7 +140,7 @@ token_output(ifp, m0, dst, rt0) struct rtentry *rt0; { u_int16_t etype; - int s, error = 0; + int s, len, error = 0; u_char edst[ISO88025_ADDR_LEN]; register struct mbuf *m = m0; register struct rtentry *rt; @@ -152,6 +152,8 @@ token_output(ifp, m0, dst, rt0) struct token_rif *rif = (struct token_rif *)0; struct token_rif bcastrif; size_t riflen = 0; + ALTQ_DECL(struct altq_pktattr pktattr;) + short mflags; if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) senderr(ENETDOWN); @@ -177,6 +179,13 @@ token_output(ifp, m0, dst, rt0) time.tv_sec < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } + + /* + * If the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + switch (dst->sa_family) { #ifdef INET @@ -439,23 +448,25 @@ token_output(ifp, m0, dst, rt0) send: #endif /* 0 */ + mflags = m->m_flags; + len = m->m_pkthdr.len; s = splimp(); /* * Queue message on interface, and start output if interface * not yet active. */ - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); + IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); + if (error) { + /* mbuf is already freed */ splx(s); - senderr(ENOBUFS); + return (error); } - ifp->if_obytes += m->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m); + ifp->if_obytes += len; + if (mflags & M_MCAST) + ifp->if_omcasts++; if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); - if (m->m_flags & M_MCAST) - ifp->if_omcasts++; return (error); bad: diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index e9b7ff47528..e93689d2b8b 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tun.c,v 1.35 2001/06/15 03:38:34 itojun Exp $ */ +/* $OpenBSD: if_tun.c,v 1.36 2001/06/27 06:07:46 kjc Exp $ */ /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ /* @@ -112,6 +112,9 @@ int tunselect __P((dev_t, int, struct proc *)); static int tuninit __P((struct tun_softc *)); +#ifdef ALTQ +static void tunstart __P((struct ifnet *)); +#endif void tunattach(n) @@ -132,9 +135,13 @@ tunattach(n) ifp->if_mtu = TUNMTU; ifp->if_ioctl = tun_ioctl; ifp->if_output = tun_output; +#ifdef ALTQ + ifp->if_start = tunstart; +#endif ifp->if_flags = IFF_POINTOPOINT; ifp->if_type = IFT_PROPVIRTUAL; - ifp->if_snd.ifq_maxlen = ifqmaxlen; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); ifp->if_hdrlen = sizeof(u_int32_t); ifp->if_collisions = 0; ifp->if_ierrors = 0; @@ -194,7 +201,6 @@ tunclose(dev, flag, mode, p) register int unit, s; struct tun_softc *tp; struct ifnet *ifp; - struct mbuf *m; if ((unit = minor(dev)) >= ntun) return (ENXIO); @@ -206,13 +212,9 @@ tunclose(dev, flag, mode, p) /* * junk all pending output */ - do { - s = splimp(); - IF_DEQUEUE(&ifp->if_snd, m); - splx(s); - if (m) - m_freem(m); - } while (m); + s = splimp(); + IFQ_PURGE(&ifp->if_snd); + splx(s); if ((ifp->if_flags & IFF_UP) && !(tp->tun_flags & TUN_STAYUP)) { s = splimp(); @@ -330,8 +332,9 @@ tun_output(ifp, m0, dst, rt) struct rtentry *rt; { struct tun_softc *tp = ifp->if_softc; - int s; + int s, len, error; u_int32_t *af; + ALTQ_DECL(struct altq_pktattr pktattr;) TUNDEBUG(("%s: tun_output\n", ifp->if_xname)); @@ -342,6 +345,12 @@ tun_output(ifp, m0, dst, rt) return EHOSTDOWN; } + /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr); + M_PREPEND(m0, sizeof(*af), M_DONTWAIT); af = mtod(m0, u_int32_t *); *af = htonl(dst->sa_family); @@ -351,19 +360,17 @@ tun_output(ifp, m0, dst, rt) bpf_mtap(ifp->if_bpf, m0); #endif + len = m0->m_pkthdr.len + sizeof(*af); s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - m_freem(m0); + IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error); + if (error) { splx(s); ifp->if_collisions++; - return (ENOBUFS); + return (error); } - IF_ENQUEUE(&ifp->if_snd, m0); - - ifp->if_opackets++; - ifp->if_obytes += m0->m_pkthdr.len + sizeof(*af); splx(s); + ifp->if_opackets++; + ifp->if_obytes += len; if (tp->tun_flags & TUN_RWAIT) { tp->tun_flags &= ~TUN_RWAIT; @@ -510,7 +517,7 @@ tunread(dev, uio, ioflag) splx(s); return (error); } - IF_DEQUEUE(&ifp->if_snd, m0); + IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == 0) { if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) { splx(s); @@ -716,3 +723,34 @@ tunselect(dev, rw, p) TUNDEBUG(("%s: tunselect waiting\n", ifp->if_xname)); return 0; } + +#ifdef ALTQ +/* + * Start packet transmission on the interface. + * when the interface queue is rate-limited by ALTQ or TBR, + * if_start is needed to drain packets from the queue in order + * to notify readers when outgoing packets become ready. + */ +static void +tunstart(ifp) + struct ifnet *ifp; +{ + struct tun_softc *tp = ifp->if_softc; + struct mbuf *m; + + if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd)) + return; + + IFQ_POLL(&ifp->if_snd, m); + if (m != NULL) { + if (tp->tun_flags & TUN_RWAIT) { + tp->tun_flags &= ~TUN_RWAIT; + wakeup((caddr_t)tp); + } + if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) + csignal(tp->tun_pgid, SIGIO, + tp->tun_siguid, tp->tun_sigeuid); + selwakeup(&tp->tun_rsel); + } +} +#endif diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index fcb27c76b22..5f7546803fa 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan.c,v 1.23 2001/06/27 03:49:53 angelos Exp $ */ +/* $OpenBSD: if_vlan.c,v 1.24 2001/06/27 06:07:46 kjc Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology * @@ -165,7 +165,8 @@ vlanattach(void *dummy) ifp->if_start = vlan_start; ifp->if_ioctl = vlan_ioctl; ifp->if_output = ether_output; - ifp->if_snd.ifq_maxlen = ifqmaxlen; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp); @@ -182,13 +183,15 @@ vlan_start(struct ifnet *ifp) struct ifnet *p; struct ether_vlan_header *evl; struct mbuf *m, *m0; + int error; + ALTQ_DECL(struct altq_pktattr pktattr;) ifv = ifp->if_softc; p = ifv->ifv_p; ifp->if_flags |= IFF_OACTIVE; for (;;) { - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; @@ -201,6 +204,26 @@ vlan_start(struct ifnet *ifp) continue; } +#ifdef ALTQ + /* + * If ALTQ is enabled on the parent interface, do + * classification; the queueing discipline might + * not require classification, but might require + * the address family/header pointer in the pktattr. + */ + if (ALTQ_IS_ENABLED(&p->if_snd)) { + switch (p->if_type) { + case IFT_ETHER: + altq_etherclassify(&p->if_snd, m, &pktattr); + break; +#ifdef DIAGNOSTIC + default: + panic("vlan_start: impossible (altq)"); +#endif + } + } +#endif /* ALTQ */ + #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, m); @@ -271,17 +294,16 @@ vlan_start(struct ifnet *ifp) * Send it, precisely as ether_output() would have. * We are already running at splimp. */ - if (IF_QFULL(&p->if_snd)) { - IF_DROP(&p->if_snd); - /* XXX stats */ - ifp->if_oerrors++; - m_freem(m); - continue; - } p->if_obytes += m->m_pkthdr.len; if (m->m_flags & M_MCAST) p->if_omcasts++; - IF_ENQUEUE(&p->if_snd, m); + IFQ_ENQUEUE(&p->if_snd, m, &pktattr, error); + if (error) { + /* mbuf is already freed */ + ifp->if_oerrors++; + continue; + } + ifp->if_opackets++; if ((p->if_flags & IFF_OACTIVE) == 0) p->if_start(p); diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h index 7abd64b245a..308effcfd9a 100644 --- a/sys/netinet/if_ether.h +++ b/sys/netinet/if_ether.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.h,v 1.16 2001/06/23 21:32:26 fgsch Exp $ */ +/* $OpenBSD: if_ether.h,v 1.17 2001/06/27 06:07:47 kjc Exp $ */ /* $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $ */ /* @@ -285,6 +285,9 @@ void revarprequest __P((struct ifnet *)); int revarpwhoarewe __P((struct ifnet *, struct in_addr *, struct in_addr *)); int revarpwhoami __P((struct in_addr *, struct ifnet *)); int db_show_arptab __P((void)); +#ifdef ALTQ +void altq_etherclassify(struct ifaltq *, struct mbuf *, struct altq_pktattr *); +#endif /* ALTQ */ #else |