fve
TAILQ_ENTRY(fve) fve_lru; /* for LRU list */
TAILQ_HEAD(fv_flowhead, fve) fv_flowlist; /* LRU list */
struct fve *fv_fves; /* pointer to the allocated fves */
static inline struct fve *
struct fve *fve;
TAILQ_FOREACH(fve, &fv->fv_flowlist, fve_lru){
if (fve->fve_lastdrop.tv_sec == 0)
if (fve->fve_lastdrop.tv_sec < tthresh.tv_sec) {
fve->fve_lastdrop.tv_sec = 0;
if (fve->fve_flow.flow_af == AF_INET &&
fve->fve_flow.flow_ip.ip_src.s_addr ==
fve->fve_flow.flow_ip.ip_dst.s_addr ==
return fve;
TAILQ_FOREACH(fve, &fv->fv_flowlist, fve_lru){
if (fve->fve_lastdrop.tv_sec == 0)
if (fve->fve_lastdrop.tv_sec < tthresh.tv_sec) {
fve->fve_lastdrop.tv_sec = 0;
if (fve->fve_flow.flow_af == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&fve->fve_flow.flow_ip6.ip6_src,
IN6_ARE_ADDR_EQUAL(&fve->fve_flow.flow_ip6.ip6_dst,
return fve;
static inline struct fve *
struct fve *fve;
fve = TAILQ_LAST(&fv->fv_flowlist, fv_flowhead);
fve->fve_flow.flow_af = AF_INET;
fve->fve_flow.flow_ip.ip_src = ip->ip_src;
fve->fve_flow.flow_ip.ip_dst = ip->ip_dst;
fve->fve_flow.flow_af = AF_INET6;
fve->fve_flow.flow_ip6.ip6_src = ip6->ip6_src;
fve->fve_flow.flow_ip6.ip6_dst = ip6->ip6_dst;
fve->fve_state = Green;
fve->fve_p = 0.0;
fve->fve_f = 0.0;
fve->fve_ifseq = fv->fv_ifseq - 1;
fve->fve_count = 0;
return fve;
flowlist_move_to_head(struct flowvalve *fv, struct fve *fve)
if (TAILQ_FIRST(&fv->fv_flowlist) != fve) {
TAILQ_REMOVE(&fv->fv_flowlist, fve, fve_lru);
TAILQ_INSERT_HEAD(&fv->fv_flowlist, fve, fve_lru);
struct fve *fve;
fv->fv_fves = malloc(sizeof(struct fve) * num, M_DEVBUF,
fve = &fv->fv_fves[i];
fve->fve_lastdrop.tv_sec = 0;
TAILQ_INSERT_TAIL(&fv->fv_flowlist, fve, fve_lru);
struct fve **fcache)
struct fve *fve;
if ((fve = flowlist_lookup(fv, pktattr, &now)) == NULL)
*fcache = fve;
if (++fve->fve_count == FV_N) {
fve->fve_f =
(FV_N << FP_SHIFT) / (fv->fv_ifseq - fve->fve_ifseq)
+ fve->fve_f - FV_FUNSCALE(fve->fve_f);
fve->fve_ifseq = fv->fv_ifseq;
fve->fve_count = 0;
if (fve->fve_state == Green && fve->fve_p > fv->fv_pthresh) {
fthresh = fv_p2f(fv, fve->fve_p);
if (fve->fve_f > fthresh)
fve->fve_state = Red;
if (fve->fve_state == Red) {
if (now.tv_sec - fve->fve_lastdrop.tv_sec > FV_BACKOFFTHRESH) {
fve->fve_p = 0;
fve->fve_state = Green;
flowlist_move_to_head(fv, fve);
fve->fve_lastdrop = now;
fve->fve_p -= FV_PUNSCALE(fve->fve_p);
if (fve->fve_p < 0)
fve->fve_p = 0;
struct fve *fcache)
struct fve *fve;
fve = fcache;
else if ((fve = flowlist_lookup(fv, pktattr, &now)) == NULL)
fve = flowlist_reclaim(fv, pktattr);
flowlist_move_to_head(fv, fve);
fve->fve_p = (1 << FP_SHIFT) + fve->fve_p;
fve->fve_lastdrop = now;
static inline struct fve *flowlist_lookup(struct flowvalve *,
static inline struct fve *flowlist_reclaim(struct flowvalve *,
static inline void flowlist_move_to_head(struct flowvalve *, struct fve *);
struct fve **);
struct fve *);
struct fve *fve = NULL;
if (fv_checkflow(rp->red_flowvalve, pktattr, &fve)) {
fv_dropbyred(rp->red_flowvalve, pktattr, fve);