39#include "opt_tcpdebug.h"
40#include "opt_ratelimit.h"
41#include "opt_kern_tls.h"
44#include <sys/module.h>
45#include <sys/kernel.h>
49#include <sys/malloc.h>
53#include <sys/socket.h>
54#include <sys/socketvar.h>
58#include <sys/sysctl.h>
64#include <sys/refcount.h>
67#include <sys/kthread.h>
70#include <sys/tim_filter.h>
73#include <sys/kern_prefetch.h>
77#include <net/ethernet.h>
90#include <netinet6/in6_pcb.h>
91#include <netinet6/ip6_var.h>
109#include <netinet6/tcp6_var.h>
113#include <netipsec/ipsec_support.h>
115#include <net/if_var.h>
117#if defined(IPSEC) || defined(IPSEC_SUPPORT)
118#include <netipsec/ipsec.h>
119#include <netipsec/ipsec6.h>
124#include <machine/in_cksum.h>
127#include <security/mac/mac_framework.h>
137ctf_get_opt_tls_size(
struct socket *so,
uint32_t rwnd)
139 struct ktls_session *tls;
143 tls = so->so_snd.sb_tls_info;
144 len = tls->params.max_frame_len;
145 len += tls->params.tls_hlen;
146 len += tls->params.tls_tlen;
147 if ((len * 4) > rwnd) {
154 if (tls->params.max_frame_len > 4096) {
155 tls->params.max_frame_len -= 4096;
156 if (tls->params.max_frame_len < 4096)
157 tls->params.max_frame_len = 4096;
168 struct ether_header *eh;
173 struct ip *
ip = NULL;
175#if defined(INET) || defined(INET6)
187 return (m->m_pkthdr.lro_etype);
199 if (bpf_peers_present(ifp->if_bpf))
200 ETHER_BPF_MTAP(ifp, m);
202 eh = mtod(m,
struct ether_header *);
203 etype = ntohs(eh->ether_type);
204 m_adj(m,
sizeof(*eh));
209 if (m->m_len < (
sizeof(*ip6) +
sizeof(*th))) {
210 m = m_pullup(m,
sizeof(*ip6) +
sizeof(*th));
216 ip6 = (
struct ip6_hdr *)(eh + 1);
217 th = (
struct tcphdr *)(ip6 + 1);
218 drop_hdrlen =
sizeof(*ip6);
219 tlen = ntohs(ip6->ip6_plen);
220 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) {
221 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
222 th->th_sum = m->m_pkthdr.csum_data;
224 th->th_sum = in6_cksum_pseudo(ip6, tlen,
226 m->m_pkthdr.csum_data);
227 th->th_sum ^= 0xffff;
229 th->th_sum = in6_cksum(m,
IPPROTO_TCP, drop_hdrlen, tlen);
241 if (m->m_len < sizeof (
struct tcpiphdr)) {
242 m = m_pullup(m,
sizeof (
struct tcpiphdr));
248 ip = (
struct ip *)(eh + 1);
249 th = (
struct tcphdr *)(
ip + 1);
250 drop_hdrlen =
sizeof(*ip);
253 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
254 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
255 th->th_sum = m->m_pkthdr.csum_data;
259 htonl(m->m_pkthdr.csum_data + tlen +
IPPROTO_TCP));
260 th->th_sum ^= 0xffff;
267 len = drop_hdrlen + tlen;
269 ipov->
ih_len = htons(tlen);
270 th->th_sum = in_cksum(m, len);
395 struct ip *
ip = NULL;
400 int32_t retval, nxt_pkt, tlen, off;
418 CURVNET_SET(ifp->if_vnet);
422 m_save = m->m_nextpkt;
431 KASSERT(((etype == ETHERTYPE_IPV6) || (etype == ETHERTYPE_IP)),
432 (
"tp:%p m:%p etype:0x%x -- not IP or IPv6", tp, m, etype));
437 ip6 = mtod(m,
struct ip6_hdr *);
438 th = (
struct tcphdr *)(ip6 + 1);
439 tlen = ntohs(ip6->ip6_plen);
440 drop_hdrlen =
sizeof(*ip6);
441 iptos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
446 ip = mtod(m,
struct ip *);
447 th = (
struct tcphdr *)(
ip + 1);
448 drop_hdrlen =
sizeof(*ip);
458 off = th->th_off << 2;
459 if (off <
sizeof (
struct tcphdr) || off > tlen) {
460 printf(
"off:%d < hdrlen:%zu || > tlen:%u -- dump\n",
462 sizeof(
struct tcphdr),
474 m->m_pkthdr.lro_nsegs = 1;
483 (
"tp:%p inp:%p no INP_MBUF_ACKCMP flags?", tp, tp->
t_inpcb));
490 if (m_save || has_pkt)
501 iptos, nxt_pkt, &tv);
506 m_save = m->m_nextpkt;
569 int32_t rstreason, int32_t tlen)
581 if ((ts != NULL) && (cnt != NULL) &&
616 struct tcpcb *tp, int32_t *tlenp,
617 int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val,
626 todrop = tp->
rcv_nxt - th->th_seq;
628 if (thflags & TH_SYN) {
641 || (todrop == tlen && (thflags & TH_FIN) == 0)) {
671 th->th_seq + todrop);
673 *drop_hdrlen += todrop;
674 th->th_seq += todrop;
676 if (th->th_urp > todrop)
677 th->th_urp -= todrop;
690 if (todrop >= tlen) {
710 thflags &= ~(TH_PUSH | TH_FIN);
786 (
"%s: TH_RST for TCPS_SYN_SENT th %p tp %p",
796 so->so_error = ECONNREFUSED;
804 so->so_error = ECONNRESET;
818 if ((ts != NULL) && (cnt != NULL) &&
843 if (send_challenge) {
895 int32_t tlen, int32_t thflags, int32_t * ret_val)
961 win = sbspace(&so->so_rcv);
969 int32_t rstreason, int32_t tlen)
991 memset(&log, 0,
sizeof(log));
994 if (num_sack_blks > 0) {
998 if (num_sack_blks > 1) {
1002 if (num_sack_blks > 2) {
1006 if (num_sack_blks > 3) {
1014 0, &log,
false, &tv);
1026 uint64_t perc_count, decay_per;
1034 perc_count *= decay_per;
1041 return(decayed_count);
#define BANDLIM_RST_OPENPORT
u_short in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
#define INP_WLOCK_ASSERT(inp)
#define INP_UNLOCK_ASSERT(inp)
int __ctf_process_rst(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, uint32_t *ts, uint32_t *cnt)
uint32_t ctf_decay_count(uint32_t count, uint32_t decay)
int32_t ctf_progress_timeout_check(struct tcpcb *tp, bool log)
int ctf_do_queued_segments(struct socket *so, struct tcpcb *tp, int have_pkt)
void ctf_log_sack_filter(struct tcpcb *tp, int num_sack_blks, struct sackblk *sack_blocks)
void ctf_ack_war_checks(struct tcpcb *tp, uint32_t *ts, uint32_t *cnt)
static int ctf_get_enet_type(struct ifnet *ifp, struct mbuf *m)
int ctf_ts_check_ac(struct tcpcb *tp, int32_t thflags)
void ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t rstreason, int32_t tlen)
void ctf_do_drop(struct mbuf *m, struct tcpcb *tp)
void ctf_challenge_ack(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t *ret_val)
int _ctf_drop_checks(struct tcpopt *to, struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t *tlenp, int32_t *thf, int32_t *drop_hdrlen, int32_t *ret_val, uint32_t *ts, uint32_t *cnt)
uint32_t ctf_outstanding(struct tcpcb *tp)
uint32_t ctf_fixed_maxseg(struct tcpcb *tp)
uint32_t ctf_flight_size(struct tcpcb *tp, uint32_t rc_sacked)
void __ctf_do_dropafterack(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t thflags, int32_t tlen, int32_t *ret_val, uint32_t *ts, uint32_t *cnt)
int ctf_process_inbound_raw(struct tcpcb *tp, struct socket *so, struct mbuf *m, int has_pkt)
int ctf_ts_check(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t tlen, int32_t thflags, int32_t *ret_val)
void ctf_calc_rwin(struct socket *so, struct tcpcb *tp)
void ctf_do_dropwithreset_conn(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t rstreason, int32_t tlen)
#define ctf_do_dropafterack(a, b, c, d, e, f)
struct socket * inp_socket
struct in_addr ip_src ip_dst
int(* tfb_do_segment_nounlock)(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, int, int, uint8_t, int, struct timeval *)
struct tcp_function_block * t_fb
#define TCPS_SYN_RECEIVED
static __inline uint32_t tcp_get_usecs(struct timeval *tv)
#define TCP_LOG_EVENTP(tp, th, rxbuf, txbuf, eventid, errornum, len, stackinfo, th_hostorder, tv)
void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end)
static __inline uint32_t tcp_ts_getticks(void)
struct tcpcb * tcp_drop(struct tcpcb *tp, int errno)
void tcp_state_change(struct tcpcb *tp, int newstate)
struct tcpcb * tcp_close(struct tcpcb *tp)
void tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags)
u_int tcp_fixed_maxseg(const struct tcpcb *tp)
void tcp_log_end_status(struct tcpcb *tp, uint8_t status)
uint32_t tcp_ack_war_time_window
#define TCP_EI_STATUS_CLIENT_RST
#define V_tcp_insecure_rst
static void tcp_fields_to_host(struct tcphdr *th)
#define V_tcp_insecure_syn
#define KMOD_TCPSTAT_INC(name)
#define TCP_EI_STATUS_PROGRESS
#define KMOD_TCPSTAT_ADD(name, val)