/*-1* Copyright (C) 2016 Centre for Advanced Internet Architectures,2* Swinburne University of Technology, Melbourne, Australia.3* Portions of this code were made possible in part by a gift from4* The Comcast Innovation Fund.5* Implemented by Rasool Al-Saadi <[email protected]>6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829/*30* API for writing an Active Queue Management algorithm for Dummynet31*/3233#ifndef _IP_DN_AQM_H34#define _IP_DN_AQM_H3536#include <sys/ck.h>3738/* NOW is the current time in millisecond*/39#define NOW ((V_dn_cfg.curr_time * tick) / 1000)4041#define AQM_UNOW (V_dn_cfg.curr_time * tick)42#define AQM_TIME_1US ((aqm_time_t)(1))43#define AQM_TIME_1MS ((aqm_time_t)(1000))44#define AQM_TIME_1S ((aqm_time_t)(AQM_TIME_1MS * 1000))4546/* aqm time allows to store up to 4294 seconds */47typedef uint32_t aqm_time_t;48typedef int32_t aqm_stime_t;4950#define DN_AQM_MTAG_TS 553455152/* Macro for variable bounding */53#define BOUND_VAR(x,l,h) ((x) > (h)? (h) : ((x) > (l)? (x) : (l)))5455/*56* Structure for holding data and function pointers that together represent a57* AQM algorithm.58*/59struct dn_aqm {60#define DN_AQM_NAME_MAX 5061char name[DN_AQM_NAME_MAX]; /* name of AQM algorithm */62uint32_t type; /* AQM type number */6364/* Methods implemented by AQM algorithm:65*66* enqueue enqueue packet 'm' on queue 'q'.67* Return 0 on success, 1 on drop.68*69* dequeue dequeue a packet from queue 'q'.70* Return a packet, NULL if no packet available.71*72* config configure AQM algorithm73* If required, this function should allocate space to store74* the configurations and set 'fs->aqmcfg' to point to this space.75* 'dn_extra_parms' includes array of parameters send76* from ipfw userland command.77* Return 0 on success, non-zero otherwise.78*79* deconfig deconfigure AQM algorithm.80* The allocated configuration memory space should be freed here.81* Return 0 on success, non-zero otherwise.82*83* init initialise AQM status variables of queue 'q'84* This function is used to allocate space and init AQM status for a85* queue and q->aqm_status to point to this space.86* Return 0 on success, non-zero otherwise.87*88* cleanup cleanup AQM status variables of queue 'q'89* The allocated memory space for AQM status should be freed here.90* Return 0 on success, non-zero otherwise.91*92* getconfig retrieve AQM configurations93* This function is used to return AQM parameters to userland94* command. The function should fill 'dn_extra_parms' struct with95* the AQM configurations using 'par' array.96*97*/9899int (*enqueue)(struct dn_queue *, struct mbuf *);100struct mbuf * (*dequeue)(struct dn_queue *);101int (*config)(struct dn_fsk *, struct dn_extra_parms *ep, int);102int (*deconfig)(struct dn_fsk *);103int (*init)(struct dn_queue *);104int (*cleanup)(struct dn_queue *);105int (*getconfig)(struct dn_fsk *, struct dn_extra_parms *);106107int ref_count; /*Number of queues instances in the system */108int cfg_ref_count; /*Number of AQM instances in the system */109CK_LIST_ENTRY(dn_aqm) next; /* Next AQM in the list */110};111112/* Helper function to update queue and scheduler statistics.113* negative len + drop -> drop114* negative len -> dequeue115* positive len -> enqueue116* positive len + drop -> drop during enqueue117*/118__inline static void119update_stats(struct dn_queue *q, int len, int drop)120{121int inc = 0;122struct dn_flow *sni;123struct dn_flow *qni;124125sni = &q->_si->ni;126qni = &q->ni;127128if (len < 0)129inc = -1;130else if(len > 0)131inc = 1;132133if (drop) {134qni->drops++;135sni->drops++;136V_dn_cfg.io_pkt_drop++;137} else {138/*update queue stats */139qni->length += inc;140qni->len_bytes += len;141142/*update scheduler instance stats */143sni->length += inc;144sni->len_bytes += len;145}146/* tot_pkts is updated in dn_enqueue function */147}148149/* kernel module related function */150int151dn_aqm_modevent(module_t mod, int cmd, void *arg);152153#define DECLARE_DNAQM_MODULE(name, dnaqm) \154static moduledata_t name##_mod = { \155#name, dn_aqm_modevent, dnaqm \156}; \157DECLARE_MODULE(name, name##_mod, \158SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \159MODULE_DEPEND(name, dummynet, 3, 3, 3)160161#endif162163164