#ifndef _NET_ALTQ_IF_ALTQ_H_
#define _NET_ALTQ_IF_ALTQ_H_
#include <sys/mbuf.h>
#include <sys/serialize.h>
#include <net/altq/if_classq.h>
#define ALTQ_SUBQ_INDEX_DEFAULT 0
struct mbuf;
struct altq_pktattr;
struct ifaltq_subque;
struct ifaltq;
typedef int (*altq_mapsubq_t)(struct ifaltq *, int);
typedef int (*ifsq_enqueue_t)(struct ifaltq_subque *, struct mbuf *,
struct altq_pktattr *);
typedef struct mbuf *(*ifsq_dequeue_t)(struct ifaltq_subque *, int);
typedef int (*ifsq_request_t)(struct ifaltq_subque *, int, void *);
struct ifsubq_stage {
struct ifaltq_subque *stg_subq;
int stg_cnt;
int stg_len;
uint32_t stg_flags;
TAILQ_ENTRY(ifsubq_stage) stg_link;
} __cachealign;
#define IFSQ_STAGE_FLAG_QUED 0x1
#define IFSQ_STAGE_FLAG_SCHED 0x2
struct ifaltq_subque {
struct lwkt_serialize ifsq_lock;
int ifsq_index;
struct ifaltq *ifsq_altq;
struct ifnet *ifsq_ifp;
void *ifsq_hw_priv;
struct if_classq ifsq_norm;
struct if_classq ifsq_prio;
int ifsq_prio_len;
int ifsq_prio_bcnt;
int ifsq_len;
int ifsq_maxlen;
int ifsq_bcnt;
int ifsq_maxbcnt;
ifsq_enqueue_t ifsq_enqueue;
ifsq_dequeue_t ifsq_dequeue;
ifsq_request_t ifsq_request;
struct lwkt_serialize *ifsq_hw_serialize;
struct mbuf *ifsq_prepended;
int ifsq_started;
int ifsq_hw_oactive;
int ifsq_cpuid;
struct ifsubq_stage *ifsq_stage;
struct netmsg_base *ifsq_ifstart_nmsg;
} __cachealign;
#ifdef _KERNEL
#define ALTQ_SQ_ASSERT_LOCKED(ifsq) ASSERT_SERIALIZED(&(ifsq)->ifsq_lock)
#define ALTQ_SQ_LOCK_INIT(ifsq) lwkt_serialize_init(&(ifsq)->ifsq_lock)
#define ALTQ_SQ_LOCK(ifsq) \
lwkt_serialize_adaptive_enter(&(ifsq)->ifsq_lock)
#define ALTQ_SQ_UNLOCK(ifsq) lwkt_serialize_exit(&(ifsq)->ifsq_lock)
#define ASSERT_ALTQ_SQ_SERIALIZED_HW(ifsq) \
ASSERT_SERIALIZED((ifsq)->ifsq_hw_serialize)
#define ASSERT_ALTQ_SQ_NOT_SERIALIZED_HW(ifsq) \
ASSERT_NOT_SERIALIZED((ifsq)->ifsq_hw_serialize)
#define ALTQ_SQ_PKTCNT_INC(ifsq) \
do { \
(ifsq)->ifsq_len++; \
} while (0)
#define ALTQ_SQ_PKTCNT_DEC(ifsq) \
do { \
KASSERT((ifsq)->ifsq_len > 0, ("invalid packet count")); \
(ifsq)->ifsq_len--; \
} while (0)
#define ALTQ_SQ_CNTR_INC(ifsq, bcnt) \
do { \
ALTQ_SQ_PKTCNT_INC((ifsq)); \
(ifsq)->ifsq_bcnt += (bcnt); \
} while (0)
#define ALTQ_SQ_CNTR_DEC(ifsq, bcnt) \
do { \
ALTQ_SQ_PKTCNT_DEC((ifsq)); \
KASSERT((ifsq)->ifsq_bcnt >= (bcnt), ("invalid byte count")); \
(ifsq)->ifsq_bcnt -= (bcnt); \
} while (0)
#define ALTQ_SQ_CNTR_RESET(ifsq) \
do { \
(ifsq)->ifsq_len = 0; \
(ifsq)->ifsq_bcnt = 0; \
} while (0)
#define ALTQ_SQ_PRIO_CNTR_INC(ifsq, bcnt) \
do { \
(ifsq)->ifsq_prio_len++; \
(ifsq)->ifsq_prio_bcnt += (bcnt); \
} while (0)
#define ALTQ_SQ_PRIO_CNTR_DEC(ifsq, bcnt) \
do { \
KASSERT((ifsq)->ifsq_prio_len > 0, \
("invalid prio packet count")); \
(ifsq)->ifsq_prio_len--; \
KASSERT((ifsq)->ifsq_prio_bcnt >= (bcnt), \
("invalid prio byte count")); \
(ifsq)->ifsq_prio_bcnt -= (bcnt); \
} while (0)
#endif
struct ifaltq {
int altq_type;
int altq_flags;
void *altq_disc;
struct ifnet *altq_ifp;
void *altq_clfier;
void *(*altq_classify)(struct ifaltq *, struct mbuf *,
struct altq_pktattr *);
struct tb_regulator *altq_tbr;
altq_mapsubq_t altq_mapsubq;
uint32_t altq_subq_mappriv;
int altq_subq_cnt;
struct ifaltq_subque *altq_subq;
int altq_maxlen;
};
#ifdef _KERNEL
#define ALTQ_LOCK(ifq) \
ALTQ_SQ_LOCK(&(ifq)->altq_subq[ALTQ_SUBQ_INDEX_DEFAULT])
#define ALTQ_UNLOCK(ifq) \
ALTQ_SQ_UNLOCK(&(ifq)->altq_subq[ALTQ_SUBQ_INDEX_DEFAULT])
#endif
#ifdef _KERNEL
struct altq_pktattr {
void *pattr_class;
int pattr_af;
caddr_t pattr_hdr;
};
struct tb_regulator {
int64_t tbr_rate;
int64_t tbr_depth;
int64_t tbr_token;
int64_t tbr_filluptime;
uint64_t tbr_last;
int tbr_lastop;
};
#define ALTQF_READY 0x01
#define ALTQF_ENABLED 0x02
#define ALTQF_CLASSIFY 0x04
#define ALTQF_DRIVER1 0x40
#define ALTQF_CANTCHANGE (ALTQF_READY)
#define ALTDQ_REMOVE 1
#define ALTDQ_POLL 2
#define ALTRQ_PURGE 1
int altq_attach(struct ifaltq *, int, void *, altq_mapsubq_t,
ifsq_enqueue_t, ifsq_dequeue_t, ifsq_request_t, void *,
void *(*)(struct ifaltq *, struct mbuf *, struct altq_pktattr *));
int altq_detach(struct ifaltq *);
int altq_enable(struct ifaltq *);
int altq_disable(struct ifaltq *);
struct mbuf *tbr_dequeue(struct ifaltq_subque *, int);
extern int (*altq_input)(struct mbuf *, int);
#endif
#endif