14644fda3SGleb Smirnoff /*- 24644fda3SGleb Smirnoff * Copyright (c) 2007-2008 34644fda3SGleb Smirnoff * Swinburne University of Technology, Melbourne, Australia. 44644fda3SGleb Smirnoff * Copyright (c) 2009-2010 Lawrence Stewart <lstewart@freebsd.org> 54644fda3SGleb Smirnoff * Copyright (c) 2010 The FreeBSD Foundation 64644fda3SGleb Smirnoff * All rights reserved. 74644fda3SGleb Smirnoff * 84644fda3SGleb Smirnoff * This software was developed at the Centre for Advanced Internet 94644fda3SGleb Smirnoff * Architectures, Swinburne University of Technology, by Lawrence Stewart and 104644fda3SGleb Smirnoff * James Healy, made possible in part by a grant from the Cisco University 114644fda3SGleb Smirnoff * Research Program Fund at Community Foundation Silicon Valley. 124644fda3SGleb Smirnoff * 134644fda3SGleb Smirnoff * Portions of this software were developed at the Centre for Advanced 144644fda3SGleb Smirnoff * Internet Architectures, Swinburne University of Technology, Melbourne, 154644fda3SGleb Smirnoff * Australia by David Hayes under sponsorship from the FreeBSD Foundation. 164644fda3SGleb Smirnoff * 174644fda3SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 184644fda3SGleb Smirnoff * modification, are permitted provided that the following conditions 194644fda3SGleb Smirnoff * are met: 204644fda3SGleb Smirnoff * 1. Redistributions of source code must retain the above copyright 214644fda3SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 224644fda3SGleb Smirnoff * 2. Redistributions in binary form must reproduce the above copyright 234644fda3SGleb Smirnoff * notice, this list of conditions and the following disclaimer in the 244644fda3SGleb Smirnoff * documentation and/or other materials provided with the distribution. 254644fda3SGleb Smirnoff * 264644fda3SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 274644fda3SGleb Smirnoff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 284644fda3SGleb Smirnoff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 294644fda3SGleb Smirnoff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 304644fda3SGleb Smirnoff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 314644fda3SGleb Smirnoff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 324644fda3SGleb Smirnoff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 334644fda3SGleb Smirnoff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 344644fda3SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 354644fda3SGleb Smirnoff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 364644fda3SGleb Smirnoff * SUCH DAMAGE. 374644fda3SGleb Smirnoff */ 384644fda3SGleb Smirnoff 394644fda3SGleb Smirnoff /* 404644fda3SGleb Smirnoff * This software was first released in 2007 by James Healy and Lawrence Stewart 414644fda3SGleb Smirnoff * whilst working on the NewTCP research project at Swinburne University of 424644fda3SGleb Smirnoff * Technology's Centre for Advanced Internet Architectures, Melbourne, 434644fda3SGleb Smirnoff * Australia, which was made possible in part by a grant from the Cisco 444644fda3SGleb Smirnoff * University Research Program Fund at Community Foundation Silicon Valley. 454644fda3SGleb Smirnoff * More details are available at: 464644fda3SGleb Smirnoff * http://caia.swin.edu.au/urp/newtcp/ 474644fda3SGleb Smirnoff */ 484644fda3SGleb Smirnoff 494644fda3SGleb Smirnoff #ifndef _NETINET_CC_CC_H_ 504644fda3SGleb Smirnoff #define _NETINET_CC_CC_H_ 514644fda3SGleb Smirnoff 52adc56f5aSEdward Tomasz Napierala #ifdef _KERNEL 534644fda3SGleb Smirnoff 54b8d60729SRandall Stewart MALLOC_DECLARE(M_CC_MEM); 55b8d60729SRandall Stewart 564644fda3SGleb Smirnoff /* Global CC vars. */ 574644fda3SGleb Smirnoff extern STAILQ_HEAD(cc_head, cc_algo) cc_list; 584644fda3SGleb Smirnoff extern const int tcprexmtthresh; 594644fda3SGleb Smirnoff 604644fda3SGleb Smirnoff /* Per-netstack bits. */ 614644fda3SGleb Smirnoff VNET_DECLARE(struct cc_algo *, default_cc_ptr); 624644fda3SGleb Smirnoff #define V_default_cc_ptr VNET(default_cc_ptr) 634644fda3SGleb Smirnoff 64370efe5aSLawrence Stewart VNET_DECLARE(int, cc_do_abe); 65370efe5aSLawrence Stewart #define V_cc_do_abe VNET(cc_do_abe) 66370efe5aSLawrence Stewart 67370efe5aSLawrence Stewart VNET_DECLARE(int, cc_abe_frlossreduce); 68370efe5aSLawrence Stewart #define V_cc_abe_frlossreduce VNET(cc_abe_frlossreduce) 69370efe5aSLawrence Stewart 704644fda3SGleb Smirnoff /* Define the new net.inet.tcp.cc sysctl tree. */ 71e68b3792SGleb Smirnoff #ifdef _SYS_SYSCTL_H_ 724644fda3SGleb Smirnoff SYSCTL_DECL(_net_inet_tcp_cc); 73e68b3792SGleb Smirnoff #endif 744644fda3SGleb Smirnoff 75a9696510SRandall Stewart /* For CC modules that use hystart++ */ 76a9696510SRandall Stewart extern uint32_t hystart_lowcwnd; 77a9696510SRandall Stewart extern uint32_t hystart_minrtt_thresh; 78a9696510SRandall Stewart extern uint32_t hystart_maxrtt_thresh; 79a9696510SRandall Stewart extern uint32_t hystart_n_rttsamples; 80a9696510SRandall Stewart extern uint32_t hystart_css_growth_div; 81a9696510SRandall Stewart extern uint32_t hystart_css_rounds; 82a9696510SRandall Stewart extern uint32_t hystart_bblogs; 83a9696510SRandall Stewart 844644fda3SGleb Smirnoff /* CC housekeeping functions. */ 854644fda3SGleb Smirnoff int cc_register_algo(struct cc_algo *add_cc); 864644fda3SGleb Smirnoff int cc_deregister_algo(struct cc_algo *remove_cc); 87e68b3792SGleb Smirnoff #endif /* _KERNEL */ 884644fda3SGleb Smirnoff 89e68b3792SGleb Smirnoff #if defined(_KERNEL) || defined(_WANT_TCPCB) 904644fda3SGleb Smirnoff /* 914644fda3SGleb Smirnoff * Wrapper around transport structs that contain same-named congestion 924644fda3SGleb Smirnoff * control variables. Allows algos to be shared amongst multiple CC aware 934644fda3SGleb Smirnoff * transprots. 944644fda3SGleb Smirnoff */ 954644fda3SGleb Smirnoff struct cc_var { 964644fda3SGleb Smirnoff void *cc_data; /* Per-connection private CC algorithm data. */ 974644fda3SGleb Smirnoff int bytes_this_ack; /* # bytes acked by the current ACK. */ 984644fda3SGleb Smirnoff tcp_seq curack; /* Most recent ACK. */ 994644fda3SGleb Smirnoff uint32_t flags; /* Flags for cc_var (see below) */ 1004644fda3SGleb Smirnoff int type; /* Indicates which ptr is valid in ccvc. */ 1014644fda3SGleb Smirnoff union ccv_container { 1024644fda3SGleb Smirnoff struct tcpcb *tcp; 1034644fda3SGleb Smirnoff struct sctp_nets *sctp; 1044644fda3SGleb Smirnoff } ccvc; 1054b7b743cSLawrence Stewart uint16_t nsegs; /* # segments coalesced into current chain. */ 1065d8fd932SRandall Stewart uint8_t labc; /* Dont use system abc use passed in */ 1074644fda3SGleb Smirnoff }; 1084644fda3SGleb Smirnoff 1094644fda3SGleb Smirnoff /* cc_var flags. */ 1104644fda3SGleb Smirnoff #define CCF_ABC_SENTAWND 0x0001 /* ABC counted cwnd worth of bytes? */ 1114644fda3SGleb Smirnoff #define CCF_CWND_LIMITED 0x0002 /* Are we currently cwnd limited? */ 1125d8fd932SRandall Stewart #define CCF_USE_LOCAL_ABC 0x0004 /* Dont use the system l_abc val */ 1134644fda3SGleb Smirnoff #define CCF_ACKNOW 0x0008 /* Will this ack be sent now? */ 1144644fda3SGleb Smirnoff #define CCF_IPHDR_CE 0x0010 /* Does this packet set CE bit? */ 1154644fda3SGleb Smirnoff #define CCF_TCPHDR_CWR 0x0020 /* Does this packet set CWR bit? */ 1165d8fd932SRandall Stewart #define CCF_MAX_CWND 0x0040 /* Have we reached maximum cwnd? */ 117ea6d0de2SRichard Scheffenegger #define CCF_CHG_MAX_CWND 0x0080 /* CUBIC max_cwnd changed, for K */ 1185d8fd932SRandall Stewart #define CCF_USR_IWND 0x0100 /* User specified initial window */ 1195d8fd932SRandall Stewart #define CCF_USR_IWND_INIT_NSEG 0x0200 /* Convert segs to bytes on conn init */ 120a9696510SRandall Stewart #define CCF_HYSTART_ALLOWED 0x0400 /* If the CC supports it Hystart is allowed */ 121a9696510SRandall Stewart #define CCF_HYSTART_CAN_SH_CWND 0x0800 /* Can hystart when going CSS -> CA slam the cwnd */ 122a9696510SRandall Stewart #define CCF_HYSTART_CONS_SSTH 0x1000 /* Should hystart use the more conservative ssthresh */ 1234644fda3SGleb Smirnoff 124*f74352fbSRichard Scheffenegger typedef enum { 1254644fda3SGleb Smirnoff /* ACK types passed to the ack_received() hook. */ 126*f74352fbSRichard Scheffenegger CC_ACK = 0x0001, /* Regular in sequence ACK. */ 127*f74352fbSRichard Scheffenegger CC_DUPACK = 0x0002, /* Duplicate ACK. */ 128*f74352fbSRichard Scheffenegger CC_PARTIALACK = 0x0004, /* Not yet. */ 129*f74352fbSRichard Scheffenegger CC_SACK = 0x0008, /* Not yet. */ 130*f74352fbSRichard Scheffenegger /* Congestion signal types passed to the cong_signal() hook. */ 131*f74352fbSRichard Scheffenegger CC_ECN = 0x0100, /* ECN marked packet received. */ 132*f74352fbSRichard Scheffenegger CC_RTO = 0x0200, /* RTO fired. */ 133*f74352fbSRichard Scheffenegger CC_RTO_ERR = 0x0400, /* RTO fired in error. */ 134*f74352fbSRichard Scheffenegger CC_NDUPACK = 0x0800, /* Threshold of dupack's reached. */ 1354644fda3SGleb Smirnoff /* 136*f74352fbSRichard Scheffenegger * The highest order 8 bits (0x01000000 - 0x80000000) are reserved 137*f74352fbSRichard Scheffenegger * for CC algos to declare their own congestion signal types. 1384644fda3SGleb Smirnoff */ 139*f74352fbSRichard Scheffenegger CC_SIGPRIVMASK = 0xFF000000 /* Mask to check if sig is private. */ 140*f74352fbSRichard Scheffenegger } ccsignal_t; 141*f74352fbSRichard Scheffenegger #endif /* defined(_KERNEL) || defined(_WANT_TCPCB) */ 1424644fda3SGleb Smirnoff 143adc56f5aSEdward Tomasz Napierala #ifdef _KERNEL 1444644fda3SGleb Smirnoff /* 1454644fda3SGleb Smirnoff * Structure to hold data and function pointers that together represent a 1464644fda3SGleb Smirnoff * congestion control algorithm. 1474644fda3SGleb Smirnoff */ 1484644fda3SGleb Smirnoff struct cc_algo { 1494644fda3SGleb Smirnoff char name[TCP_CA_NAME_MAX]; 1504644fda3SGleb Smirnoff 1514644fda3SGleb Smirnoff /* Init global module state on kldload. */ 1524644fda3SGleb Smirnoff int (*mod_init)(void); 1534644fda3SGleb Smirnoff 1544644fda3SGleb Smirnoff /* Cleanup global module state on kldunload. */ 1554644fda3SGleb Smirnoff int (*mod_destroy)(void); 1564644fda3SGleb Smirnoff 157b8d60729SRandall Stewart /* Return the size of the void pointer the CC needs for state */ 158b8d60729SRandall Stewart size_t (*cc_data_sz)(void); 159b8d60729SRandall Stewart 160b8d60729SRandall Stewart /* 161b8d60729SRandall Stewart * Init CC state for a new control block. The CC 162b8d60729SRandall Stewart * module may be passed a NULL ptr indicating that 163b8d60729SRandall Stewart * it must allocate the memory. If it is passed a 164b8d60729SRandall Stewart * non-null pointer it is pre-allocated memory by 165b8d60729SRandall Stewart * the caller and the cb_init is expected to use that memory. 166b8d60729SRandall Stewart * It is not expected to fail if memory is passed in and 167b8d60729SRandall Stewart * all currently defined modules do not. 168b8d60729SRandall Stewart */ 169b8d60729SRandall Stewart int (*cb_init)(struct cc_var *ccv, void *ptr); 1704644fda3SGleb Smirnoff 1714644fda3SGleb Smirnoff /* Cleanup CC state for a terminating control block. */ 1724644fda3SGleb Smirnoff void (*cb_destroy)(struct cc_var *ccv); 1734644fda3SGleb Smirnoff 1744644fda3SGleb Smirnoff /* Init variables for a newly established connection. */ 1754644fda3SGleb Smirnoff void (*conn_init)(struct cc_var *ccv); 1764644fda3SGleb Smirnoff 1774644fda3SGleb Smirnoff /* Called on receipt of an ack. */ 178*f74352fbSRichard Scheffenegger void (*ack_received)(struct cc_var *ccv, ccsignal_t type); 1794644fda3SGleb Smirnoff 1804644fda3SGleb Smirnoff /* Called on detection of a congestion signal. */ 181*f74352fbSRichard Scheffenegger void (*cong_signal)(struct cc_var *ccv, ccsignal_t type); 1824644fda3SGleb Smirnoff 1834644fda3SGleb Smirnoff /* Called after exiting congestion recovery. */ 1844644fda3SGleb Smirnoff void (*post_recovery)(struct cc_var *ccv); 1854644fda3SGleb Smirnoff 1864644fda3SGleb Smirnoff /* Called when data transfer resumes after an idle period. */ 1874644fda3SGleb Smirnoff void (*after_idle)(struct cc_var *ccv); 1884644fda3SGleb Smirnoff 1894644fda3SGleb Smirnoff /* Called for an additional ECN processing apart from RFC3168. */ 1904644fda3SGleb Smirnoff void (*ecnpkt_handler)(struct cc_var *ccv); 1914644fda3SGleb Smirnoff 1924e4c84f8SRandall Stewart /* Called when a new "round" begins, if the transport is tracking rounds. */ 1934e4c84f8SRandall Stewart void (*newround)(struct cc_var *ccv, uint32_t round_cnt); 1944e4c84f8SRandall Stewart 1954e4c84f8SRandall Stewart /* 1964e4c84f8SRandall Stewart * Called when a RTT sample is made (fas = flight at send, if you dont have it 1974e4c84f8SRandall Stewart * send the cwnd in). 1984e4c84f8SRandall Stewart */ 1994e4c84f8SRandall Stewart void (*rttsample)(struct cc_var *ccv, uint32_t usec_rtt, uint32_t rxtcnt, uint32_t fas); 2004e4c84f8SRandall Stewart 2014644fda3SGleb Smirnoff /* Called for {get|set}sockopt() on a TCP socket with TCP_CCALGOOPT. */ 2024644fda3SGleb Smirnoff int (*ctl_output)(struct cc_var *, struct sockopt *, void *); 2034644fda3SGleb Smirnoff 2044644fda3SGleb Smirnoff STAILQ_ENTRY (cc_algo) entries; 205ea9017fbSRandall Stewart u_int cc_refcount; 206b8d60729SRandall Stewart uint8_t flags; 2074644fda3SGleb Smirnoff }; 2084644fda3SGleb Smirnoff 209b8d60729SRandall Stewart #define CC_MODULE_BEING_REMOVED 0x01 /* The module is being removed */ 210b8d60729SRandall Stewart 2114644fda3SGleb Smirnoff /* Macro to obtain the CC algo's struct ptr. */ 212e68b3792SGleb Smirnoff #define CC_ALGO(tp) ((tp)->t_cc) 2134644fda3SGleb Smirnoff 2144644fda3SGleb Smirnoff /* Macro to obtain the CC algo's data ptr. */ 215e68b3792SGleb Smirnoff #define CC_DATA(tp) ((tp)->t_ccv.cc_data) 2164644fda3SGleb Smirnoff 2174644fda3SGleb Smirnoff /* Macro to obtain the system default CC algo's struct ptr. */ 218b8d60729SRandall Stewart #define CC_DEFAULT_ALGO() V_default_cc_ptr 2194644fda3SGleb Smirnoff 2204644fda3SGleb Smirnoff extern struct rwlock cc_list_lock; 2214644fda3SGleb Smirnoff #define CC_LIST_LOCK_INIT() rw_init(&cc_list_lock, "cc_list") 2224644fda3SGleb Smirnoff #define CC_LIST_LOCK_DESTROY() rw_destroy(&cc_list_lock) 2234644fda3SGleb Smirnoff #define CC_LIST_RLOCK() rw_rlock(&cc_list_lock) 2244644fda3SGleb Smirnoff #define CC_LIST_RUNLOCK() rw_runlock(&cc_list_lock) 2254644fda3SGleb Smirnoff #define CC_LIST_WLOCK() rw_wlock(&cc_list_lock) 2264644fda3SGleb Smirnoff #define CC_LIST_WUNLOCK() rw_wunlock(&cc_list_lock) 2274644fda3SGleb Smirnoff #define CC_LIST_LOCK_ASSERT() rw_assert(&cc_list_lock, RA_LOCKED) 2284644fda3SGleb Smirnoff 229c8b53cedSMichael Tuexen #define CC_ALGOOPT_LIMIT 2048 230c8b53cedSMichael Tuexen 231b8d60729SRandall Stewart /* 232b8d60729SRandall Stewart * These routines give NewReno behavior to the caller 233b8d60729SRandall Stewart * they require no state and can be used by any other CC 234b8d60729SRandall Stewart * module that wishes to use NewReno type behaviour (along 235b8d60729SRandall Stewart * with anything else they may add on, pre or post call). 236b8d60729SRandall Stewart */ 237b8d60729SRandall Stewart void newreno_cc_post_recovery(struct cc_var *); 238b8d60729SRandall Stewart void newreno_cc_after_idle(struct cc_var *); 239*f74352fbSRichard Scheffenegger void newreno_cc_cong_signal(struct cc_var *, ccsignal_t); 240*f74352fbSRichard Scheffenegger void newreno_cc_ack_received(struct cc_var *, ccsignal_t); 241b8d60729SRandall Stewart 242ea9017fbSRandall Stewart /* Called to temporarily keep an algo from going away during change */ 243ea9017fbSRandall Stewart void cc_refer(struct cc_algo *algo); 244ea9017fbSRandall Stewart /* Called to release the temporary hold */ 245ea9017fbSRandall Stewart void cc_release(struct cc_algo *algo); 246ea9017fbSRandall Stewart 247ea9017fbSRandall Stewart /* Called to attach a CC algorithm to a tcpcb */ 248ea9017fbSRandall Stewart void cc_attach(struct tcpcb *, struct cc_algo *); 249ea9017fbSRandall Stewart /* Called to detach a CC algorithm from a tcpcb */ 250ea9017fbSRandall Stewart void cc_detach(struct tcpcb *); 251ea9017fbSRandall Stewart 252adc56f5aSEdward Tomasz Napierala #endif /* _KERNEL */ 2534644fda3SGleb Smirnoff #endif /* _NETINET_CC_CC_H_ */ 254