/* * priq_enqueue is an enqueue function to be registered to * (*altq_enqueue) in struct ifaltq. */ static int priq_enqueue(struct ifaltq_subque *ifsq, struct mbuf *m, struct altq_pktattr *pktattr) { struct ifaltq *ifq = ifsq->ifsq_altq; struct priq_if *pif = (struct priq_if *)ifq->altq_disc; struct priq_class *cl; int error; int len; if (ifsq_get_index(ifsq) != PRIQ_SUBQ_INDEX) { /* * Race happened, the unrelated subqueue was * picked during the packet scheduler transition. */ ifsq_classic_request(ifsq, ALTRQ_PURGE, NULL); m_freem(m); return ENOBUFS; } crit_enter(); /* grab class set by classifier */ if ((m->m_flags & M_PKTHDR) == 0) { /* should not happen */ if_printf(ifq->altq_ifp, "altq: packet does not have pkthdr\n"); m_freem(m); error = ENOBUFS; goto done; } if (m->m_pkthdr.fw_flags & PF_MBUF_STRUCTURE) cl = clh_to_clp(pif, m->m_pkthdr.pf.qid); else cl = NULL; if (cl == NULL) { cl = pif->pif_default; if (cl == NULL) { m_freem(m); error = ENOBUFS; goto done; } } cl->cl_pktattr = NULL; len = m_pktlen(m); if (priq_addq(cl, m) != 0) { /* drop occurred. mbuf was freed in priq_addq. */ PKTCNTR_ADD(&cl->cl_dropcnt, len); error = ENOBUFS; goto done; } ifsq->ifq_len++; error = 0; done: crit_exit(); return (error); }
/* * priq_enqueue is an enqueue function to be registered to * (*altq_enqueue) in struct ifaltq. */ static int priq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr) { struct priq_if *pif = (struct priq_if *)ifq->altq_disc; struct priq_class *cl; struct pf_mtag *t; int len; IFQ_LOCK_ASSERT(ifq); /* grab class set by classifier */ if ((m->m_flags & M_PKTHDR) == 0) { /* should not happen */ #if defined(__NetBSD__) || defined(__OpenBSD__)\ || (defined(__FreeBSD__) && __FreeBSD_version >= 501113) printf("altq: packet for %s does not have pkthdr\n", ifq->altq_ifp->if_xname); #else printf("altq: packet for %s%d does not have pkthdr\n", ifq->altq_ifp->if_name, ifq->altq_ifp->if_unit); #endif m_freem(m); return (ENOBUFS); } cl = NULL; if ((t = pf_find_mtag(m)) != NULL) cl = clh_to_clp(pif, t->qid); #ifdef ALTQ3_COMPAT else if ((ifq->altq_flags & ALTQF_CLASSIFY) && pktattr != NULL) cl = pktattr->pattr_class; #endif if (cl == NULL) { cl = pif->pif_default; if (cl == NULL) { m_freem(m); return (ENOBUFS); } } #ifdef ALTQ3_COMPAT if (pktattr != NULL) cl->cl_pktattr = pktattr; /* save proto hdr used by ECN */ else #endif cl->cl_pktattr = NULL; len = m_pktlen(m); if (priq_addq(cl, m) != 0) { /* drop occurred. mbuf was freed in priq_addq. */ PKTCNTR_ADD(&cl->cl_dropcnt, len); return (ENOBUFS); } IFQ_INC_LEN(ifq); /* successfully queued. */ return (0); }
/* * priq_enqueue is an enqueue function to be registered to * (*altq_enqueue) in struct ifaltq. */ static int priq_enqueue(struct ifaltq *ifq, struct mbuf *m, struct altq_pktattr *pktattr) { struct priq_if *pif = (struct priq_if *)ifq->altq_disc; struct priq_class *cl; struct m_tag *t; int len; /* grab class set by classifier */ if ((m->m_flags & M_PKTHDR) == 0) { /* should not happen */ printf("altq: packet for %s does not have pkthdr\n", ifq->altq_ifp->if_xname); m_freem(m); return (ENOBUFS); } cl = NULL; if ((t = m_tag_find(m, PACKET_TAG_ALTQ_QID, NULL)) != NULL) cl = clh_to_clp(pif, ((struct altq_tag *)(t+1))->qid); #ifdef ALTQ3_COMPAT else if ((ifq->altq_flags & ALTQF_CLASSIFY) && pktattr != NULL) cl = pktattr->pattr_class; #endif if (cl == NULL) { cl = pif->pif_default; if (cl == NULL) { m_freem(m); return (ENOBUFS); } } #ifdef ALTQ3_COMPAT if (pktattr != NULL) cl->cl_pktattr = pktattr; /* save proto hdr used by ECN */ else #endif cl->cl_pktattr = NULL; len = m_pktlen(m); if (priq_addq(cl, m) != 0) { /* drop occurred. mbuf was freed in priq_addq. */ PKTCNTR_ADD(&cl->cl_dropcnt, len); return (ENOBUFS); } IFQ_INC_LEN(ifq); /* successfully queued. */ return (0); }
int priq_enqueue(struct priq_if *pif, struct priq_class *cl, struct mbuf *m, struct pf_mtag *t) { struct ifclassq *ifq = pif->pif_ifq; u_int32_t pri; int len, ret; IFCQ_LOCK_ASSERT_HELD(ifq); VERIFY(cl == NULL || cl->cl_pif == pif); if (cl == NULL) { #if PF_ALTQ cl = priq_clh_to_clp(pif, t->pftag_qid); #else /* !PF_ALTQ */ cl = priq_clh_to_clp(pif, 0); #endif /* !PF_ALTQ */ if (cl == NULL) { cl = pif->pif_default; if (cl == NULL) { IFCQ_CONVERT_LOCK(ifq); m_freem(m); return (ENOBUFS); } } } pri = cl->cl_pri; VERIFY(pri < PRIQ_MAXPRI); len = m_pktlen(m); ret = priq_addq(cl, m, t); if (ret != 0) { if (ret == CLASSQEQ_SUCCESS_FC) { /* packet enqueued, return advisory feedback */ ret = EQFULL; } else { VERIFY(ret == CLASSQEQ_DROPPED || ret == CLASSQEQ_DROPPED_FC || ret == CLASSQEQ_DROPPED_SP); /* packet has been freed in priq_addq */ PKTCNTR_ADD(&cl->cl_dropcnt, 1, len); IFCQ_DROP_ADD(ifq, 1, len); switch (ret) { case CLASSQEQ_DROPPED: return (ENOBUFS); case CLASSQEQ_DROPPED_FC: return (EQFULL); case CLASSQEQ_DROPPED_SP: return (EQSUSPENDED); } /* NOT REACHED */ } } IFCQ_INC_LEN(ifq); IFCQ_INC_BYTES(ifq, len); /* class is now active; indicate it as such */ if (!pktsched_bit_tst(pri, &pif->pif_bitmap)) pktsched_bit_set(pri, &pif->pif_bitmap); /* successfully queued. */ return (ret); }