cxgbe/t4_tom: restore socket's protosw before entering TIME_WAIT.
This fixes a panic due to stale so->so_proto if t4_tom is unloaded and one or more connections that were previously offloaded are still around in TIME_WAIT state. Reviewed by: jhb@ MFC after: 1 week Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D29503
This commit is contained in:
parent
869880463c
commit
5394893269
@ -1260,6 +1260,7 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
|
||||
break;
|
||||
|
||||
case TCPS_FIN_WAIT_2:
|
||||
restore_so_proto(so, inp->inp_vflag & INP_IPV6);
|
||||
tcp_twstart(tp);
|
||||
INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */
|
||||
NET_EPOCH_EXIT(et);
|
||||
@ -1320,6 +1321,7 @@ do_close_con_rpl(struct sge_iq *iq, const struct rss_header *rss,
|
||||
|
||||
switch (tp->t_state) {
|
||||
case TCPS_CLOSING: /* see TCPS_FIN_WAIT_2 in do_peer_close too */
|
||||
restore_so_proto(so, inp->inp_vflag & INP_IPV6);
|
||||
tcp_twstart(tp);
|
||||
release:
|
||||
INP_UNLOCK_ASSERT(inp); /* safe, we have a ref on the inp */
|
||||
|
@ -79,9 +79,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include "tom/t4_tom.h"
|
||||
#include "tom/t4_tls.h"
|
||||
|
||||
static struct protosw *tcp_protosw;
|
||||
static struct protosw toe_protosw;
|
||||
static struct pr_usrreqs toe_usrreqs;
|
||||
|
||||
static struct protosw *tcp6_protosw;
|
||||
static struct protosw toe6_protosw;
|
||||
static struct pr_usrreqs toe6_usrreqs;
|
||||
|
||||
@ -263,6 +265,15 @@ offload_socket(struct socket *so, struct toepcb *toep)
|
||||
mtx_unlock(&td->toep_list_lock);
|
||||
}
|
||||
|
||||
void
|
||||
restore_so_proto(struct socket *so, bool v6)
|
||||
{
|
||||
if (v6)
|
||||
so->so_proto = tcp6_protosw;
|
||||
else
|
||||
so->so_proto = tcp_protosw;
|
||||
}
|
||||
|
||||
/* This is _not_ the normal way to "unoffload" a socket. */
|
||||
void
|
||||
undo_offload_socket(struct socket *so)
|
||||
@ -282,6 +293,7 @@ undo_offload_socket(struct socket *so)
|
||||
sb = &so->so_rcv;
|
||||
SOCKBUF_LOCK(sb);
|
||||
sb->sb_flags &= ~SB_NOCOALESCE;
|
||||
restore_so_proto(so, inp->inp_vflag & INP_IPV6);
|
||||
SOCKBUF_UNLOCK(sb);
|
||||
|
||||
tp->tod = NULL;
|
||||
@ -1837,8 +1849,6 @@ t4_ctloutput_tom(struct socket *so, struct sockopt *sopt)
|
||||
static int
|
||||
t4_tom_mod_load(void)
|
||||
{
|
||||
struct protosw *tcp_protosw, *tcp6_protosw;
|
||||
|
||||
/* CPL handlers */
|
||||
t4_register_cpl_handler(CPL_GET_TCB_RPL, do_get_tcb_rpl);
|
||||
t4_register_shared_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl2,
|
||||
|
@ -352,6 +352,7 @@ int init_toepcb(struct vi_info *, struct toepcb *);
|
||||
struct toepcb *hold_toepcb(struct toepcb *);
|
||||
void free_toepcb(struct toepcb *);
|
||||
void offload_socket(struct socket *, struct toepcb *);
|
||||
void restore_so_proto(struct socket *, bool);
|
||||
void undo_offload_socket(struct socket *);
|
||||
void final_cpl_received(struct toepcb *);
|
||||
void insert_tid(struct adapter *, int, void *, int);
|
||||
|
Loading…
x
Reference in New Issue
Block a user