Index: conf/files =================================================================== RCS file: /home/ncvs/src/sys/conf/files,v retrieving revision 1.790 diff -u -r1.790 files --- conf/files 11 May 2003 06:37:52 -0000 1.790 +++ conf/files 31 May 2003 04:57:55 -0000 @@ -39,6 +39,20 @@ kern/bus_if.m standard kern/clock_if.m optional genclock kern/linker_if.m standard +altq/altq_afmap.c optional altq +altq/altq_blue.c optional altq +altq/altq_cbq.c optional altq +altq/altq_cdnr.c optional altq +altq/altq_conf.c optional altq +altq/altq_fifoq.c optional altq +altq/altq_hfsc.c optional altq +altq/altq_localq.c optional altq +altq/altq_priq.c optional altq +altq/altq_red.c optional altq +altq/altq_rio.c optional altq +altq/altq_rmclass.c optional altq +altq/altq_subr.c optional altq +altq/altq_wfq.c optional altq cam/cam.c optional scbus cam/cam_periph.c optional scbus cam/cam_queue.c optional scbus Index: conf/options =================================================================== RCS file: /home/ncvs/src/sys/conf/options,v retrieving revision 1.393 diff -u -r1.393 options --- conf/options 18 May 2003 03:46:30 -0000 1.393 +++ conf/options 31 May 2003 04:26:59 -0000 @@ -309,6 +309,21 @@ # Net stuff. ACCEPT_FILTER_DATA ACCEPT_FILTER_HTTP +ALTQ opt_global.h +ALTQ_BLUE opt_altq.h +ALTQ_CBQ opt_altq.h +ALTQ_FIFOQ opt_altq.h +ALTQ_FLOWVALVE opt_altq.h +ALTQ_HFSC opt_altq.h +ALTQ_LOCALQ opt_altq.h +ALTQ_PRIQ opt_altq.h +ALTQ_RED opt_altq.h +ALTQ_RIO opt_altq.h +ALTQ_WFQ opt_altq.h +ALTQ_CDNR opt_altq.h +ALTQ_IPSEC opt_altq.h +ALTQ_NOPCC opt_altq.h +ALTQ_DEBUG opt_altq.h BOOTP opt_bootp.h BOOTP_COMPAT opt_bootp.h BOOTP_NFSROOT opt_bootp.h Index: net/bridge.c =================================================================== RCS file: /home/ncvs/src/sys/net/bridge.c,v retrieving revision 1.67 diff -u -r1.67 bridge.c --- net/bridge.c 19 Feb 2003 05:47:28 -0000 1.67 +++ net/bridge.c 31 May 2003 04:27:03 -0000 @@ -816,11 +816,13 @@ int once = 0; /* loop only once */ struct ifnet *real_dst = dst ; /* real dst from ether_output */ struct ip_fw_args args; + int error; #ifdef PFIL_HOOKS struct packet_filter_hook *pfh; int rv; #endif /* PFIL_HOOKS */ struct ether_header save_eh; + ALTQ_DECL(struct altq_pktattr pktattr;) DEB(quad_t ticks; ticks = rdtsc();) @@ -1050,7 +1052,8 @@ return m0 ; /* the original is still there... */ } } - if (!IF_HANDOFF(&last->if_snd, m, last)) { + IFQ_HANDOFF(last, m, &pktattr, error); + if (error != 0) { #if 0 BDG_MUTE(last); /* should I also mute ? */ #endif Index: net/if.c =================================================================== RCS file: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.163 diff -u -r1.163 if.c --- net/if.c 30 Apr 2003 12:57:40 -0000 1.163 +++ net/if.c 31 May 2003 04:27:03 -0000 @@ -83,7 +83,7 @@ static void if_init(void *); static void if_check(void *); static int if_findindex(struct ifnet *); -static void if_qflush(struct ifqueue *); +static void if_qflush(struct ifaltq *); static void if_slowtimo(void *); static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *); static int if_rtdel(struct radix_node *, void *); @@ -441,6 +441,13 @@ TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); } ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ +#ifdef ALTQ + ifp->if_snd.altq_type = 0; + ifp->if_snd.altq_disc = NULL; + ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE; + ifp->if_snd.altq_tbr = NULL; + ifp->if_snd.altq_ifp = ifp; +#endif /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); @@ -464,6 +471,12 @@ */ s = splnet(); if_down(ifp); +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) + altq_disable(&ifp->if_snd); + if (ALTQ_IS_ATTACHED(&ifp->if_snd)) + altq_detach(&ifp->if_snd); +#endif /* * Remove address from ifindex_table[] and maybe decrement if_index. @@ -1141,10 +1154,14 @@ */ static void if_qflush(ifq) - register struct ifqueue *ifq; + register struct ifaltq *ifq; { register struct mbuf *m, *n; +#ifdef ALTQ + if (ALTQ_IS_ENABLED(ifq)) + ALTQ_PURGE(ifq); +#endif n = ifq->ifq_head; while ((m = n) != 0) { n = m->m_act; Index: net/if_arcsubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_arcsubr.c,v retrieving revision 1.13 diff -u -r1.13 if_arcsubr.c --- net/if_arcsubr.c 4 Mar 2003 23:19:51 -0000 1.13 +++ net/if_arcsubr.c 31 May 2003 04:27:03 -0000 @@ -78,6 +78,7 @@ #include #include #endif + ALTQ_DECL(struct altq_pktattr pktattr;) MODULE_VERSION(arcnet, 1); @@ -124,6 +125,12 @@ error = rt_check(&rt, &rt0, dst); if (error) goto bad; + + /* + * 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 Index: net/if_atmsubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_atmsubr.c,v retrieving revision 1.27 diff -u -r1.27 if_atmsubr.c --- net/if_atmsubr.c 31 May 2003 20:07:16 -0000 1.27 +++ net/if_atmsubr.c 1 Jun 2003 06:44:19 -0000 @@ -109,6 +109,7 @@ struct atmllc *atmllc; struct atmllc *llc_hdr = NULL; u_int32_t atm_flags; + ALTQ_DECL(struct altq_pktattr pktattr;) #ifdef MAC error = mac_check_ifnet_transmit(ifp, m); @@ -120,6 +121,12 @@ senderr(ENETDOWN); /* + * if the queueing discipline needs packet classification, + * do it before prepending link headers. + */ + IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); + + /* * check route */ error = rt_check(&rt, &rt0, dst); @@ -196,8 +203,7 @@ * Queue message on interface, and start output if interface * not yet active. */ - if (! IF_HANDOFF(&ifp->if_snd, m, ifp)) - return (ENOBUFS); + IFQ_HANDOFF(ifp, m, &pktattr, error); return (error); bad: @@ -219,7 +225,6 @@ { int isr; u_int16_t etype = ETHERTYPE_IP; /* default */ - int s; if ((ifp->if_flags & IFF_UP) == 0) { m_freem(m); Index: net/if_ef.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ef.c,v retrieving revision 1.25 diff -u -r1.25 if_ef.c --- net/if_ef.c 31 May 2003 20:06:27 -0000 1.25 +++ net/if_ef.c 1 Jun 2003 06:44:19 -0000 @@ -215,17 +215,19 @@ struct efnet *sc = (struct efnet*)ifp->if_softc; struct ifnet *p; struct mbuf *m; + int error; ifp->if_flags |= IFF_OACTIVE; p = sc->ef_ifp; EFDEBUG("\n"); for (;;) { - IF_DEQUEUE(&ifp->if_snd, m); + IFQ_DEQUEUE(&ifp->if_snd, m); if (m == 0) break; BPF_MTAP(ifp, m); - if (! IF_HANDOFF(&p->if_snd, m, p)) { + IFQ_HANDOFF(p, m, NULL, error); + if (error != 0) { ifp->if_oerrors++; continue; } Index: net/if_ethersubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.147 diff -u -r1.147 if_ethersubr.c --- net/if_ethersubr.c 5 May 2003 09:15:50 -0000 1.147 +++ net/if_ethersubr.c 31 May 2003 04:27:03 -0000 @@ -324,6 +324,8 @@ ether_output_frame(struct ifnet *ifp, struct mbuf *m) { struct ip_fw *rule = NULL; + ALTQ_DECL(struct altq_pktattr pktattr;) + int error; /* Extract info from dummynet tag, ignore others */ for (; m->m_type == MT_TAG; m = m->m_next) @@ -352,11 +354,17 @@ } } +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) + altq_etherclassify(&ifp->if_snd, m, &pktattr); +#endif + /* * Queue message on interface, update output statistics if * successful, and start output if interface not yet active. */ - return (IF_HANDOFF(&ifp->if_snd, m, ifp) ? 0 : ENOBUFS); + IFQ_HANDOFF(ifp, m, &pktattr, error); + return (error); } /* @@ -953,6 +961,81 @@ return (error); } +#ifdef ALTQ +/* + * find the size of ethernet header, and call classifier + */ +void +altq_etherclassify(ifq, m, pktattr) + struct ifaltq *ifq; + struct mbuf *m; + struct altq_pktattr *pktattr; +{ + struct ether_header *eh; + u_short ether_type; + int hlen, af, hdrsize; + caddr_t hdr; + + hlen = sizeof(struct ether_header); + eh = mtod(m, struct ether_header *); + + ether_type = ntohs(eh->ether_type); + if (ether_type < ETHERMTU) { + /* ick! 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) + goto bad; /* not snap! */ + + ether_type = ntohs(llc->llc_un.type_snap.ether_type); + } + + if (ether_type == ETHERTYPE_IP) { + af = AF_INET; + hdrsize = 20; /* sizeof(struct ip) */ +#ifdef INET6 + } else if (ether_type == ETHERTYPE_IPV6) { + af = AF_INET6; + hdrsize = 40; /* sizeof(struct ip6_hdr) */ +#endif + } else + goto bad; + + while (m->m_len <= hlen) { + hlen -= m->m_len; + m = m->m_next; + } + hdr = m->m_data + hlen; + if (m->m_len < hlen + hdrsize) { + /* + * ip header is not in a single mbuf. this should not + * happen in the current code. + * (todo: use m_pulldown in the future) + */ + goto bad; + } + m->m_data += hlen; + m->m_len -= hlen; + if (ALTQ_NEEDS_CLASSIFY(ifq)) + pktattr->pattr_class = + (*ifq->altq_classify)(ifq->altq_clfier, m, af); + m->m_data -= hlen; + m->m_len += hlen; + + pktattr->pattr_af = af; + pktattr->pattr_hdr = hdr; + return; + +bad: + pktattr->pattr_class = NULL; + pktattr->pattr_hdr = NULL; + pktattr->pattr_af = AF_UNSPEC; +} +#endif /* ALTQ */ static int ether_resolvemulti(ifp, llsa, sa) struct ifnet *ifp; Index: net/if_fddisubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_fddisubr.c,v retrieving revision 1.85 diff -u -r1.85 if_fddisubr.c --- net/if_fddisubr.c 16 Mar 2003 00:17:44 -0000 1.85 +++ net/if_fddisubr.c 31 May 2003 04:27:03 -0000 @@ -121,6 +121,7 @@ struct rtentry *rt; struct fddi_header *fh; struct arpcom *ac = IFP2AC(ifp); + ALTQ_DECL(struct altq_pktattr pktattr;) #ifdef MAC error = mac_check_ifnet_transmit(ifp, m); @@ -314,8 +315,7 @@ } } - if (! IF_HANDOFF(&ifp->if_snd, m, ifp)) - senderr(ENOBUFS); + IFQ_HANDOFF(ifp, m, &pktattr, error); return (error); bad: Index: net/if_iso88025subr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_iso88025subr.c,v retrieving revision 1.54 diff -u -r1.54 if_iso88025subr.c --- net/if_iso88025subr.c 16 Mar 2003 00:17:44 -0000 1.54 +++ net/if_iso88025subr.c 31 May 2003 04:27:03 -0000 @@ -284,6 +284,12 @@ } } + /* + * 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 case AF_INET: Index: net/if_loop.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_loop.c,v retrieving revision 1.83 diff -u -r1.83 if_loop.c --- net/if_loop.c 28 May 2003 02:04:33 -0000 1.83 +++ net/if_loop.c 31 May 2003 04:52:37 -0000 @@ -108,6 +108,9 @@ struct sockaddr *dst, struct rtentry *rt); int lo_clone_create(struct if_clone *, int); void lo_clone_destroy(struct ifnet *); +#ifdef ALTQ +static void lo_altqstart __P((struct ifnet *)); +#endif struct ifnet *loif = NULL; /* Used externally */ @@ -151,8 +154,12 @@ sc->sc_if.if_ioctl = loioctl; sc->sc_if.if_output = looutput; sc->sc_if.if_type = IFT_LOOP; - sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen; sc->sc_if.if_softc = sc; + IFQ_SET_MAXLEN(&sc->sc_if.if_snd, ifqmaxlen); + IFQ_SET_READY(&sc->sc_if.if_snd); +#ifdef ALTQ + sc->sc_if.if_start = lo_altqstart; +#endif if_attach(&sc->sc_if); bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); LIST_INSERT_HEAD(&lo_list, sc, sc_next); @@ -310,6 +317,35 @@ #endif } +#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, af, &pktattr); + + M_PREPEND(m, sizeof(int32_t), M_DONTWAIT); + if (m == 0) + return(ENOBUFS); + afp = mtod(m, int32_t *); + *afp = (int32_t)af; + + IFQ_HANDOFF(ifp, m, &pktattr, error); + return (error); + } +#endif /* ALTQ */ + /* Deliver to upper layer protocol */ switch (af) { #ifdef INET @@ -343,6 +379,59 @@ netisr_dispatch(isr, m); return (0); } + +#ifdef ALTQ +static void +lo_altqstart(ifp) + struct ifnet *ifp; +{ + struct mbuf *m; + int32_t af, *afp; + int isr; + + while (1) { + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + return; + + afp = mtod(m, int32_t *); + af = *afp; + m_adj(m, sizeof(int32_t)); + + switch (af) { +#ifdef INET + case AF_INET: + isr = NETISR_IP; + break; +#endif +#ifdef INET6 + case AF_INET6: + m->m_flags |= M_LOOP; + isr = NETISR_IPV6; + break; +#endif +#ifdef IPX + case AF_IPX: + isr = NETISR_IPX; + break; +#endif +#ifdef NETATALK + case AF_APPLETALK: + isr = NETISR_ATALK; + break; +#endif + default: + printf("lo_altqstart: can't handle af%d\n", af); + m_freem(m); + return; + } + + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + netisr_dispatch(isr, m); + } +} +#endif /* ALTQ */ /* ARGSUSED */ static void Index: net/if_ppp.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ppp.c,v retrieving revision 1.91 diff -u -r1.91 if_ppp.c --- net/if_ppp.c 27 Mar 2003 12:52:57 -0000 1.91 +++ net/if_ppp.c 31 May 2003 04:27:04 -0000 @@ -900,18 +900,26 @@ sc->sc_npqtail = &m0->m_nextpkt; } else { /* fastq and if_snd are emptied at spl[soft]net now */ - ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd; - IF_LOCK(ifq); - if (_IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { - _IF_DROP(ifq); + if (m0->m_flags & M_HIGHPRI) { + ifq = &sc->sc_fastq; + IF_LOCK(ifq); + if (_IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) { + _IF_DROP(ifq); + m_freem(m0); + error = ENOBUFS; + } else { + _IF_ENQUEUE(ifq, m0); + error = 0; + } IF_UNLOCK(ifq); + } else + IFQ_ENQUEUE(&sc->sc_if.if_snd, m0, NULL, error); + if (error != 0) { + splx(s); sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; - error = ENOBUFS; - goto bad; + return (error); } - _IF_ENQUEUE(ifq, m0); - IF_UNLOCK(ifq); (*sc->sc_start)(sc); } getmicrotime(&ifp->if_lastchange); @@ -936,8 +944,8 @@ struct ppp_softc *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 *))) { @@ -955,8 +963,14 @@ */ *mpp = m->m_nextpkt; m->m_nextpkt = NULL; - ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd; - if (! IF_HANDOFF(ifq, m, NULL)) { + if (m->m_flags & M_HIGHPRI) { + if (! IF_HANDOFF(&sc->sc_fastq, m, NULL)) + error = ENOBUFS; + else + error = 0; + } else + IFQ_HANDOFF(&sc->sc_if, m, NULL, error); + if (error != 0) { sc->sc_if.if_oerrors++; sc->sc_stats.ppp_oerrors++; } Index: net/if_sl.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_sl.c,v retrieving revision 1.110 diff -u -r1.110 if_sl.c --- net/if_sl.c 4 Mar 2003 23:19:51 -0000 1.110 +++ net/if_sl.c 31 May 2003 04:27:04 -0000 @@ -546,7 +546,7 @@ register struct sl_softc *sc = ifp->if_softc; register struct ip *ip; register struct ifqueue *ifq; - int s; + int s, error; /* * `Cannot happen' (see slioctl). Someday we will extend @@ -567,18 +567,24 @@ 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) + if (ip->ip_tos & IPTOS_LOWDELAY) { ifq = &sc->sc_fastq; - if (! IF_HANDOFF(ifq, m, NULL)) { + if (! IF_HANDOFF(ifq, m, NULL)) + error = ENOBUFS; + else + error = 0; + } else + IFQ_HANDOFF(&sc->sc_if, m, NULL, error); + if (error != 0) { sc->sc_if.if_oerrors++; return (ENOBUFS); } + s = splimp(); if (sc->sc_ttyp->t_outq.c_cc == 0) slstart(sc->sc_ttyp); Index: net/if_spppsubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.102 diff -u -r1.102 if_spppsubr.c --- net/if_spppsubr.c 5 Mar 2003 19:24:22 -0000 1.102 +++ net/if_spppsubr.c 31 May 2003 04:27:04 -0000 @@ -741,9 +741,10 @@ struct sppp *sp = (struct sppp*) ifp; struct ppp_header *h; struct ifqueue *ifq = NULL; - int s, rv = 0; + int s, error, rv = 0; int ipproto = PPP_IP; int debug = ifp->if_flags & IFF_DEBUG; + ALTQ_DECL(struct altq_pktattr pktattr;) s = splimp(); @@ -781,7 +782,12 @@ 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 if (dst->sa_family == AF_INET) { /* XXX Check mbuf length here? */ @@ -1038,7 +1044,7 @@ { 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); } @@ -1054,7 +1060,7 @@ 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); } Index: net/if_tun.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_tun.c,v retrieving revision 1.125 diff -u -r1.125 if_tun.c --- net/if_tun.c 8 Mar 2003 17:32:21 -0000 1.125 +++ net/if_tun.c 31 May 2003 04:27:04 -0000 @@ -426,9 +426,7 @@ struct rtentry *rt) { struct tun_softc *tp = ifp->if_softc; -#ifdef MAC int error; -#endif TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); @@ -514,9 +512,10 @@ } } - if (! IF_HANDOFF(&ifp->if_snd, m0, ifp)) { + IFQ_HANDOFF(ifp, m0, NULL, error); + if (error != 0) { ifp->if_collisions++; - return (ENOBUFS); + return (error); } ifp->if_opackets++; return (0); Index: net/if_var.h =================================================================== RCS file: /home/ncvs/src/sys/net/if_var.h,v retrieving revision 1.58 diff -u -r1.58 if_var.h --- net/if_var.h 1 Jan 2003 18:48:54 -0000 1.58 +++ net/if_var.h 31 May 2003 05:02:59 -0000 @@ -84,6 +84,10 @@ #include /* XXX */ #include /* XXX */ +#if 1 /* ALTQ */ +#include +#endif + TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ TAILQ_HEAD(ifprefixhead, ifprefix); @@ -173,7 +177,11 @@ (void *); int (*if_resolvemulti) /* validate/resolve multicast */ (struct ifnet *, struct sockaddr **, struct sockaddr *); +#if 1 /* ALTQ */ + struct ifaltq if_snd; /* output queue (includes altq) */ +#else struct ifqueue if_snd; /* output queue */ +#endif struct ifqueue *if_poll_slowq; /* input queue for slow devices */ struct ifprefixhead if_prefixhead; /* list of prefixes per if */ u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ @@ -274,19 +282,27 @@ IF_UNLOCK(ifq); \ } while (0) -#define IF_DRAIN(ifq) do { \ +#define _IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) +#define IF_POLL(ifq, m) _IF_POLL(ifq) + +#define _IF_DRAIN(ifq) do { \ struct mbuf *m; \ - IF_LOCK(ifq); \ for (;;) { \ _IF_DEQUEUE(ifq, m); \ if (m == NULL) \ break; \ m_freem(m); \ } \ +} while (0) + +#define IF_DRAIN(ifq) do { \ + IF_LOCK(ifq); \ + _IF_DRAIN(ifq); \ IF_UNLOCK(ifq); \ } while (0) #ifdef _KERNEL + #define IF_HANDOFF(ifq, m, ifp) if_handoff(ifq, m, ifp, 0) #define IF_HANDOFF_ADJ(ifq, m, ifp, adj) if_handoff(ifq, m, ifp, adj) @@ -314,6 +330,137 @@ (*ifp->if_start)(ifp); return (1); } +#ifdef ALTQ +#define ALTQ_DECL(x) x + +#define IFQ_ENQUEUE(ifq, m, pattr, err) \ +do { \ + IF_LOCK(ifq); \ + if (ALTQ_IS_ENABLED(ifq)) \ + ALTQ_ENQUEUE(ifq, m, pattr, err); \ + else { \ + if (_IF_QFULL(ifq)) { \ + m_freem(m); \ + (err) = ENOBUFS; \ + } else { \ + _IF_ENQUEUE(ifq, m); \ + (err) = 0; \ + } \ + } \ + if (err) \ + (ifq)->ifq_drops++; \ + IF_UNLOCK(ifq); \ +} while (0) + +#define IFQ_DEQUEUE_NOLOCK(ifq, m) \ +do { \ + if (TBR_IS_ENABLED(ifq)) \ + (m) = tbr_dequeue(ifq, ALTDQ_REMOVE); \ + else if (ALTQ_IS_ENABLED(ifq)) \ + ALTQ_DEQUEUE(ifq, m); \ + else \ + _IF_DEQUEUE(ifq, m); \ +} while (0) + +#define IFQ_DEQUEUE(ifq, m) \ +do { \ + IF_LOCK(ifq); \ + IFQ_DEQUEUE_NOLOCK(ifq, m); \ + IF_UNLOCK(ifq); \ +} while (0) + +#define IFQ_POLL_NOLOCK(ifq, m) \ +do { \ + if (TBR_IS_ENABLED(ifq)) \ + (m) = tbr_dequeue(ifq, ALTDQ_POLL); \ + else if (ALTQ_IS_ENABLED(ifq)) \ + ALTQ_POLL(ifq, m); \ + else \ + _IF_POLL(ifq, m); \ +} while (0) + +#define IFQ_PURGE_NOLOCK(ifq) \ +do { \ + if (ALTQ_IS_ENABLED(ifq)) { \ + ALTQ_PURGE(ifq); \ + } else \ + _IF_DRAIN(ifq); \ +} while (0) + +#define IFQ_PURGE(ifq) \ +do { \ + IF_LOCK(ifq); \ + IFQ_PURGE_NOLOCK(ifq); \ + IF_UNLOCK(ifq); \ +} while (0) + +#define IFQ_SET_READY(ifq) \ + do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) + +#define IFQ_CLASSIFY(ifq, m, af, pa) \ +do { \ + if (ALTQ_IS_ENABLED(ifq)) { \ + if (ALTQ_NEEDS_CLASSIFY(ifq)) \ + (pa)->pattr_class = (*(ifq)->altq_classify) \ + ((ifq)->altq_clfier, m, af); \ + (pa)->pattr_af = (af); \ + (pa)->pattr_hdr = mtod((m), caddr_t); \ + } \ +} while (0) + +#else /* !ALTQ */ +#define ALTQ_DECL(x) /* nothing */ + +#define IFQ_ENQUEUE(ifq, m, pattr, err) \ +do { \ + IF_LOCK(ifq); \ + if (_IF_QFULL(ifq)) { \ + m_freem(m); \ + (err) = ENOBUFS; \ + } else { \ + _IF_ENQUEUE(ifq, m); \ + (err) = 0; \ + } \ + if (err) \ + (ifq)->ifq_drops++; \ + IF_UNLOCK(ifq); \ +} while (0) + +#define IFQ_DEQUEUE_NOLOCK(ifq, m) _IF_DEQUEUE(ifq, m) +#define IFQ_DEQUEUE(ifq, m) IF_DEQUEUE(ifq, m) +#define IFQ_POLL_NOLOCK(ifq, m) _IF_POLL(ifq, m) +#define IFQ_PURGE_NOLOCK(ifq) _IF_DRAIN(ifq) +#define IFQ_PURGE(ifq) IF_DRAIN(ifq) + +#define IFQ_SET_READY(ifq) /* nothing */ +#define IFQ_CLASSIFY(ifq, m, af, pa) /* nothing */ + +#endif /* !ALTQ */ + +#define IFQ_LOCK(ifq) IF_LOCK(ifq) +#define IFQ_UNLOCK(ifq) IF_UNLOCK(ifq) +#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) +#define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) +#define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) +#define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) +#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) + +#define IFQ_HANDOFF(ifp, m, pattr, err) \ +do { \ + int len; \ + short mflags; \ + \ + len = (m)->m_pkthdr.len; \ + mflags = (m)->m_flags; \ + IFQ_ENQUEUE(&(ifp)->if_snd, m, pattr, err); \ + if ((err) == 0) { \ + (ifp)->if_obytes += len; \ + if (mflags & M_MCAST) \ + (ifp)->if_omcasts++; \ + if (((ifp)->if_flags & IFF_OACTIVE) == 0) \ + (*(ifp)->if_start)(ifp); \ + } \ +} while (0) /* * 72 was chosen below because it is the size of a TCP/IP Index: net/if_vlan.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_vlan.c,v retrieving revision 1.49 diff -u -r1.49 if_vlan.c --- net/if_vlan.c 12 Mar 2003 14:45:22 -0000 1.49 +++ net/if_vlan.c 31 May 2003 04:27:04 -0000 @@ -290,13 +290,14 @@ struct ifnet *p; struct ether_vlan_header *evl; struct mbuf *m; + int error; 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 == 0) break; BPF_MTAP(ifp, m); @@ -370,7 +371,8 @@ * Send it, precisely as ether_output() would have. * We are already running at splimp. */ - if (IF_HANDOFF(&p->if_snd, m, p)) + IFQ_HANDOFF(p, m, &pktattr, error); + if (error == 0) ifp->if_opackets++; else ifp->if_oerrors++; Index: netinet/ip.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip.h,v retrieving revision 1.24 diff -u -r1.24 ip.h --- netinet/ip.h 2 Apr 2003 20:14:43 -0000 1.24 +++ netinet/ip.h 31 May 2003 04:27:04 -0000 @@ -84,10 +84,10 @@ #define IPTOS_THROUGHPUT 0x08 #define IPTOS_RELIABILITY 0x04 #define IPTOS_MINCOST 0x02 -/* ECN bits proposed by Sally Floyd */ +#if 1 /* obsoleted by RFC3168 */ #define IPTOS_CE 0x01 /* congestion experienced */ #define IPTOS_ECT 0x02 /* ECN-capable transport */ - +#endif /* * Definitions for IP precedence (also in ip_tos) (hopefully unused) @@ -100,6 +100,16 @@ #define IPTOS_PREC_IMMEDIATE 0x40 #define IPTOS_PREC_PRIORITY 0x20 #define IPTOS_PREC_ROUTINE 0x00 + +/* + * ECN (Explicit Congestion Notification) codepoints in RFC3168 + * mapped to the lower 2 bits of the TOS field. + */ +#define IPTOS_ECN_NOTECT 0x00 /* not-ECT */ +#define IPTOS_ECN_ECT1 0x01 /* ECN-capable transport (1) */ +#define IPTOS_ECN_ECT0 0x02 /* ECN-capable transport (0) */ +#define IPTOS_ECN_CE 0x03 /* congestion experienced */ +#define IPTOS_ECN_MASK 0x03 /* ECN field mask */ /* * Definitions for options. Index: netinet/ip_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.237 diff -u -r1.237 ip_input.c --- netinet/ip_input.c 6 May 2003 20:34:04 -0000 1.237 +++ netinet/ip_input.c 31 May 2003 04:27:04 -0000 @@ -395,6 +395,12 @@ goto bad; } +#ifdef ALTQ + if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0) + /* packet is dropped by traffic conditioner */ + return; +#endif + /* * Convert fields to host representation. */ Index: netinet/ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.189 diff -u -r1.189 ip_output.c --- netinet/ip_output.c 31 May 2003 17:55:21 -0000 1.189 +++ netinet/ip_output.c 1 Jun 2003 06:44:21 -0000 @@ -452,6 +452,12 @@ } } #endif /* notdef */ +#ifdef ALTQ + /* + * disable packet drop hack. + * packetdrop should be done by queueing. + */ +#else /* !ALTQ */ /* * Verify that we have any chance at all of being able to queue * the packet or packet fragments @@ -462,6 +468,7 @@ ipstat.ips_odropped++; goto bad; } +#endif /* !ALTQ */ /* * Look for broadcast address and Index: netinet6/ip6_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.47 diff -u -r1.47 ip6_input.c --- netinet6/ip6_input.c 12 Mar 2003 06:08:48 -0000 1.47 +++ netinet6/ip6_input.c 31 May 2003 04:27:04 -0000 @@ -378,6 +378,12 @@ return; } +#ifdef ALTQ + if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) { + /* packet is dropped by traffic conditioner */ + return; + } +#endif /* * Check against address spoofing/corruption. */ Index: pci/if_rl.c =================================================================== RCS file: /home/ncvs/src/sys/pci/if_rl.c,v retrieving revision 1.99 diff -u -r1.99 if_rl.c --- pci/if_rl.c 31 May 2003 20:01:14 -0000 1.99 +++ pci/if_rl.c 1 Jun 2003 06:44:23 -0000 @@ -1053,7 +1053,8 @@ ifp->if_watchdog = rl_watchdog; ifp->if_init = rl_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); callout_handle_init(&sc->rl_stat_ch); @@ -1469,7 +1470,7 @@ } - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) rl_start(ifp); #ifdef DEVICE_POLLING Index: pci/if_xl.c =================================================================== RCS file: /home/ncvs/src/sys/pci/if_xl.c,v retrieving revision 1.143 diff -u -r1.143 if_xl.c --- pci/if_xl.c 21 Apr 2003 18:34:04 -0000 1.143 +++ pci/if_xl.c 31 May 2003 04:27:04 -0000 @@ -928,6 +928,7 @@ { struct mbuf *m; struct ifnet *ifp; + int error; ifp = &sc->arpcom.ac_if; @@ -945,7 +946,7 @@ mtod(m, unsigned char *)[15] = 0; mtod(m, unsigned char *)[16] = 0xE3; m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3; - IF_ENQUEUE(&ifp->if_snd, m); + IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); xl_start(ifp); return; @@ -1579,7 +1580,8 @@ ifp->if_watchdog = xl_watchdog; ifp->if_init = xl_init; ifp->if_baudrate = 10000000; - ifp->if_snd.ifq_maxlen = XL_TX_LIST_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1); + IFQ_SET_READY(&ifp->if_snd); ifp->if_capenable = ifp->if_capabilities; /* @@ -2348,7 +2350,7 @@ } } - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); XL_UNLOCK(sc); @@ -2519,7 +2521,7 @@ start_tx = sc->xl_cdata.xl_tx_free; while(sc->xl_cdata.xl_tx_free != NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -2652,7 +2654,7 @@ break; } - IF_DEQUEUE(&ifp->if_snd, m_head); + IFQ_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -3134,7 +3136,7 @@ xl_reset(sc); xl_init(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); XL_UNLOCK(sc);