summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Stewart <rrs@FreeBSD.org>2020-05-04 20:19:57 +0000
committerRandall Stewart <rrs@FreeBSD.org>2020-05-04 20:19:57 +0000
commitd3b6c96b7dfd20f16785fdbe02141b5a3664290d (patch)
tree99f727a10e7e76f3de5a62511d18caf1d3c48173
parentea69bf7f5d1f3fcf2966a79ba80fbc8189f261e9 (diff)
Notes
-rw-r--r--sys/netinet/tcp_usrreq.c33
-rw-r--r--sys/netinet/tcp_var.h1
2 files changed, 34 insertions, 0 deletions
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;