Index: head/sys/amd64/conf/GENERIC =================================================================== --- head/sys/amd64/conf/GENERIC +++ head/sys/amd64/conf/GENERIC @@ -33,6 +33,7 @@ options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_OFFLOAD # TCP offload options TCP_HHOOK # hhook(9) framework for TCP +options TCP_RFC7413 # TCP Fast Open options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support Index: head/sys/arm64/conf/GENERIC =================================================================== --- head/sys/arm64/conf/GENERIC +++ head/sys/arm64/conf/GENERIC @@ -33,6 +33,7 @@ options IPSEC_SUPPORT # Allow kldload of ipsec and tcpmd5 options TCP_HHOOK # hhook(9) framework for TCP options TCP_OFFLOAD # TCP offload +options TCP_RFC7413 # TCP Fast Open options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support Index: head/sys/netinet/tcp_fastopen.h =================================================================== --- head/sys/netinet/tcp_fastopen.h +++ head/sys/netinet/tcp_fastopen.h @@ -31,13 +31,20 @@ #ifdef _KERNEL +#include "opt_inet.h" + #define TCP_FASTOPEN_COOKIE_LEN 8 /* SipHash24 64-bit output */ +#ifdef TCP_RFC7413 VNET_DECLARE(unsigned int, tcp_fastopen_client_enable); #define V_tcp_fastopen_client_enable VNET(tcp_fastopen_client_enable) VNET_DECLARE(unsigned int, tcp_fastopen_server_enable); #define V_tcp_fastopen_server_enable VNET(tcp_fastopen_server_enable) +#else +#define V_tcp_fastopen_client_enable 0 +#define V_tcp_fastopen_server_enable 0 +#endif /* TCP_RFC7413 */ union tcp_fastopen_ip_addr { struct in_addr v4; @@ -74,6 +81,7 @@ uint32_t secret; }; +#ifdef TCP_RFC7413 void tcp_fastopen_init(void); void tcp_fastopen_destroy(void); unsigned int *tcp_fastopen_alloc_counter(void); @@ -84,6 +92,17 @@ void tcp_fastopen_disable_path(struct tcpcb *); void tcp_fastopen_update_cache(struct tcpcb *, uint16_t, uint8_t, uint8_t *); +#else +#define tcp_fastopen_init() ((void)0) +#define tcp_fastopen_destroy() ((void)0) +#define tcp_fastopen_alloc_counter() NULL +#define tcp_fastopen_decrement_counter(c) ((void)0) +#define tcp_fastopen_check_cookie(i, c, l, lc) (-1) +#define tcp_fastopen_connect(t) ((void)0) +#define tcp_fastopen_disable_path(t) ((void)0) +#define tcp_fastopen_update_cache(t, m, l, c) ((void)0) +#endif /* TCP_RFC7413 */ + #endif /* _KERNEL */ #endif /* _TCP_FASTOPEN_H_ */ Index: head/sys/netinet/tcp_input.c =================================================================== --- head/sys/netinet/tcp_input.c +++ head/sys/netinet/tcp_input.c @@ -108,9 +108,7 @@ #include #include #include -#ifdef TCP_RFC7413 #include -#endif #ifdef TCPPCAP #include #endif @@ -1130,9 +1128,7 @@ rstreason = BANDLIM_RST_OPENPORT; goto dropwithreset; } -#ifdef TCP_RFC7413 tfo_socket_result: -#endif if (so == NULL) { /* * We completed the 3-way handshake @@ -1375,12 +1371,9 @@ #endif TCP_PROBE3(debug__input, tp, th, m); tcp_dooptions(&to, optp, optlen, TO_SYN); -#ifdef TCP_RFC7413 if (syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL)) goto tfo_socket_result; -#else - syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL); -#endif + /* * Entry added to syncache and mbuf consumed. * Only the listen socket is unlocked by syncache_add(). @@ -1550,9 +1543,7 @@ struct in_conninfo *inc; struct mbuf *mfree; struct tcpopt to; -#ifdef TCP_RFC7413 int tfo_syn; -#endif #ifdef TCPDEBUG /* @@ -1717,7 +1708,6 @@ if ((tp->t_flags & TF_SACK_PERMIT) && (to.to_flags & TOF_SACKPERM) == 0) tp->t_flags &= ~TF_SACK_PERMIT; -#ifdef TCP_RFC7413 if (IS_FASTOPEN(tp->t_flags)) { if (to.to_flags & TOF_FASTOPEN) tcp_fastopen_update_cache(tp, to.to_mss, @@ -1725,7 +1715,6 @@ else tcp_fastopen_disable_path(tp); } -#endif } /* @@ -1983,7 +1972,6 @@ rstreason = BANDLIM_RST_OPENPORT; goto dropwithreset; } -#ifdef TCP_RFC7413 if (IS_FASTOPEN(tp->t_flags)) { /* * When a TFO connection is in SYN_RECEIVED, the @@ -2004,7 +1992,6 @@ goto drop; } } -#endif break; /* @@ -2423,13 +2410,11 @@ if ((thflags & TH_ACK) == 0) { if (tp->t_state == TCPS_SYN_RECEIVED || (tp->t_flags & TF_NEEDSYN)) { -#ifdef TCP_RFC7413 if (tp->t_state == TCPS_SYN_RECEIVED && IS_FASTOPEN(tp->t_flags)) { tp->snd_wnd = tiwin; cc_conn_init(tp); } -#endif goto step6; } else if (tp->t_flags & TF_ACKNOW) goto dropafterack; @@ -2470,8 +2455,7 @@ tcp_state_change(tp, TCPS_ESTABLISHED); TCP_PROBE5(accept__established, NULL, tp, m, tp, th); -#ifdef TCP_RFC7413 - if (tp->t_tfo_pending) { + if (IS_FASTOPEN(tp->t_flags) && tp->t_tfo_pending) { tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; @@ -2489,7 +2473,6 @@ * is retransmitted. */ if (!IS_FASTOPEN(tp->t_flags)) -#endif cc_conn_init(tp); tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); } @@ -3055,12 +3038,8 @@ * case PRU_RCVD). If a FIN has already been received on this * connection then we just ignore the text. */ -#ifdef TCP_RFC7413 tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && IS_FASTOPEN(tp->t_flags)); -#else -#define tfo_syn (false) -#endif if ((tlen || (thflags & TH_FIN) || tfo_syn) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { tcp_seq save_start = th->th_seq; @@ -3284,9 +3263,6 @@ if (tp != NULL) INP_WUNLOCK(tp->t_inpcb); m_freem(m); -#ifndef TCP_RFC7413 -#undef tfo_syn -#endif } /* @@ -3440,7 +3416,6 @@ to->to_sacks = cp + 2; TCPSTAT_INC(tcps_sack_rcv_blocks); break; -#ifdef TCP_RFC7413 case TCPOPT_FAST_OPEN: /* * Cookie length validation is performed by the @@ -3456,7 +3431,6 @@ to->to_tfo_len = optlen - 2; to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL; break; -#endif default: continue; } Index: head/sys/netinet/tcp_output.c =================================================================== --- head/sys/netinet/tcp_output.c +++ head/sys/netinet/tcp_output.c @@ -79,9 +79,7 @@ #include #include #include -#ifdef TCP_RFC7413 #include -#endif #ifdef TCPPCAP #include #endif @@ -212,10 +210,8 @@ struct sackhole *p; int tso, mtu; struct tcpopt to; -#ifdef TCP_RFC7413 unsigned int wanted_cookie = 0; unsigned int dont_sendalot = 0; -#endif #if 0 int maxburst = TCP_MAXBURST; #endif @@ -233,7 +229,6 @@ return (tcp_offload_output(tp)); #endif -#ifdef TCP_RFC7413 /* * For TFO connections in SYN_RECEIVED, only allow the initial * SYN|ACK and those sent by the retransmit timer. @@ -243,7 +238,7 @@ SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN|ACK sent */ (tp->snd_nxt != tp->snd_una)) /* not a retransmit */ return (0); -#endif + /* * Determine length of data that should be transmitted, * and flags that will be used. @@ -429,7 +424,6 @@ if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) { if (tp->t_state != TCPS_SYN_RECEIVED) flags &= ~TH_SYN; -#ifdef TCP_RFC7413 /* * When sending additional segments following a TFO SYN|ACK, * do not include the SYN bit. @@ -437,7 +431,6 @@ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) flags &= ~TH_SYN; -#endif off--, len++; } @@ -451,7 +444,6 @@ flags &= ~TH_FIN; } -#ifdef TCP_RFC7413 /* * On TFO sockets, ensure no data is sent in the following cases: * @@ -470,7 +462,6 @@ (tp->t_tfo_client_cookie_len == 0)) || (flags & TH_RST))) len = 0; -#endif if (len <= 0) { /* * If FIN has been sent but not acked, @@ -774,7 +765,7 @@ tp->snd_nxt = tp->iss; to.to_mss = tcp_mssopt(&tp->t_inpcb->inp_inc); to.to_flags |= TOF_MSS; -#ifdef TCP_RFC7413 + /* * On SYN or SYN|ACK transmits on TFO connections, * only include the TFO option if it is not a @@ -807,7 +798,6 @@ dont_sendalot = 1; } } -#endif } /* Window scaling. */ if ((flags & TH_SYN) && (tp->t_flags & TF_REQ_SCALE)) { @@ -851,7 +841,6 @@ /* Processing the options. */ hdrlen += optlen = tcp_addoptions(&to, opt); -#ifdef TCP_RFC7413 /* * If we wanted a TFO option to be added, but it was unable * to fit, ensure no data is sent. @@ -859,7 +848,6 @@ if (IS_FASTOPEN(tp->t_flags) && wanted_cookie && !(to.to_flags & TOF_FASTOPEN)) len = 0; -#endif } /* @@ -1004,10 +992,8 @@ } else { len = tp->t_maxseg - optlen - ipoptlen; sendalot = 1; -#ifdef TCP_RFC7413 if (dont_sendalot) sendalot = 0; -#endif } } else tso = 0; @@ -1811,7 +1797,6 @@ TCPSTAT_INC(tcps_sack_send_blocks); break; } -#ifdef TCP_RFC7413 case TOF_FASTOPEN: { int total_len; @@ -1831,7 +1816,6 @@ optlen += total_len; break; } -#endif default: panic("%s: unknown TCP option type", __func__); break; Index: head/sys/netinet/tcp_subr.c =================================================================== --- head/sys/netinet/tcp_subr.c +++ head/sys/netinet/tcp_subr.c @@ -104,9 +104,7 @@ #include #endif #include -#ifdef TCP_RFC7413 #include -#endif #ifdef TCPPCAP #include #endif @@ -755,9 +753,7 @@ V_sack_hole_zone = uma_zcreate("sackhole", sizeof(struct sackhole), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); -#ifdef TCP_RFC7413 tcp_fastopen_init(); -#endif /* Skip initialization of globals for non-default instances. */ if (!IS_DEFAULT_VNET(curvnet)) @@ -844,13 +840,11 @@ uma_zdestroy(V_sack_hole_zone); uma_zdestroy(V_tcpcb_zone); -#ifdef TCP_RFC7413 /* * Cannot free the zone until all tcpcbs are released as we attach * the allocations to them. */ tcp_fastopen_destroy(); -#endif #ifdef TCP_HHOOK error = hhook_head_deregister(V_tcp_hhh[HHOOK_TCP_EST_IN]); @@ -1647,7 +1641,6 @@ if (tp->t_state == TCPS_LISTEN) tcp_offload_listen_stop(tp); #endif -#ifdef TCP_RFC7413 /* * This releases the TFO pending counter resource for TFO listen * sockets as well as passively-created TFO sockets that transition @@ -1657,7 +1650,6 @@ tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; } -#endif in_pcbdrop(inp); TCPSTAT_INC(tcps_closed); if (tp->t_state != TCPS_CLOSED) @@ -2407,10 +2399,8 @@ if (tp->t_state != TCPS_SYN_SENT) return (inp); -#ifdef TCP_RFC7413 if (IS_FASTOPEN(tp->t_flags)) tcp_fastopen_disable_path(tp); -#endif tp = tcp_drop(tp, errno); if (tp != NULL) Index: head/sys/netinet/tcp_syncache.h =================================================================== --- head/sys/netinet/tcp_syncache.h +++ head/sys/netinet/tcp_syncache.h @@ -75,9 +75,7 @@ #endif struct label *sc_label; /* MAC label reference */ struct ucred *sc_cred; /* cred cache for jail checks */ -#ifdef TCP_RFC7413 void *sc_tfo_cookie; /* for TCP Fast Open response */ -#endif void *sc_pspare; /* TCP_SIGNATURE */ u_int32_t sc_spare[2]; /* UTO */ }; Index: head/sys/netinet/tcp_syncache.c =================================================================== --- head/sys/netinet/tcp_syncache.c +++ head/sys/netinet/tcp_syncache.c @@ -83,9 +83,7 @@ #include #endif #include -#ifdef TCP_RFC7413 #include -#endif #include #include #include @@ -1176,7 +1174,6 @@ return (0); } -#ifdef TCP_RFC7413 static void syncache_tfo_expand(struct syncache *sc, struct socket **lsop, struct mbuf *m, uint64_t response_cookie) @@ -1208,7 +1205,6 @@ TCPSTAT_INC(tcps_sc_completed); } } -#endif /* TCP_RFC7413 */ /* * Given a LISTEN socket and an inbound SYN request, add @@ -1251,12 +1247,10 @@ #endif struct syncache scs; struct ucred *cred; -#ifdef TCP_RFC7413 uint64_t tfo_response_cookie; unsigned int *tfo_pending = NULL; int tfo_cookie_valid = 0; int tfo_response_cookie_valid = 0; -#endif INP_WLOCK_ASSERT(inp); /* listen socket */ KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN, @@ -1281,7 +1275,6 @@ win = so->sol_sbrcv_hiwat; ltflags = (tp->t_flags & (TF_NOOPT | TF_SIGNATURE)); -#ifdef TCP_RFC7413 if (V_tcp_fastopen_server_enable && IS_FASTOPEN(tp->t_flags) && (tp->t_tfo_pending != NULL) && (to->to_flags & TOF_FASTOPEN)) { @@ -1308,7 +1301,6 @@ */ tfo_pending = tp->t_tfo_pending; } -#endif /* By the time we drop the lock these should no longer be used. */ so = NULL; @@ -1321,9 +1313,7 @@ } else mac_syncache_create(maclabel, inp); #endif -#ifdef TCP_RFC7413 if (!tfo_cookie_valid) -#endif INP_WUNLOCK(inp); /* @@ -1369,10 +1359,8 @@ sc = syncache_lookup(inc, &sch); /* returns locked entry */ SCH_LOCK_ASSERT(sch); if (sc != NULL) { -#ifdef TCP_RFC7413 if (tfo_cookie_valid) INP_WUNLOCK(inp); -#endif TCPSTAT_INC(tcps_sc_dupsyn); if (ipopts) { /* @@ -1415,13 +1403,11 @@ goto done; } -#ifdef TCP_RFC7413 if (tfo_cookie_valid) { bzero(&scs, sizeof(scs)); sc = &scs; goto skip_alloc; } -#endif sc = uma_zalloc(V_tcp_syncache.zone, M_NOWAIT | M_ZERO); if (sc == NULL) { @@ -1449,11 +1435,9 @@ } } -#ifdef TCP_RFC7413 skip_alloc: if (!tfo_cookie_valid && tfo_response_cookie_valid) sc->sc_tfo_cookie = &tfo_response_cookie; -#endif /* * Fill in the syncache values. @@ -1562,14 +1546,12 @@ #endif SCH_UNLOCK(sch); -#ifdef TCP_RFC7413 if (tfo_cookie_valid) { syncache_tfo_expand(sc, lsop, m, tfo_response_cookie); /* INP_WUNLOCK(inp) will be performed by the caller */ rv = 1; goto tfo_expanded; } -#endif /* * Do a standard 3-way handshake. @@ -1592,7 +1574,6 @@ *lsop = NULL; m_freem(m); } -#ifdef TCP_RFC7413 /* * If tfo_pending is not NULL here, then a TFO SYN that did not * result in a new socket was processed and the associated pending @@ -1603,7 +1584,6 @@ tcp_fastopen_decrement_counter(tfo_pending); tfo_expanded: -#endif if (cred != NULL) crfree(cred); #ifdef MAC @@ -1740,7 +1720,6 @@ if (sc->sc_flags & SCF_SIGNATURE) to.to_flags |= TOF_SIGNATURE; #endif -#ifdef TCP_RFC7413 if (sc->sc_tfo_cookie) { to.to_flags |= TOF_FASTOPEN; to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN; @@ -1748,7 +1727,6 @@ /* don't send cookie again when retransmitting response */ sc->sc_tfo_cookie = NULL; } -#endif optlen = tcp_addoptions(&to, (u_char *)(th + 1)); /* Adjust headers by option size. */ Index: head/sys/netinet/tcp_usrreq.c =================================================================== --- head/sys/netinet/tcp_usrreq.c +++ head/sys/netinet/tcp_usrreq.c @@ -92,9 +92,7 @@ #include #include #include -#ifdef TCP_RFC7413 #include -#endif #ifdef TCPPCAP #include #endif @@ -430,10 +428,9 @@ } SOCK_UNLOCK(so); -#ifdef TCP_RFC7413 if (IS_FASTOPEN(tp->t_flags)) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); -#endif + out: TCPDEBUG2(PRU_LISTEN); TCP_PROBE2(debug__user, tp, PRU_LISTEN); @@ -480,10 +477,9 @@ } SOCK_UNLOCK(so); -#ifdef TCP_RFC7413 if (IS_FASTOPEN(tp->t_flags)) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); -#endif + out: TCPDEBUG2(PRU_LISTEN); TCP_PROBE2(debug__user, tp, PRU_LISTEN); @@ -848,7 +844,6 @@ } tp = intotcpcb(inp); TCPDEBUG1(); -#ifdef TCP_RFC7413 /* * For passively-created TFO connections, don't attempt a window * update while still in SYN_RECEIVED as this may trigger an early @@ -859,7 +854,6 @@ if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) goto out; -#endif #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) tcp_offload_rcvd(tp); @@ -950,12 +944,9 @@ #endif if (error) goto out; -#ifdef TCP_RFC7413 if (IS_FASTOPEN(tp->t_flags)) tcp_fastopen_connect(tp); - else -#endif - { + else { tp->snd_wnd = TTCP_CLIENT_SND_WND; tcp_mss(tp, -1); } @@ -1004,13 +995,12 @@ * initialize window to default value, and * initialize maxseg using peer's cached MSS. */ -#ifdef TCP_RFC7413 + /* * Not going to contemplate SYN|URG */ if (IS_FASTOPEN(tp->t_flags)) tp->t_flags &= ~TF_FASTOPEN; -#endif #ifdef INET6 if (isipv6) error = tcp6_connect(tp, nam, td); @@ -1782,7 +1772,6 @@ goto unlock_and_done; #endif -#ifdef TCP_RFC7413 case TCP_FASTOPEN: { struct tcp_fastopen tfo_optval; @@ -1829,7 +1818,6 @@ tp->t_flags &= ~TF_FASTOPEN; goto unlock_and_done; } -#endif default: INP_WUNLOCK(inp); @@ -1911,14 +1899,11 @@ error = sooptcopyout(sopt, &optval, sizeof optval); break; #endif - -#ifdef TCP_RFC7413 case TCP_FASTOPEN: optval = tp->t_flags & TF_FASTOPEN; INP_WUNLOCK(inp); error = sooptcopyout(sopt, &optval, sizeof optval); break; -#endif default: INP_WUNLOCK(inp); error = ENOPROTOOPT; Index: head/sys/netinet/tcp_var.h =================================================================== --- head/sys/netinet/tcp_var.h +++ head/sys/netinet/tcp_var.h @@ -191,14 +191,12 @@ u_int t_flags2; /* More tcpcb flags storage */ struct tcp_function_block *t_fb;/* TCP function call block */ void *t_fb_ptr; /* Pointer to t_fb specific data */ -#ifdef TCP_RFC7413 uint8_t t_tfo_client_cookie_len; /* TCP Fast Open client cookie length */ unsigned int *t_tfo_pending; /* TCP Fast Open server pending counter */ union { uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN]; uint64_t server; } t_tfo_cookie; /* TCP Fast Open cookie to send */ -#endif #ifdef TCPPCAP struct mbufq t_inpkts; /* List of saved input packets. */ struct mbufq t_outpkts; /* List of saved output packets. */