Index: head/sys/netinet/tcp_usrreq.c =================================================================== --- head/sys/netinet/tcp_usrreq.c +++ head/sys/netinet/tcp_usrreq.c @@ -133,6 +133,8 @@ 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 @@ 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 @@ 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 @@ 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) || Index: head/sys/netinet/tcp_var.h =================================================================== --- head/sys/netinet/tcp_var.h +++ head/sys/netinet/tcp_var.h @@ -345,6 +345,7 @@ 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;