Skip to content

Commit

Permalink
Greatly reduce the number of #ifdefs supporting the TCP_RFC7413 kerne…
Browse files Browse the repository at this point in the history
…l option.

The conditional compilation support is now centralized in
tcp_fastopen.h and tcp_var.h. This doesn't provide the minimum
theoretical code/data footprint when TCP_RFC7413 is disabled, but
nearly all the TFO code should wind up being removed by the optimizer,
the additional footprint in the syncache entries is a single pointer,
and the additional overhead in the tcpcb is at the end of the
structure.

This enables the TCP_RFC7413 kernel option by default in amd64 and
arm64 GENERIC.

Reviewed by:	hiren
MFC after:	1 month
Sponsored by:	Limelight Networks
Differential Revision:	https://reviews.freebsd.org/D14048
  • Loading branch information
pkelsey committed Feb 26, 2018
1 parent d2557e9 commit 91dbc8d
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 101 deletions.
1 change: 1 addition & 0 deletions sys/amd64/conf/GENERIC
Expand Up @@ -33,6 +33,7 @@ options IPSEC # IP (v4/v6) security
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
Expand Down
1 change: 1 addition & 0 deletions sys/arm64/conf/GENERIC
Expand Up @@ -33,6 +33,7 @@ options IPSEC # IP (v4/v6) security
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
Expand Down
19 changes: 19 additions & 0 deletions sys/netinet/tcp_fastopen.h
Expand Up @@ -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;
Expand Down Expand Up @@ -74,6 +81,7 @@ struct tcp_fastopen_ccache {
uint32_t secret;
};

#ifdef TCP_RFC7413
void tcp_fastopen_init(void);
void tcp_fastopen_destroy(void);
unsigned int *tcp_fastopen_alloc_counter(void);
Expand All @@ -84,6 +92,17 @@ void tcp_fastopen_connect(struct tcpcb *);
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_ */
30 changes: 2 additions & 28 deletions sys/netinet/tcp_input.c
Expand Up @@ -108,9 +108,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/tcp6_var.h>
#include <netinet/tcpip.h>
#include <netinet/cc/cc.h>
#ifdef TCP_RFC7413
#include <netinet/tcp_fastopen.h>
#endif
#ifdef TCPPCAP
#include <netinet/tcp_pcap.h>
#endif
Expand Down Expand Up @@ -1130,9 +1128,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
rstreason = BANDLIM_RST_OPENPORT;
goto dropwithreset;
}
#ifdef TCP_RFC7413
tfo_socket_result:
#endif
if (so == NULL) {
/*
* We completed the 3-way handshake
Expand Down Expand Up @@ -1375,12 +1371,9 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
#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().
Expand Down Expand Up @@ -1550,9 +1543,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
struct in_conninfo *inc;
struct mbuf *mfree;
struct tcpopt to;
#ifdef TCP_RFC7413
int tfo_syn;
#endif

#ifdef TCPDEBUG
/*
Expand Down Expand Up @@ -1717,15 +1708,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
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,
to.to_tfo_len, to.to_tfo_cookie);
else
tcp_fastopen_disable_path(tp);
}
#endif
}

/*
Expand Down Expand Up @@ -1983,7 +1972,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
rstreason = BANDLIM_RST_OPENPORT;
goto dropwithreset;
}
#ifdef TCP_RFC7413
if (IS_FASTOPEN(tp->t_flags)) {
/*
* When a TFO connection is in SYN_RECEIVED, the
Expand All @@ -2004,7 +1992,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
goto drop;
}
}
#endif
break;

/*
Expand Down Expand Up @@ -2423,13 +2410,11 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
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;
Expand Down Expand Up @@ -2470,8 +2455,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
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;

Expand All @@ -2489,7 +2473,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* is retransmitted.
*/
if (!IS_FASTOPEN(tp->t_flags))
#endif
cc_conn_init(tp);
tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp));
}
Expand Down Expand Up @@ -3055,12 +3038,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* 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;
Expand Down Expand Up @@ -3284,9 +3263,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (tp != NULL)
INP_WUNLOCK(tp->t_inpcb);
m_freem(m);
#ifndef TCP_RFC7413
#undef tfo_syn
#endif
}

/*
Expand Down Expand Up @@ -3440,7 +3416,6 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
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
Expand All @@ -3456,7 +3431,6 @@ tcp_dooptions(struct tcpopt *to, u_char *cp, int cnt, int flags)
to->to_tfo_len = optlen - 2;
to->to_tfo_cookie = to->to_tfo_len ? cp + 2 : NULL;
break;
#endif
default:
continue;
}
Expand Down
20 changes: 2 additions & 18 deletions sys/netinet/tcp_output.c
Expand Up @@ -79,9 +79,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_var.h>
#include <netinet/tcpip.h>
#include <netinet/cc/cc.h>
#ifdef TCP_RFC7413
#include <netinet/tcp_fastopen.h>
#endif
#ifdef TCPPCAP
#include <netinet/tcp_pcap.h>
#endif
Expand Down Expand Up @@ -212,10 +210,8 @@ tcp_output(struct tcpcb *tp)
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
Expand All @@ -233,7 +229,6 @@ tcp_output(struct tcpcb *tp)
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.
Expand All @@ -243,7 +238,7 @@ tcp_output(struct tcpcb *tp)
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.
Expand Down Expand Up @@ -429,15 +424,13 @@ tcp_output(struct tcpcb *tp)
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.
*/
if (IS_FASTOPEN(tp->t_flags) &&
(tp->t_state == TCPS_SYN_RECEIVED))
flags &= ~TH_SYN;
#endif
off--, len++;
}

Expand All @@ -451,7 +444,6 @@ tcp_output(struct tcpcb *tp)
flags &= ~TH_FIN;
}

#ifdef TCP_RFC7413
/*
* On TFO sockets, ensure no data is sent in the following cases:
*
Expand All @@ -470,7 +462,6 @@ tcp_output(struct tcpcb *tp)
(tp->t_tfo_client_cookie_len == 0)) ||
(flags & TH_RST)))
len = 0;
#endif
if (len <= 0) {
/*
* If FIN has been sent but not acked,
Expand Down Expand Up @@ -774,7 +765,7 @@ tcp_output(struct tcpcb *tp)
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
Expand Down Expand Up @@ -807,7 +798,6 @@ tcp_output(struct tcpcb *tp)
dont_sendalot = 1;
}
}
#endif
}
/* Window scaling. */
if ((flags & TH_SYN) && (tp->t_flags & TF_REQ_SCALE)) {
Expand Down Expand Up @@ -851,15 +841,13 @@ tcp_output(struct tcpcb *tp)

/* 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.
*/
if (IS_FASTOPEN(tp->t_flags) && wanted_cookie &&
!(to.to_flags & TOF_FASTOPEN))
len = 0;
#endif
}

/*
Expand Down Expand Up @@ -1004,10 +992,8 @@ tcp_output(struct tcpcb *tp)
} else {
len = tp->t_maxseg - optlen - ipoptlen;
sendalot = 1;
#ifdef TCP_RFC7413
if (dont_sendalot)
sendalot = 0;
#endif
}
} else
tso = 0;
Expand Down Expand Up @@ -1811,7 +1797,6 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
TCPSTAT_INC(tcps_sack_send_blocks);
break;
}
#ifdef TCP_RFC7413
case TOF_FASTOPEN:
{
int total_len;
Expand All @@ -1831,7 +1816,6 @@ tcp_addoptions(struct tcpopt *to, u_char *optp)
optlen += total_len;
break;
}
#endif
default:
panic("%s: unknown TCP option type", __func__);
break;
Expand Down

0 comments on commit 91dbc8d

Please sign in to comment.