aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_stacks/bbr.c
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2021-05-22 12:35:09 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2021-06-09 00:09:37 +0000
commit6264ff9bd9f0f01f052b9b100af12e53613a825c (patch)
treebc53e7e5bc02dfc6a17ddd6d638e464405a57922 /sys/netinet/tcp_stacks/bbr.c
parent56aeedd2fda4e1a714812a1fbdc9e8a784283d94 (diff)
downloadsrc-6264ff9bd9f0f01f052b9b100af12e53613a825c.tar.gz
src-6264ff9bd9f0f01f052b9b100af12e53613a825c.zip
tcp: Handle stack switch while processing socket options
Handle the case where during socket option processing, the user switches a stack such that processing the stack specific socket option does not make sense anymore. Return an error in this case. Reviewed by: markj Reported by: syzbot+a6e1d91f240ad5d72cd1@syzkaller.appspotmail.com Sponsored by: Netflix, Inc. Differential revision: https://reviews.freebsd.org/D30395 (cherry picked from commit 8923ce630492d21ec57c2637757bcc44da9970f8)
Diffstat (limited to 'sys/netinet/tcp_stacks/bbr.c')
-rw-r--r--sys/netinet/tcp_stacks/bbr.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c
index abc0536d47c7..2a98f5cb43ef 100644
--- a/sys/netinet/tcp_stacks/bbr.c
+++ b/sys/netinet/tcp_stacks/bbr.c
@@ -518,6 +518,10 @@ static void
bbr_log_pacing_delay_calc(struct tcp_bbr *bbr, uint16_t gain, uint32_t len,
uint32_t cts, uint32_t usecs, uint64_t bw, uint32_t override, int mod);
+static int
+bbr_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp,
+ struct tcpcb *tp);
+
static inline uint8_t
bbr_state_val(struct tcp_bbr *bbr)
{
@@ -14197,6 +14201,33 @@ bbr_mtu_chg(struct tcpcb *tp)
}
}
+static int
+bbr_pru_options(struct tcpcb *tp, int flags)
+{
+ if (flags & PRUS_OOB)
+ return (EOPNOTSUPP);
+ return (0);
+}
+
+struct tcp_function_block __tcp_bbr = {
+ .tfb_tcp_block_name = __XSTRING(STACKNAME),
+ .tfb_tcp_output = bbr_output,
+ .tfb_do_queued_segments = ctf_do_queued_segments,
+ .tfb_do_segment_nounlock = bbr_do_segment_nounlock,
+ .tfb_tcp_do_segment = bbr_do_segment,
+ .tfb_tcp_ctloutput = bbr_ctloutput,
+ .tfb_tcp_fb_init = bbr_init,
+ .tfb_tcp_fb_fini = bbr_fini,
+ .tfb_tcp_timer_stop_all = bbr_stopall,
+ .tfb_tcp_timer_activate = bbr_timer_activate,
+ .tfb_tcp_timer_active = bbr_timer_active,
+ .tfb_tcp_timer_stop = bbr_timer_stop,
+ .tfb_tcp_rexmit_tmr = bbr_remxt_tmr,
+ .tfb_tcp_handoff_ok = bbr_handoff_ok,
+ .tfb_tcp_mtu_chg = bbr_mtu_chg,
+ .tfb_pru_options = bbr_pru_options,
+};
+
/*
* bbr_ctloutput() must drop the inpcb lock before performing copyin on
* socket option arguments. When it re-acquires the lock after the copy, it
@@ -14269,6 +14300,10 @@ bbr_set_sockopt(struct socket *so, struct sockopt *sopt,
return (ECONNRESET);
}
tp = intotcpcb(inp);
+ if (tp->t_fb != &__tcp_bbr) {
+ INP_WUNLOCK(inp);
+ return (ENOPROTOOPT);
+ }
bbr = (struct tcp_bbr *)tp->t_fb_ptr;
switch (sopt->sopt_name) {
case TCP_BBR_PACE_PER_SEC:
@@ -14772,33 +14807,6 @@ out:
return (error);
}
-static int
-bbr_pru_options(struct tcpcb *tp, int flags)
-{
- if (flags & PRUS_OOB)
- return (EOPNOTSUPP);
- return (0);
-}
-
-struct tcp_function_block __tcp_bbr = {
- .tfb_tcp_block_name = __XSTRING(STACKNAME),
- .tfb_tcp_output = bbr_output,
- .tfb_do_queued_segments = ctf_do_queued_segments,
- .tfb_do_segment_nounlock = bbr_do_segment_nounlock,
- .tfb_tcp_do_segment = bbr_do_segment,
- .tfb_tcp_ctloutput = bbr_ctloutput,
- .tfb_tcp_fb_init = bbr_init,
- .tfb_tcp_fb_fini = bbr_fini,
- .tfb_tcp_timer_stop_all = bbr_stopall,
- .tfb_tcp_timer_activate = bbr_timer_activate,
- .tfb_tcp_timer_active = bbr_timer_active,
- .tfb_tcp_timer_stop = bbr_timer_stop,
- .tfb_tcp_rexmit_tmr = bbr_remxt_tmr,
- .tfb_tcp_handoff_ok = bbr_handoff_ok,
- .tfb_tcp_mtu_chg = bbr_mtu_chg,
- .tfb_pru_options = bbr_pru_options,
-};
-
static const char *bbr_stack_names[] = {
__XSTRING(STACKNAME),
#ifdef STACKALIAS