#ifndef _NETINET_TCP_VAR_H_
#define _NETINET_TCP_VAR_H_
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#ifdef _KERNEL
#include <net/vnet.h>
#include <sys/mbuf.h>
#include <sys/ktls.h>
#endif
#define TCP_END_BYTE_INFO 8
#define TCP_EI_EMPTY_SLOT 0
#define TCP_EI_STATUS_CLIENT_FIN 0x1
#define TCP_EI_STATUS_CLIENT_RST 0x2
#define TCP_EI_STATUS_SERVER_FIN 0x3
#define TCP_EI_STATUS_SERVER_RST 0x4
#define TCP_EI_STATUS_RETRAN 0x5
#define TCP_EI_STATUS_PROGRESS 0x6
#define TCP_EI_STATUS_PERSIST_MAX 0x7
#define TCP_EI_STATUS_KEEP_MAX 0x8
#define TCP_EI_STATUS_DATA_A_CLOSE 0x9
#define TCP_EI_STATUS_RST_IN_FRONT 0xa
#define TCP_EI_STATUS_2MSL 0xb
#define TCP_EI_STATUS_MAX_VALUE 0xb
#define TCP_TRK_REQ_LOG_NEW 0x01
#define TCP_TRK_REQ_LOG_COMPLETE 0x02
#define TCP_TRK_REQ_LOG_FREED 0x03
#define TCP_TRK_REQ_LOG_ALLOCFAIL 0x04
#define TCP_TRK_REQ_LOG_MOREYET 0x05
#define TCP_TRK_REQ_LOG_FORCEFREE 0x06
#define TCP_TRK_REQ_LOG_STALE 0x07
#define TCP_TRK_REQ_LOG_SEARCH 0x08
#define TCP_EI_BITS_CLIENT_FIN 0x001
#define TCP_EI_BITS_CLIENT_RST 0x002
#define TCP_EI_BITS_SERVER_FIN 0x004
#define TCP_EI_BITS_SERVER_RST 0x008
#define TCP_EI_BITS_RETRAN 0x010
#define TCP_EI_BITS_PROGRESS 0x020
#define TCP_EI_BITS_PRESIST_MAX 0x040
#define TCP_EI_BITS_KEEP_MAX 0x080
#define TCP_EI_BITS_DATA_A_CLO 0x100
#define TCP_EI_BITS_RST_IN_FR 0x200
#define TCP_EI_BITS_2MS_TIMER 0x400
#define TCP_TRK_TRACK_FLG_EMPTY 0x00
#define TCP_TRK_TRACK_FLG_USED 0x01
#define TCP_TRK_TRACK_FLG_OPEN 0x02
#define TCP_TRK_TRACK_FLG_SEQV 0x04
#define TCP_TRK_TRACK_FLG_COMP 0x08
#define TCP_TRK_TRACK_FLG_FSND 0x10
#define TCP_TRK_TRACK_FLG_LSND 0x20
#define MAX_TCP_TRK_REQ 5
#if defined(_KERNEL)
#include <sys/_callout.h>
#include <sys/osd.h>
#include <netinet/cc/cc.h>
struct tseg_qent {
TAILQ_ENTRY(tseg_qent) tqe_q;
struct mbuf *tqe_m;
struct mbuf *tqe_last;
tcp_seq tqe_start;
int tqe_len;
uint32_t tqe_flags;
uint32_t tqe_mbuf_cnt;
};
TAILQ_HEAD(tsegqe_head, tseg_qent);
struct sackblk {
tcp_seq start;
tcp_seq end;
};
struct sackhole {
tcp_seq start;
tcp_seq end;
tcp_seq rxmit;
TAILQ_ENTRY(sackhole) scblink;
};
struct sackhint {
struct sackhole *nexthole;
int32_t sack_bytes_rexmit;
tcp_seq last_sack_ack;
int32_t delivered_data;
int32_t sacked_bytes;
uint32_t recover_fs;
uint32_t prr_delivered;
uint32_t prr_out;
int32_t hole_bytes;
int32_t lost_bytes;
};
#define SEGQ_EMPTY(tp) TAILQ_EMPTY(&(tp)->t_segq)
STAILQ_HEAD(tcp_log_stailq, tcp_log_mem);
struct tcp_sendfile_track {
uint64_t timestamp;
uint64_t start;
uint64_t end;
uint64_t localtime;
uint64_t deadline;
uint64_t first_send;
uint64_t cspr;
uint64_t sent_at_fs;
uint64_t rxt_at_fs;
uint64_t sent_at_ls;
uint64_t rxt_at_ls;
tcp_seq start_seq;
tcp_seq end_seq;
uint32_t flags;
uint32_t sbcc_at_s;
uint32_t hint_maxseg;
uint32_t playout_ms;
uint32_t hybrid_flags;
};
#define TCP_QUERY_SENDMAP 1
#define TCP_QUERY_TIMERS_UP 2
#define TCP_QUERY_RACK_TIMES 3
#define SNDMAP_ACKED 0x000001
#define SNDMAP_OVERMAX 0x000008
#define SNDMAP_SACK_PASSED 0x000010
#define SNDMAP_HAS_FIN 0x000040
#define SNDMAP_TLP 0x000080
#define SNDMAP_HAS_SYN 0x000800
#define SNDMAP_HAD_PUSH 0x008000
#define SNDMAP_MASK (SNDMAP_ACKED|SNDMAP_OVERMAX|SNDMAP_SACK_PASSED|SNDMAP_HAS_FIN\
|SNDMAP_TLP|SNDMAP_HAS_SYN|SNDMAP_HAD_PUSH)
#define SNDMAP_NRTX 3
struct tcp_query_resp {
int req;
uint32_t req_param;
union {
struct {
tcp_seq sendmap_start;
tcp_seq sendmap_end;
int sendmap_send_cnt;
uint64_t sendmap_time[SNDMAP_NRTX];
uint64_t sendmap_ack_arrival;
int sendmap_flags;
uint32_t sendmap_r_rtr_bytes;
uint32_t sendmap_fas;
uint8_t sendmap_dupacks;
};
struct {
uint32_t timer_hpts_flags;
uint32_t timer_pacing_to;
uint32_t timer_timer_exp;
};
struct {
uint32_t rack_reorder_ts;
uint32_t rack_num_dsacks;
uint32_t rack_rxt_last_time;
uint32_t rack_min_rtt;
uint32_t rack_rtt;
uint32_t rack_tmit_time;
uint32_t rack_time_went_idle;
uint32_t rack_sacked;
uint32_t rack_holes_rxt;
uint32_t rack_prr_delivered;
uint32_t rack_prr_recovery_fs;
uint32_t rack_prr_out;
uint32_t rack_prr_sndcnt;
uint16_t rack_tlp_cnt_out;
uint8_t rack_tlp_out;
uint8_t rack_srtt_measured;
uint8_t rack_in_persist;
uint8_t rack_wanted_output;
};
};
};
#define TCP_TMR_GRANULARITY_TICKS 1
#define TCP_TMR_GRANULARITY_USEC 2
typedef enum {
TT_REXMT = 0,
TT_PERSIST,
TT_KEEP,
TT_2MSL,
TT_DELACK,
TT_N,
} tt_which;
typedef enum {
TT_PROCESSING = 0,
TT_PROCESSED,
TT_STARTING,
TT_STOPPING,
} tt_what;
struct tcpcb {
struct inpcb t_inpcb;
#define t_start_zero t_fb
#define t_zero_size (sizeof(struct tcpcb) - \
offsetof(struct tcpcb, t_start_zero))
struct tcp_function_block *t_fb;
void *t_fb_ptr;
struct callout t_callout;
sbintime_t t_timers[TT_N];
sbintime_t t_precisions[TT_N];
TAILQ_ENTRY(tcpcb) t_hpts;
STAILQ_HEAD(, mbuf) t_inqueue;
uint32_t t_hpts_request;
uint32_t t_hpts_slot;
uint32_t t_hpts_drop_reas;
uint32_t t_hpts_gencnt;
uint16_t t_hpts_cpu;
uint16_t t_lro_cpu;
#define HPTS_CPU_NONE ((uint16_t)-1)
enum {
IHPTS_NONE = 0,
IHPTS_ONQUEUE,
IHPTS_MOVING,
} t_in_hpts;
uint32_t t_maxseg:24,
_t_logstate:8;
uint32_t t_port:16,
t_state:4,
t_idle_reduce : 1,
t_delayed_ack: 7,
t_fin_is_rst: 1,
t_log_state_set: 1,
bits_spare : 2;
u_int t_flags;
tcp_seq snd_una;
tcp_seq snd_max;
tcp_seq snd_nxt;
tcp_seq snd_up;
uint32_t snd_wnd;
uint32_t snd_cwnd;
uint32_t ts_offset;
uint32_t rfbuf_ts;
int rcv_numsacks;
u_int t_tsomax;
u_int t_tsomaxsegcount;
u_int t_tsomaxsegsize;
tcp_seq rcv_nxt;
tcp_seq rcv_adv;
uint32_t rcv_wnd;
u_int t_flags2;
int t_srtt;
int t_rttvar;
uint32_t ts_recent;
u_char snd_scale;
u_char rcv_scale;
u_char snd_limited;
u_char request_r_scale;
tcp_seq last_ack_sent;
u_int t_rcvtime;
tcp_seq rcv_up;
int t_segqlen;
uint32_t t_segqmbuflen;
struct tsegqe_head t_segq;
uint32_t snd_ssthresh;
tcp_seq snd_wl1;
tcp_seq snd_wl2;
tcp_seq irs;
tcp_seq iss;
u_int t_acktime;
u_int t_sndtime;
u_int ts_recent_age;
tcp_seq snd_recover;
char t_oobflags;
char t_iobc;
uint8_t t_nic_ktls_xmit:1,
t_nic_ktls_xmit_dis:1,
t_nic_ktls_spare:6;
int t_rxtcur;
int t_rxtshift;
u_int t_rtttime;
tcp_seq t_rtseq;
u_int t_starttime;
u_int t_fbyte_in;
u_int t_fbyte_out;
u_int t_pmtud_saved_maxseg;
int t_blackhole_enter;
int t_blackhole_exit;
u_int t_rttmin;
int t_softerror;
uint32_t max_sndwnd;
uint32_t snd_cwnd_prev;
uint32_t snd_ssthresh_prev;
tcp_seq snd_recover_prev;
int t_sndzerowin;
int snd_numholes;
u_int t_badrxtwin;
TAILQ_HEAD(sackhole_head, sackhole) snd_holes;
tcp_seq snd_fack;
struct sackblk sackblks[MAX_SACK_BLKS];
struct sackhint sackhint;
int t_rttlow;
int rfbuf_cnt;
struct toedev *tod;
int t_sndrexmitpack;
int t_rcvoopack;
void *t_toe;
struct cc_algo *t_cc;
struct cc_var t_ccv;
int t_bytes_acked;
u_int t_maxunacktime;
u_int t_keepinit;
u_int t_keepidle;
u_int t_keepintvl;
u_int t_keepcnt;
int t_dupacks;
int t_lognum;
int t_loglimit;
uint32_t t_rcep;
uint32_t t_scep;
int64_t t_pacing_rate;
struct tcp_log_stailq t_logs;
struct tcp_log_id_node *t_lin;
struct tcp_log_id_bucket *t_lib;
const char *t_output_caller;
struct statsblob *t_stats;
uint32_t t_logsn;
uint32_t gput_ts;
tcp_seq gput_seq;
tcp_seq gput_ack;
int32_t t_stats_gput_prev;
uint32_t t_sndtlppack;
uint64_t t_sndtlpbyte;
uint64_t t_sndbytes;
uint64_t t_snd_rxt_bytes;
uint32_t t_dsack_bytes;
uint32_t t_dsack_tlp_bytes;
uint32_t t_dsack_pack;
uint8_t t_tmr_granularity;
uint8_t t_rttupdated;
uint8_t t_tfo_client_cookie_len;
uint32_t t_end_info_status;
sbintime_t t_challenge_ack_end;
uint32_t t_challenge_ack_cnt;
unsigned int *t_tfo_pending;
union {
uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN];
uint64_t server;
} t_tfo_cookie;
union {
uint8_t t_end_info_bytes[TCP_END_BYTE_INFO];
uint64_t t_end_info;
};
struct osd t_osd;
uint8_t _t_logpoint;
#ifdef TCP_REQUEST_TRK
uint8_t t_tcpreq_req;
uint8_t t_tcpreq_open;
uint8_t t_tcpreq_closed;
uint32_t tcp_hybrid_start;
uint32_t tcp_hybrid_stop;
uint32_t tcp_hybrid_error;
struct tcp_sendfile_track t_tcpreq_info[MAX_TCP_TRK_REQ];
#endif
#ifdef TCP_ACCOUNTING
uint64_t tcp_cnt_counters[TCP_NUM_CNT_COUNTERS];
uint64_t tcp_proc_time[TCP_NUM_CNT_COUNTERS];
#endif
};
#endif
#ifdef _KERNEL
struct tcptemp {
u_char tt_ipgen[40];
struct tcphdr tt_t;
};
typedef enum {
SACK_NOCHANGE = 0,
SACK_CHANGE,
SACK_NEWLOSS
} sackstatus_t;
#define TCP_TUNNELING_PORT_MIN 0
#define TCP_TUNNELING_PORT_MAX 65535
#define TCP_TUNNELING_PORT_DEFAULT 0
#define TCP_TUNNELING_OVERHEAD_MIN sizeof(struct udphdr)
#define TCP_TUNNELING_OVERHEAD_MAX 1024
#define TCP_TUNNELING_OVERHEAD_DEFAULT TCP_TUNNELING_OVERHEAD_MIN
#define TCP_MIN_MAP_ENTRIES_LIMIT 128
#define TCP_FUNC_BEING_REMOVED 0x01
#define TCP_FUNC_OUTPUT_CANDROP 0x02
#define TCP_FUNC_DEFAULT_OK 0x04
struct tcp_function_block {
char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX];
int (*tfb_tcp_output)(struct tcpcb *);
void (*tfb_tcp_do_segment)(struct tcpcb *, struct mbuf *,
struct tcphdr *, int, int, uint8_t);
int (*tfb_do_segment_nounlock)(struct tcpcb *, struct mbuf *,
struct tcphdr *, int, int, uint8_t, int, struct timeval *);
int (*tfb_do_queued_segments)(struct tcpcb *, int);
int (*tfb_tcp_ctloutput)(struct tcpcb *, struct sockopt *);
int (*tfb_tcp_fb_init)(struct tcpcb *, void **);
void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
int (*tfb_tcp_handoff_ok)(struct tcpcb *);
void (*tfb_tcp_mtu_chg)(struct tcpcb *tp);
int (*tfb_pru_options)(struct tcpcb *, int);
void (*tfb_hwtls_change)(struct tcpcb *, int);
int (*tfb_chg_query)(struct tcpcb *, struct tcp_query_resp *);
void (*tfb_switch_failed)(struct tcpcb *);
bool (*tfb_early_wake_check)(struct tcpcb *);
int (*tfb_compute_pipe)(struct tcpcb *tp);
int (*tfb_stack_info)(struct tcpcb *tp, struct stack_specific_info *);
void (*tfb_inherit)(struct tcpcb *tp, struct inpcb *h_inp);
volatile uint32_t tfb_refcnt;
uint32_t tfb_flags;
uint8_t tfb_id;
};
#define TCP_FUNCTION_NAME_NUM_MAX 8
struct tcp_function {
TAILQ_ENTRY(tcp_function) tf_next;
char tf_name[TCP_FUNCTION_NAME_LEN_MAX];
struct tcp_function_block *tf_fb;
};
TAILQ_HEAD(tcp_funchead, tcp_function);
struct tcpcb * tcp_drop(struct tcpcb *, int);
#ifdef _NETINET_IN_PCB_H_
#define intotcpcb(inp) __containerof((inp), struct tcpcb, t_inpcb)
#define sototcpcb(so) intotcpcb(sotoinpcb(so))
#define tptoinpcb(tp) (&(tp)->t_inpcb)
#define tptosocket(tp) (tp)->t_inpcb.inp_socket
static inline int
tcp_output(struct tcpcb *tp)
{
struct inpcb *inp = tptoinpcb(tp);
int rv;
INP_WLOCK_ASSERT(inp);
rv = tp->t_fb->tfb_tcp_output(tp);
if (rv < 0) {
KASSERT(tp->t_fb->tfb_flags & TCP_FUNC_OUTPUT_CANDROP,
("TCP stack %s requested tcp_drop(%p)",
tp->t_fb->tfb_tcp_block_name, tp));
tp = tcp_drop(tp, -rv);
if (tp)
INP_WUNLOCK(inp);
}
return (rv);
}
static inline int
tcp_output_unlock(struct tcpcb *tp)
{
struct inpcb *inp = tptoinpcb(tp);
int rv;
INP_WLOCK_ASSERT(inp);
rv = tp->t_fb->tfb_tcp_output(tp);
if (rv < 0) {
KASSERT(tp->t_fb->tfb_flags & TCP_FUNC_OUTPUT_CANDROP,
("TCP stack %s requested tcp_drop(%p)",
tp->t_fb->tfb_tcp_block_name, tp));
rv = -rv;
tp = tcp_drop(tp, rv);
if (tp)
INP_WUNLOCK(inp);
} else
INP_WUNLOCK(inp);
return (rv);
}
static inline int
tcp_output_nodrop(struct tcpcb *tp)
{
int rv;
INP_WLOCK_ASSERT(tptoinpcb(tp));
rv = tp->t_fb->tfb_tcp_output(tp);
KASSERT(rv >= 0 || tp->t_fb->tfb_flags & TCP_FUNC_OUTPUT_CANDROP,
("TCP stack %s requested tcp_drop(%p)",
tp->t_fb->tfb_tcp_block_name, tp));
return (rv);
}
static inline int
tcp_unlock_or_drop(struct tcpcb *tp, int tcp_output_retval)
{
struct inpcb *inp = tptoinpcb(tp);
INP_WLOCK_ASSERT(inp);
if (tcp_output_retval < 0) {
tcp_output_retval = -tcp_output_retval;
if (tcp_drop(tp, tcp_output_retval) != NULL)
INP_WUNLOCK(inp);
} else
INP_WUNLOCK(inp);
return (tcp_output_retval);
}
#endif
static int inline
tcp_packets_this_ack(struct tcpcb *tp, tcp_seq ack)
{
return ((ack - tp->snd_una) / tp->t_maxseg +
((((ack - tp->snd_una) % tp->t_maxseg) != 0) ? 1 : 0));
}
#endif
#define TF_ACKNOW 0x00000001
#define TF_DELACK 0x00000002
#define TF_NODELAY 0x00000004
#define TF_NOOPT 0x00000008
#define TF_SENTFIN 0x00000010
#define TF_REQ_SCALE 0x00000020
#define TF_RCVD_SCALE 0x00000040
#define TF_REQ_TSTMP 0x00000080
#define TF_RCVD_TSTMP 0x00000100
#define TF_SACK_PERMIT 0x00000200
#define TF_NEEDSYN 0x00000400
#define TF_NEEDFIN 0x00000800
#define TF_NOPUSH 0x00001000
#define TF_PREVVALID 0x00002000
#define TF_WAKESOR 0x00004000
#define TF_GPUTINPROG 0x00008000
#define TF_MORETOCOME 0x00010000
#define TF_SONOTCONN 0x00020000
#define TF_LASTIDLE 0x00040000
#define TF_RXWIN0SENT 0x00080000
#define TF_FASTRECOVERY 0x00100000
#define TF_WASFRECOVERY 0x00200000
#define TF_SIGNATURE 0x00400000
#define TF_FORCEDATA 0x00800000
#define TF_TSO 0x01000000
#define TF_TOE 0x02000000
#define TF_CLOSED 0x04000000
#define TF_UNUSED 0x08000000
#define TF_LRD 0x10000000
#define TF_CONGRECOVERY 0x20000000
#define TF_WASCRECOVERY 0x40000000
#define TF_FASTOPEN 0x80000000
#define TF_BITS "\20" \
"\1TF_ACKNOW\2TF_DELACK\3TF_NODELAY\4TF_NOOPT" \
"\5TF_SENTFIN\6TF_REQ_SCALE\7TF_RCVD_SCALE\10TF_REQ_TSTMP" \
"\11TF_RCVD_TSTMP\12TF_SACK_PERMIT\13TF_NEEDSYN\14TF_NEEDFIN" \
"\15TF_NOPUSH\16TF_PREVVALID\17TF_WAKESOR\20TF_GPUTINPROG" \
"\21TF_MORETOCOME\22TF_SONOTCONN\23TF_LASTIDLE\24TF_RXWIN0SENT" \
"\25TF_FASTRECOVERY\26TF_WASFRECOVERY\27TF_SIGNATURE\30TF_FORCEDATA" \
"\31TF_TSO\32TF_TOE\33TF_CLOSED\34TF_UNUSED" \
"\35TF_LRD\36TF_CONGRECOVERY\37TF_WASCRECOVERY\40TF_FASTOPEN"
#define IN_FASTRECOVERY(t_flags) (t_flags & TF_FASTRECOVERY)
#define ENTER_FASTRECOVERY(t_flags) t_flags |= TF_FASTRECOVERY
#define EXIT_FASTRECOVERY(t_flags) t_flags &= ~TF_FASTRECOVERY
#define IN_CONGRECOVERY(t_flags) (t_flags & TF_CONGRECOVERY)
#define ENTER_CONGRECOVERY(t_flags) t_flags |= TF_CONGRECOVERY
#define EXIT_CONGRECOVERY(t_flags) t_flags &= ~TF_CONGRECOVERY
#define IN_RECOVERY(t_flags) (t_flags & (TF_CONGRECOVERY | TF_FASTRECOVERY))
#define ENTER_RECOVERY(t_flags) t_flags |= (TF_CONGRECOVERY | TF_FASTRECOVERY)
#define EXIT_RECOVERY(t_flags) t_flags &= ~(TF_CONGRECOVERY | TF_FASTRECOVERY)
#define BYTES_THIS_ACK(tp, th) (th->th_ack - tp->snd_una)
#define TCPOOB_HAVEDATA 0x01
#define TCPOOB_HADDATA 0x02
#define TCPOOB_BITS "\20\1TCPOOB_HAVEDATA\2TCPOOB_HADDATA"
#define TF2_PLPMTU_BLACKHOLE 0x00000001
#define TF2_PLPMTU_PMTUD 0x00000002
#define TF2_PLPMTU_MAXSEGSNT 0x00000004
#define TF2_LOG_AUTO 0x00000008
#define TF2_DROP_AF_DATA 0x00000010
#define TF2_ECN_PERMIT 0x00000020
#define TF2_ECN_SND_CWR 0x00000040
#define TF2_ECN_SND_ECE 0x00000080
#define TF2_ACE_PERMIT 0x00000100
#define TF2_HPTS_CPU_SET 0x00000200
#define TF2_FBYTES_COMPLETE 0x00000400
#define TF2_ECN_USE_ECT1 0x00000800
#define TF2_TCP_ACCOUNTING 0x00001000
#define TF2_HPTS_CALLS 0x00002000
#define TF2_MBUF_L_ACKS 0x00004000
#define TF2_MBUF_ACKCMP 0x00008000
#define TF2_SUPPORTS_MBUFQ 0x00010000
#define TF2_MBUF_QUEUE_READY 0x00020000
#define TF2_DONT_SACK_QUEUE 0x00040000
#define TF2_CANNOT_DO_ECN 0x00080000
#define TF2_PROC_SACK_PROHIBIT 0x00100000
#define TF2_IPSEC_TSO 0x00200000
#define TF2_NO_ISS_CHECK 0x00400000
#define TF2_BITS "\20" \
"\1TF2_PLPMTU_BLACKHOLE\2TF2_PLPMTU_PMTUD" \
"\3TF2_PLPMTU_MAXSEGSNT\4TF2_LOG_AUTO" \
"\5TF2_DROP_AF_DATA\6TF2_ECN_PERMIT" \
"\7TF2_ECN_SND_CWR\10TF2_ECN_SND_ECE" \
"\11TF2_ACE_PERMIT\12TF2_HPTS_CPU_SET" \
"\13TF2_FBYTES_COMPLETE\14TF2_ECN_USE_ECT1" \
"\15TF2_TCP_ACCOUNTING\16TF2_HPTS_CALLS" \
"\17TF2_MBUF_L_ACKS\20TF2_MBUF_ACKCMP" \
"\21TF2_SUPPORTS_MBUFQ\22TF2_MBUF_QUEUE_READY" \
"\23TF2_DONT_SACK_QUEUE\24TF2_CANNOT_DO_ECN" \
"\25TF2_PROC_SACK_PROHIBIT\26TF2_IPSEC_TSO" \
"\27TF2_NO_ISS_CHECK"
struct tcpopt {
u_int32_t to_flags;
#define TOF_MSS 0x0001
#define TOF_SCALE 0x0002
#define TOF_SACKPERM 0x0004
#define TOF_TS 0x0010
#define TOF_SIGNATURE 0x0040
#define TOF_SACK 0x0080
#define TOF_FASTOPEN 0x0100
#define TOF_MAXOPT 0x0200
u_int32_t to_tsval;
u_int32_t to_tsecr;
u_char *to_sacks;
u_char *to_signature;
u_int8_t *to_tfo_cookie;
u_int16_t to_mss;
u_int8_t to_wscale;
u_int8_t to_nsacks;
u_int8_t to_tfo_len;
u_int32_t to_spare;
};
#define TO_SYN 0x01
struct hc_metrics_lite {
uint32_t hc_mtu;
uint32_t hc_ssthresh;
uint32_t hc_rtt;
uint32_t hc_rttvar;
uint32_t hc_cwnd;
uint32_t hc_sendpipe;
uint32_t hc_recvpipe;
};
#ifndef _NETINET_IN_PCB_H_
struct in_conninfo;
#endif
#define TCP_RTT_SCALE 32
#define TCP_RTT_SHIFT 5
#define TCP_RTTVAR_SCALE 16
#define TCP_RTTVAR_SHIFT 4
#define TCP_DELTA_SHIFT 2
#define TCP_REXMTVAL(tp) \
max((tp)->t_rttmin, (((tp)->t_srtt >> (TCP_RTT_SHIFT - TCP_DELTA_SHIFT)) \
+ (tp)->t_rttvar) >> TCP_DELTA_SHIFT)
struct tcpstat {
uint64_t tcps_connattempt;
uint64_t tcps_accepts;
uint64_t tcps_connects;
uint64_t tcps_drops;
uint64_t tcps_conndrops;
uint64_t tcps_minmssdrops;
uint64_t tcps_closed;
uint64_t tcps_segstimed;
uint64_t tcps_rttupdated;
uint64_t tcps_delack;
uint64_t tcps_timeoutdrop;
uint64_t tcps_rexmttimeo;
uint64_t tcps_persisttimeo;
uint64_t tcps_keeptimeo;
uint64_t tcps_keepprobe;
uint64_t tcps_keepdrops;
uint64_t tcps_progdrops;
uint64_t tcps_sndtotal;
uint64_t tcps_sndpack;
uint64_t tcps_sndbyte;
uint64_t tcps_sndrexmitpack;
uint64_t tcps_sndrexmitbyte;
uint64_t tcps_sndrexmitbad;
uint64_t tcps_sndacks;
uint64_t tcps_sndprobe;
uint64_t tcps_sndurg;
uint64_t tcps_sndwinup;
uint64_t tcps_sndctrl;
uint64_t tcps_rcvtotal;
uint64_t tcps_rcvpack;
uint64_t tcps_rcvbyte;
uint64_t tcps_rcvbadsum;
uint64_t tcps_rcvbadoff;
uint64_t tcps_rcvreassfull;
uint64_t tcps_rcvshort;
uint64_t tcps_rcvduppack;
uint64_t tcps_rcvdupbyte;
uint64_t tcps_rcvpartduppack;
uint64_t tcps_rcvpartdupbyte;
uint64_t tcps_rcvoopack;
uint64_t tcps_rcvoobyte;
uint64_t tcps_rcvpackafterwin;
uint64_t tcps_rcvbyteafterwin;
uint64_t tcps_rcvafterclose;
uint64_t tcps_rcvwinprobe;
uint64_t tcps_rcvdupack;
uint64_t tcps_rcvacktoomuch;
uint64_t tcps_rcvackpack;
uint64_t tcps_rcvackbyte;
uint64_t tcps_rcvwinupd;
uint64_t tcps_pawsdrop;
uint64_t tcps_predack;
uint64_t tcps_preddat;
uint64_t tcps_pcbcachemiss;
uint64_t tcps_cachedrtt;
uint64_t tcps_cachedrttvar;
uint64_t tcps_cachedssthresh;
uint64_t tcps_usedrtt;
uint64_t tcps_usedrttvar;
uint64_t tcps_usedssthresh;
uint64_t tcps_persistdrop;
uint64_t tcps_badsyn;
uint64_t tcps_mturesent;
uint64_t tcps_listendrop;
uint64_t tcps_badrst;
uint64_t tcps_sc_added;
uint64_t tcps_sc_retransmitted;
uint64_t tcps_sc_dupsyn;
uint64_t tcps_sc_dropped;
uint64_t tcps_sc_completed;
uint64_t tcps_sc_bucketoverflow;
uint64_t tcps_sc_cacheoverflow;
uint64_t tcps_sc_reset;
uint64_t tcps_sc_stale;
uint64_t tcps_sc_aborted;
uint64_t tcps_sc_badack;
uint64_t tcps_sc_unreach;
uint64_t tcps_sc_zonefail;
uint64_t tcps_sc_sendcookie;
uint64_t tcps_sc_recvcookie;
uint64_t tcps_sc_spurcookie;
uint64_t tcps_sc_failcookie;
uint64_t tcps_hc_added;
uint64_t tcps_hc_bucketoverflow;
uint64_t tcps_finwait2_drops;
uint64_t tcps_sack_recovery_episode;
uint64_t tcps_sack_rexmits;
uint64_t tcps_sack_rexmits_tso;
uint64_t tcps_sack_rexmit_bytes;
uint64_t tcps_sack_rcv_blocks;
uint64_t tcps_sack_send_blocks;
uint64_t tcps_sack_lostrexmt;
uint64_t tcps_sack_sboverflow;
uint64_t tcps_ecn_rcvce;
uint64_t tcps_ecn_rcvect0;
uint64_t tcps_ecn_rcvect1;
uint64_t tcps_ecn_shs;
uint64_t tcps_ecn_rcwnd;
uint64_t tcps_sig_rcvgoodsig;
uint64_t tcps_sig_rcvbadsig;
uint64_t tcps_sig_err_buildsig;
uint64_t tcps_sig_err_sigopt;
uint64_t tcps_sig_err_nosigopt;
uint64_t tcps_pmtud_blackhole_activated;
uint64_t tcps_pmtud_blackhole_activated_min_mss;
uint64_t tcps_pmtud_blackhole_failed;
uint64_t tcps_tunneled_pkts;
uint64_t tcps_tunneled_errs;
uint64_t tcps_dsack_count;
uint64_t tcps_dsack_bytes;
uint64_t tcps_dsack_tlp_bytes;
uint64_t tcps_tw_recycles;
uint64_t tcps_tw_resets;
uint64_t tcps_tw_responds;
uint64_t tcps_ace_nect;
uint64_t tcps_ace_ect1;
uint64_t tcps_ace_ect0;
uint64_t tcps_ace_ce;
uint64_t tcps_ecn_sndect0;
uint64_t tcps_ecn_sndect1;
uint64_t tcps_tlpresends;
uint64_t tcps_tlpresend_bytes;
uint64_t tcps_rcvghostack;
uint64_t tcps_rcvacktooold;
uint64_t _pad[1];
};
#define tcps_rcvmemdrop tcps_rcvreassfull
#ifdef _KERNEL
#include <sys/counter.h>
#include <netinet/in_kdtrace.h>
VNET_PCPUSTAT_DECLARE(struct tcpstat, tcpstat);
#define TCPSTAT_ADD(name, val) \
do { \
MIB_SDT_PROBE1(tcp, count, name, (val)); \
VNET_PCPUSTAT_ADD(struct tcpstat, tcpstat, name, (val)); \
} while (0)
#define TCPSTAT_INC(name) TCPSTAT_ADD(name, 1)
void kmod_tcpstat_add(int statnum, int val);
#define KMOD_TCPSTAT_ADD(name, val) \
do { \
MIB_SDT_PROBE1(tcp, count, name, (val)); \
kmod_tcpstat_add(offsetof(struct tcpstat, name) / \
sizeof(uint64_t), \
val); \
} while (0)
#define KMOD_TCPSTAT_INC(name) KMOD_TCPSTAT_ADD(name, 1)
VNET_DECLARE(counter_u64_t, tcps_states[TCP_NSTATES]);
#define V_tcps_states VNET(tcps_states)
#define TCPSTATES_INC(state) counter_u64_add(V_tcps_states[state], 1)
#define TCPSTATES_DEC(state) counter_u64_add(V_tcps_states[state], -1)
#define HHOOK_TCP_EST_IN 0
#define HHOOK_TCP_EST_OUT 1
#define HHOOK_TCP_LAST HHOOK_TCP_EST_OUT
struct tcp_hhook_data {
struct tcpcb *tp;
struct tcphdr *th;
struct tcpopt *to;
uint32_t len;
int tso;
tcp_seq curack;
};
#ifdef TCP_HHOOK
void hhook_run_tcp_est_out(struct tcpcb *tp,
struct tcphdr *th, struct tcpopt *to,
uint32_t len, int tso);
#endif
#endif
#if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_)
struct xtcpcb {
ksize_t xt_len;
struct xinpcb xt_inp;
char xt_stack[TCP_FUNCTION_NAME_LEN_MAX];
char xt_logid[TCP_LOG_ID_LEN];
char xt_cc[TCP_CA_NAME_MAX];
int64_t spare64[6];
int32_t t_state;
uint32_t t_flags;
int32_t t_sndzerowin;
int32_t t_sndrexmitpack;
int32_t t_rcvoopack;
int32_t t_rcvtime;
int32_t tt_rexmt;
int32_t tt_persist;
int32_t tt_keep;
int32_t tt_2msl;
int32_t tt_delack;
int32_t t_logstate;
uint32_t t_snd_cwnd;
uint32_t t_snd_ssthresh;
uint32_t t_maxseg;
uint32_t t_rcv_wnd;
uint32_t t_snd_wnd;
uint32_t xt_ecn;
uint32_t t_dsack_bytes;
uint32_t t_dsack_tlp_bytes;
uint32_t t_dsack_pack;
uint16_t xt_encaps_port;
int16_t spare16;
int32_t spare32[22];
} __aligned(8);
#ifdef _KERNEL
void tcp_inptoxtp(const struct inpcb *, struct xtcpcb *);
#endif
#endif
struct tcp_function_info {
uint32_t tfi_refcnt;
uint8_t tfi_id;
char tfi_name[TCP_FUNCTION_NAME_LEN_MAX];
char tfi_alias[TCP_FUNCTION_NAME_LEN_MAX];
};
#define TCPCTL_DO_RFC1323 1
#define TCPCTL_MSSDFLT 3
#define TCPCTL_STATS 4
#define TCPCTL_RTTDFLT 5
#define TCPCTL_KEEPIDLE 6
#define TCPCTL_KEEPINTVL 7
#define TCPCTL_SENDSPACE 8
#define TCPCTL_RECVSPACE 9
#define TCPCTL_KEEPINIT 10
#define TCPCTL_PCBLIST 11
#define TCPCTL_DELACKTIME 12
#define TCPCTL_V6MSSDFLT 13
#define TCPCTL_SACK 14
#define TCPCTL_DROP 15
#define TCPCTL_STATES 16
#define TCPCTL_KTLSLIST 17
#define TCPCTL_KTLSLIST_WKEYS 18
#ifdef _KERNEL
#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_inet_tcp);
SYSCTL_DECL(_net_inet_tcp_sack);
MALLOC_DECLARE(M_TCPLOG);
#endif
VNET_DECLARE(int, tcp_log_in_vain);
#define V_tcp_log_in_vain VNET(tcp_log_in_vain)
VNET_DECLARE(int, drop_synfin);
VNET_DECLARE(int, path_mtu_discovery);
VNET_DECLARE(int, tcp_abc_l_var);
VNET_DECLARE(uint32_t, tcp_ack_war_cnt);
VNET_DECLARE(uint32_t, tcp_ack_war_time_window);
VNET_DECLARE(int, tcp_autorcvbuf_max);
VNET_DECLARE(int, tcp_autosndbuf_inc);
VNET_DECLARE(int, tcp_autosndbuf_max);
VNET_DECLARE(int, tcp_bind_all_fibs);
VNET_DECLARE(int, tcp_delack_enabled);
VNET_DECLARE(int, tcp_do_autorcvbuf);
VNET_DECLARE(int, tcp_do_autosndbuf);
VNET_DECLARE(int, tcp_do_ecn);
VNET_DECLARE(int, tcp_do_lrd);
VNET_DECLARE(int, tcp_do_prr);
VNET_DECLARE(int, tcp_do_prr_conservative);
VNET_DECLARE(int, tcp_do_newcwv);
VNET_DECLARE(int, tcp_do_rfc1323);
VNET_DECLARE(int, tcp_tolerate_missing_ts);
VNET_DECLARE(int, tcp_do_rfc3042);
VNET_DECLARE(int, tcp_do_rfc3390);
VNET_DECLARE(int, tcp_do_rfc3465);
VNET_DECLARE(int, tcp_do_sack);
VNET_DECLARE(int, tcp_do_tso);
VNET_DECLARE(int, tcp_ecn_maxretries);
VNET_DECLARE(int, tcp_initcwnd_segments);
VNET_DECLARE(int, tcp_insecure_rst);
VNET_DECLARE(int, tcp_insecure_syn);
VNET_DECLARE(int, tcp_insecure_ack);
VNET_DECLARE(uint32_t, tcp_map_entries_limit);
VNET_DECLARE(uint32_t, tcp_map_split_limit);
VNET_DECLARE(int, tcp_minmss);
VNET_DECLARE(int, tcp_mssdflt);
#ifdef STATS
VNET_DECLARE(int, tcp_perconn_stats_dflt_tpl);
VNET_DECLARE(int, tcp_perconn_stats_enable);
#endif
VNET_DECLARE(int, tcp_recvspace);
VNET_DECLARE(int, tcp_retries);
VNET_DECLARE(int, tcp_sack_globalholes);
VNET_DECLARE(int, tcp_sack_globalmaxholes);
VNET_DECLARE(int, tcp_sack_maxholes);
VNET_DECLARE(int, tcp_sack_tso);
VNET_DECLARE(int, tcp_sc_rst_sock_fail);
VNET_DECLARE(int, tcp_sendspace);
VNET_DECLARE(int, tcp_udp_tunneling_overhead);
VNET_DECLARE(int, tcp_udp_tunneling_port);
VNET_DECLARE(struct inpcbinfo, tcbinfo);
#define V_tcp_do_lrd VNET(tcp_do_lrd)
#define V_tcp_do_prr VNET(tcp_do_prr)
#define V_tcp_do_newcwv VNET(tcp_do_newcwv)
#define V_drop_synfin VNET(drop_synfin)
#define V_path_mtu_discovery VNET(path_mtu_discovery)
#define V_tcbinfo VNET(tcbinfo)
#define V_tcp_abc_l_var VNET(tcp_abc_l_var)
#define V_tcp_ack_war_cnt VNET(tcp_ack_war_cnt)
#define V_tcp_ack_war_time_window VNET(tcp_ack_war_time_window)
#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max)
#define V_tcp_autosndbuf_inc VNET(tcp_autosndbuf_inc)
#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max)
#define V_tcp_bind_all_fibs VNET(tcp_bind_all_fibs)
#define V_tcp_delack_enabled VNET(tcp_delack_enabled)
#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf)
#define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf)
#define V_tcp_do_ecn VNET(tcp_do_ecn)
#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323)
#define V_tcp_tolerate_missing_ts VNET(tcp_tolerate_missing_ts)
#define V_tcp_ts_offset_per_conn VNET(tcp_ts_offset_per_conn)
#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042)
#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390)
#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465)
#define V_tcp_do_sack VNET(tcp_do_sack)
#define V_tcp_do_tso VNET(tcp_do_tso)
#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries)
#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments)
#define V_tcp_insecure_rst VNET(tcp_insecure_rst)
#define V_tcp_insecure_syn VNET(tcp_insecure_syn)
#define V_tcp_insecure_ack VNET(tcp_insecure_ack)
#define V_tcp_map_entries_limit VNET(tcp_map_entries_limit)
#define V_tcp_map_split_limit VNET(tcp_map_split_limit)
#define V_tcp_minmss VNET(tcp_minmss)
#define V_tcp_mssdflt VNET(tcp_mssdflt)
#ifdef STATS
#define V_tcp_perconn_stats_dflt_tpl VNET(tcp_perconn_stats_dflt_tpl)
#define V_tcp_perconn_stats_enable VNET(tcp_perconn_stats_enable)
#endif
#define V_tcp_recvspace VNET(tcp_recvspace)
#define V_tcp_retries VNET(tcp_retries)
#define V_tcp_sack_globalholes VNET(tcp_sack_globalholes)
#define V_tcp_sack_globalmaxholes VNET(tcp_sack_globalmaxholes)
#define V_tcp_sack_maxholes VNET(tcp_sack_maxholes)
#define V_tcp_sack_tso VNET(tcp_sack_tso)
#define V_tcp_sc_rst_sock_fail VNET(tcp_sc_rst_sock_fail)
#define V_tcp_sendspace VNET(tcp_sendspace)
#define V_tcp_udp_tunneling_overhead VNET(tcp_udp_tunneling_overhead)
#define V_tcp_udp_tunneling_port VNET(tcp_udp_tunneling_port)
#ifdef TCP_HHOOK
VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]);
#define V_tcp_hhh VNET(tcp_hhh)
#endif
void tcp_account_for_send(struct tcpcb *, uint32_t, uint8_t, uint8_t, bool);
int tcp_addoptions(struct tcpopt *, u_char *);
struct tcpcb *
tcp_close(struct tcpcb *);
void tcp_discardcb(struct tcpcb *);
void tcp_twstart(struct tcpcb *);
int tcp_ctloutput(struct socket *, struct sockopt *);
void tcp_fini(void *);
char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, const void *,
const void *);
char *tcp_log_vain(struct in_conninfo *, struct tcphdr *, const void *,
const void *);
int tcp_reass(struct tcpcb *, struct tcphdr *, tcp_seq *, int *,
struct mbuf *);
void tcp_reass_global_init(void);
void tcp_reass_flush(struct tcpcb *);
void tcp_dooptions(struct tcpopt *, u_char *, int, int);
void tcp_dropwithreset(struct mbuf *, struct tcphdr *, struct tcpcb *, int);
void tcp_pulloutofband(struct socket *,
struct tcphdr *, struct mbuf *, int);
void tcp_xmit_timer(struct tcpcb *, int);
void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *);
void cc_ack_received(struct tcpcb *tp, struct tcphdr *th,
uint16_t nsegs, uint16_t type);
void cc_conn_init(struct tcpcb *tp);
void cc_post_recovery(struct tcpcb *tp, struct tcphdr *th);
void cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos);
void cc_ecnpkt_handler_flags(struct tcpcb *tp, uint16_t flags, uint8_t iptos);
void cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type);
#ifdef TCP_HHOOK
void hhook_run_tcp_est_in(struct tcpcb *tp,
struct tcphdr *th, struct tcpopt *to);
#endif
int tcp_input(struct mbuf **, int *, int);
int tcp_autorcvbuf(struct mbuf *, struct tcphdr *, struct socket *,
struct tcpcb *, int);
int tcp_input_with_port(struct mbuf **, int *, int, uint16_t);
void tcp_do_segment(struct tcpcb *, struct mbuf *, struct tcphdr *, int,
int, uint8_t);
int register_tcp_functions(struct tcp_function_block *blk, int wait);
int register_tcp_functions_as_names(struct tcp_function_block *blk,
int wait, const char *names[], int *num_names);
int register_tcp_functions_as_name(struct tcp_function_block *blk,
const char *name, int wait);
int deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce,
bool force);
struct tcp_function_block *find_and_ref_tcp_functions(struct tcp_function_set *fs);
int find_tcp_function_alias(struct tcp_function_block *blk, struct tcp_function_set *fs);
uint32_t tcp_get_srtt(struct tcpcb *tp, int granularity);
void tcp_switch_back_to_default(struct tcpcb *tp);
struct tcp_function_block *
find_and_ref_tcp_fb(struct tcp_function_block *fs);
int tcp_default_ctloutput(struct tcpcb *tp, struct sockopt *sopt);
int tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt);
void tcp_log_socket_option(struct tcpcb *tp, uint32_t option_num,
uint32_t option_val, int err);
extern counter_u64_t tcp_inp_lro_direct_queue;
extern counter_u64_t tcp_inp_lro_wokeup_queue;
extern counter_u64_t tcp_inp_lro_compressed;
extern counter_u64_t tcp_inp_lro_locks_taken;
extern counter_u64_t tcp_extra_mbuf;
extern counter_u64_t tcp_would_have_but;
extern counter_u64_t tcp_comp_total;
extern counter_u64_t tcp_uncomp_total;
extern counter_u64_t tcp_bad_csums;
extern uint32_t tcp_ack_war_time_window;
extern uint32_t tcp_ack_war_cnt;
struct tcp_ifcap {
int ifcap;
u_int tsomax;
u_int tsomaxsegcount;
u_int tsomaxsegsize;
bool ipsec_tso;
};
uint32_t tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
uint32_t tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
void tcp6_use_min_mtu(struct tcpcb *);
u_int tcp_maxseg(const struct tcpcb *);
u_int tcp_fixed_maxseg(const struct tcpcb *);
void tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *,
struct tcp_ifcap *);
void tcp_mss(struct tcpcb *, int);
int tcp_mssopt(struct in_conninfo *);
struct tcpcb *
tcp_newtcpcb(struct inpcb *, struct tcpcb *);
int tcp_default_output(struct tcpcb *);
void tcp_state_change(struct tcpcb *, int);
void tcp_respond(struct tcpcb *, void *,
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, uint16_t);
bool tcp_challenge_ack_check(sbintime_t *, uint32_t *);
void tcp_send_challenge_ack(struct tcpcb *, struct tcphdr *, struct mbuf *);
bool tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *,
struct mbuf *, int);
void tcp_setpersist(struct tcpcb *);
void tcp_record_dsack(struct tcpcb *tp, tcp_seq start, tcp_seq end, int tlp);
struct tcptemp *
tcpip_maketemplate(struct inpcb *);
void tcpip_fillheaders(struct inpcb *, uint16_t, void *, void *);
void tcp_timer_activate(struct tcpcb *, tt_which, u_int);
bool tcp_timer_active(struct tcpcb *, tt_which);
void tcp_timer_stop(struct tcpcb *);
int inp_to_cpuid(struct inpcb *inp);
void tcp_hc_init(void);
#ifdef VIMAGE
void tcp_hc_destroy(void);
#endif
void tcp_hc_get(const struct in_conninfo *, struct hc_metrics_lite *);
uint32_t tcp_hc_getmtu(const struct in_conninfo *);
void tcp_hc_updatemtu(const struct in_conninfo *, uint32_t);
void tcp_hc_update(const struct in_conninfo *, struct hc_metrics_lite *);
void cc_after_idle(struct tcpcb *tp);
extern struct protosw tcp_protosw;
extern struct protosw tcp6_protosw;
uint32_t tcp_new_ts_offset(struct in_conninfo *);
tcp_seq tcp_new_isn(struct in_conninfo *);
sackstatus_t
tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq);
int tcp_dsack_block_exists(struct tcpcb *);
void tcp_update_dsack_list(struct tcpcb *, tcp_seq, tcp_seq);
void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart,
tcp_seq rcv_lastend);
void tcp_clean_dsack_blocks(struct tcpcb *tp);
void tcp_clean_sackreport(struct tcpcb *tp);
int tcp_sack_adjust(struct tcpcb *tp);
struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
void tcp_do_prr_ack(struct tcpcb *, struct tcphdr *, struct tcpopt *,
sackstatus_t, u_int *);
void tcp_lost_retransmission(struct tcpcb *, struct tcphdr *);
void tcp_sack_partialack(struct tcpcb *, struct tcphdr *, u_int *);
void tcp_resend_sackholes(struct tcpcb *tp);
void tcp_free_sackholes(struct tcpcb *tp);
void tcp_sack_lost_retransmission(struct tcpcb *, struct tcphdr *);
int tcp_newreno(struct tcpcb *, struct tcphdr *);
int tcp_compute_pipe(struct tcpcb *);
uint32_t tcp_compute_initwnd(uint32_t);
void tcp_sndbuf_autoscale(struct tcpcb *, struct socket *, uint32_t);
int tcp_stats_sample_rollthedice(struct tcpcb *tp, void *seed_bytes,
size_t seed_len);
int tcp_can_enable_pacing(void);
int tcp_incr_dgp_pacing_cnt(void);
void tcp_dec_dgp_pacing_cnt(void);
void tcp_decrement_paced_conn(void);
void tcp_change_time_units(struct tcpcb *, int);
void tcp_handle_orphaned_packets(struct tcpcb *);
struct mbuf *
tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen,
int32_t seglimit, int32_t segsize, struct sockbuf *sb, bool hw_tls);
int tcp_stats_init(void);
void tcp_log_end_status(struct tcpcb *tp, uint8_t status);
#ifdef TCP_REQUEST_TRK
void tcp_req_free_a_slot(struct tcpcb *tp, struct tcp_sendfile_track *ent);
struct tcp_sendfile_track *
tcp_req_find_a_req_that_is_completed_by(struct tcpcb *tp, tcp_seq th_ack, int *ip);
int tcp_req_check_for_comp(struct tcpcb *tp, tcp_seq ack_point);
int
tcp_req_is_entry_comp(struct tcpcb *tp, struct tcp_sendfile_track *ent, tcp_seq ack_point);
struct tcp_sendfile_track *
tcp_req_find_req_for_seq(struct tcpcb *tp, tcp_seq seq);
void
tcp_req_log_req_info(struct tcpcb *tp,
struct tcp_sendfile_track *req, uint16_t slot,
uint8_t val, uint64_t offset, uint64_t nbytes);
uint32_t
tcp_estimate_tls_overhead(struct socket *so, uint64_t tls_usr_bytes);
void
tcp_req_alloc_req(struct tcpcb *tp, union tcp_log_userdata *user,
uint64_t ts);
struct tcp_sendfile_track *
tcp_req_alloc_req_full(struct tcpcb *tp, struct tcp_snd_req *req, uint64_t ts, int rec_dups);
#endif
#ifdef TCP_ACCOUNTING
int tcp_do_ack_accounting(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, uint32_t tiwin, int mss);
#endif
static inline void
tcp_lro_features_off(struct tcpcb *tp)
{
tp->t_flags2 &= ~(TF2_SUPPORTS_MBUFQ|
TF2_MBUF_QUEUE_READY|
TF2_DONT_SACK_QUEUE|
TF2_MBUF_ACKCMP|
TF2_MBUF_L_ACKS);
}
static inline void
tcp_fields_to_host(struct tcphdr *th)
{
th->th_seq = ntohl(th->th_seq);
th->th_ack = ntohl(th->th_ack);
th->th_win = ntohs(th->th_win);
th->th_urp = ntohs(th->th_urp);
}
static inline void
tcp_fields_to_net(struct tcphdr *th)
{
th->th_seq = htonl(th->th_seq);
th->th_ack = htonl(th->th_ack);
th->th_win = htons(th->th_win);
th->th_urp = htons(th->th_urp);
}
#endif
#endif