From d3b6c96b7dfd20f16785fdbe02141b5a3664290d Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 4 May 2020 20:19:57 +0000 Subject: Adjust the fb to have a way to ask the underlying stack if it can support the PRUS option (OOB). And then have the new function call that to validate and give the correct error response if needed to the user (rack and bbr do not support obsoleted OOB data). Sponsoered by: Netflix Inc. Differential Revision: https://reviews.freebsd.org/D24574 --- sys/netinet/tcp_usrreq.c | 33 +++++++++++++++++++++++++++++++++ sys/netinet/tcp_var.h | 1 + 2 files changed, 34 insertions(+) diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index d1eb34e49ec45..0fd488ad9fd00 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -133,6 +133,8 @@ static void tcp_disconnect(struct tcpcb *); static void tcp_usrclosed(struct tcpcb *); static void tcp_fill_info(struct tcpcb *, struct tcp_info *); +static int tcp_pru_options_support(struct tcpcb *tp, int flags); + #ifdef TCPDEBUG #define TCPDEBUG0 int ostate = 0 #define TCPDEBUG1() ostate = tp ? tp->t_state : 0 @@ -979,6 +981,15 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m, goto out; } tp = intotcpcb(inp); + if (flags & PRUS_OOB) { + if ((error = tcp_pru_options_support(tp, PRUS_OOB)) != 0) { + if (control) + m_freem(control); + if (m && (flags & PRUS_NOTREADY) == 0) + m_freem(m); + goto out; + } + } TCPDEBUG1(); if (nam != NULL && tp->t_state < TCPS_SYN_SENT) { switch (nam->sa_family) { @@ -1362,6 +1373,24 @@ tcp_usr_close(struct socket *so) NET_EPOCH_EXIT(et); } +static int +tcp_pru_options_support(struct tcpcb *tp, int flags) +{ + /* + * If the specific TCP stack has a pru_options + * specified then it does not always support + * all the PRU_XX options and we must ask it. + * If the function is not specified then all + * of the PRU_XX options are supported. + */ + int ret = 0; + + if (tp->t_fb->tfb_pru_options) { + ret = (*tp->t_fb->tfb_pru_options)(tp, flags); + } + return (ret); +} + /* * Receive out-of-band data. */ @@ -1381,6 +1410,10 @@ tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags) goto out; } tp = intotcpcb(inp); + error = tcp_pru_options_support(tp, PRUS_OOB); + if (error) { + goto out; + } TCPDEBUG1(); if ((so->so_oobmark == 0 && (so->so_rcv.sb_state & SBS_RCVATMARK) == 0) || diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 261ed3f561227..265746c699644 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -345,6 +345,7 @@ struct tcp_function_block { void (*tfb_tcp_rexmit_tmr)(struct tcpcb *); int (*tfb_tcp_handoff_ok)(struct tcpcb *); void (*tfb_tcp_mtu_chg)(struct tcpcb *); + int (*tfb_pru_options)(struct tcpcb *, int); volatile uint32_t tfb_refcnt; uint32_t tfb_flags; uint8_t tfb_id; -- cgit v1.2.3