#ifndef __NET_SCHED_CODEL_H1#define __NET_SCHED_CODEL_H23/*4* Codel - The Controlled-Delay Active Queue Management algorithm5*6* Copyright (C) 2011-2012 Kathleen Nichols <[email protected]>7* Copyright (C) 2011-2012 Van Jacobson <[email protected]>8* Copyright (C) 2012 Michael D. Taht <[email protected]>9* Copyright (C) 2012,2015 Eric Dumazet <[email protected]>10*11* Redistribution and use in source and binary forms, with or without12* modification, are permitted provided that the following conditions13* are met:14* 1. Redistributions of source code must retain the above copyright15* notice, this list of conditions, and the following disclaimer,16* without modification.17* 2. Redistributions in binary form must reproduce the above copyright18* notice, this list of conditions and the following disclaimer in the19* documentation and/or other materials provided with the distribution.20* 3. The names of the authors may not be used to endorse or promote products21* derived from this software without specific prior written permission.22*23* Alternatively, provided that this notice is retained in full, this24* software may be distributed under the terms of the GNU General25* Public License ("GPL") version 2, in which case the provisions of the26* GPL apply INSTEAD OF those given above.27*28* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS29* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT30* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR31* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT32* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,33* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT34* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,35* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY36* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT37* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE38* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH39* DAMAGE.40*41*/4243#include <linux/types.h>44#include <linux/ktime.h>45#include <linux/skbuff.h>4647/* Controlling Queue Delay (CoDel) algorithm48* =========================================49* Source : Kathleen Nichols and Van Jacobson50* http://queue.acm.org/detail.cfm?id=220933651*52* Implemented on linux by Dave Taht and Eric Dumazet53*/545556/* CoDel uses a 1024 nsec clock, encoded in u3257* This gives a range of 2199 seconds, because of signed compares58*/59typedef u32 codel_time_t;60typedef s32 codel_tdiff_t;61#define CODEL_SHIFT 1062#define MS2TIME(a) ((a * NSEC_PER_MSEC) >> CODEL_SHIFT)6364static inline codel_time_t codel_get_time(void)65{66u64 ns = ktime_get_ns();6768return ns >> CODEL_SHIFT;69}7071/* Dealing with timer wrapping, according to RFC 1982, as desc in wikipedia:72* https://en.wikipedia.org/wiki/Serial_number_arithmetic#General_Solution73* codel_time_after(a,b) returns true if the time a is after time b.74*/75#define codel_time_after(a, b) \76(typecheck(codel_time_t, a) && \77typecheck(codel_time_t, b) && \78((s32)((a) - (b)) > 0))79#define codel_time_before(a, b) codel_time_after(b, a)8081#define codel_time_after_eq(a, b) \82(typecheck(codel_time_t, a) && \83typecheck(codel_time_t, b) && \84((s32)((a) - (b)) >= 0))85#define codel_time_before_eq(a, b) codel_time_after_eq(b, a)8687static inline u32 codel_time_to_us(codel_time_t val)88{89u64 valns = ((u64)val << CODEL_SHIFT);9091do_div(valns, NSEC_PER_USEC);92return (u32)valns;93}9495/**96* struct codel_params - contains codel parameters97* @target: target queue size (in time units)98* @ce_threshold: threshold for marking packets with ECN CE99* @interval: width of moving time window100* @mtu: device mtu, or minimal queue backlog in bytes.101* @ecn: is Explicit Congestion Notification enabled102* @ce_threshold_selector: apply ce_threshold to packets matching this value103* in the diffserv/ECN byte of the IP header104* @ce_threshold_mask: mask to apply to ce_threshold_selector comparison105*/106struct codel_params {107codel_time_t target;108codel_time_t ce_threshold;109codel_time_t interval;110u32 mtu;111bool ecn;112u8 ce_threshold_selector;113u8 ce_threshold_mask;114};115116/**117* struct codel_vars - contains codel variables118* @count: how many drops we've done since the last time we119* entered dropping state120* @lastcount: count at entry to dropping state121* @dropping: set to true if in dropping state122* @rec_inv_sqrt: reciprocal value of sqrt(count) >> 1123* @first_above_time: when we went (or will go) continuously above target124* for interval125* @drop_next: time to drop next packet, or when we dropped last126* @ldelay: sojourn time of last dequeued packet127*/128struct codel_vars {129u32 count;130u32 lastcount;131bool dropping;132u16 rec_inv_sqrt;133codel_time_t first_above_time;134codel_time_t drop_next;135codel_time_t ldelay;136};137138#define REC_INV_SQRT_BITS (8 * sizeof(u16)) /* or sizeof_in_bits(rec_inv_sqrt) */139/* needed shift to get a Q0.32 number from rec_inv_sqrt */140#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS)141142/**143* struct codel_stats - contains codel shared variables and stats144* @maxpacket: largest packet we've seen so far145* @drop_count: temp count of dropped packets in dequeue()146* @drop_len: bytes of dropped packets in dequeue()147* @ecn_mark: number of packets we ECN marked instead of dropping148* @ce_mark: number of packets CE marked because sojourn time was above ce_threshold149*/150struct codel_stats {151u32 maxpacket;152u32 drop_count;153u32 drop_len;154u32 ecn_mark;155u32 ce_mark;156};157158#define CODEL_DISABLED_THRESHOLD INT_MAX159160typedef u32 (*codel_skb_len_t)(const struct sk_buff *skb);161typedef codel_time_t (*codel_skb_time_t)(const struct sk_buff *skb);162typedef void (*codel_skb_drop_t)(struct sk_buff *skb, void *ctx);163typedef struct sk_buff * (*codel_skb_dequeue_t)(struct codel_vars *vars,164void *ctx);165166#endif167168169