RDMA/nes: Fix Xansation test crash on cm_node ref_count
While running a Xansation test, an active side node crashed. The problem started on the passive side, which generated an STtag that was 0. The passive side sent a TERMINATE instead of an MPA REJECT msg. The active side, receives TERMINATE and sends connect_err() and set the cm_node state to CLOSED. The passive side sends FIN + ACK after TERMINATE. Active side ends up in handle_ack_pkt() and send_reset(). send_reset() consumes 1 cm_node's ref_count. Because the cm_node is in CLOSED state, which means that cm_node will be destroyed after completion of the connect_err() indication, CM will crash after send_reset(). Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
f9f3f1e08b
commit
886f98a315
|
@ -1610,6 +1610,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
|
|||
break;
|
||||
case NES_CM_STATE_CLOSED:
|
||||
cleanup_retrans_entry(cm_node);
|
||||
add_ref_cm_node(cm_node);
|
||||
send_reset(cm_node, skb);
|
||||
break;
|
||||
case NES_CM_STATE_TSA:
|
||||
|
@ -1661,9 +1662,15 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
|
|||
passive_open_err(cm_node, skb, 1);
|
||||
break;
|
||||
case NES_CM_STATE_LISTENING:
|
||||
cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
|
||||
cleanup_retrans_entry(cm_node);
|
||||
cm_node->state = NES_CM_STATE_CLOSED;
|
||||
send_reset(cm_node, skb);
|
||||
break;
|
||||
case NES_CM_STATE_CLOSED:
|
||||
cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
|
||||
cleanup_retrans_entry(cm_node);
|
||||
add_ref_cm_node(cm_node);
|
||||
send_reset(cm_node, skb);
|
||||
break;
|
||||
case NES_CM_STATE_ESTABLISHED:
|
||||
|
@ -1732,8 +1739,13 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
|
|||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
case NES_CM_STATE_LISTENING:
|
||||
cleanup_retrans_entry(cm_node);
|
||||
cm_node->state = NES_CM_STATE_CLOSED;
|
||||
send_reset(cm_node, skb);
|
||||
break;
|
||||
case NES_CM_STATE_CLOSED:
|
||||
cleanup_retrans_entry(cm_node);
|
||||
add_ref_cm_node(cm_node);
|
||||
send_reset(cm_node, skb);
|
||||
break;
|
||||
case NES_CM_STATE_LAST_ACK:
|
||||
|
@ -2193,8 +2205,11 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
|
|||
case NES_CM_STATE_CLOSING:
|
||||
ret = -1;
|
||||
break;
|
||||
case NES_CM_STATE_MPAREJ_RCVD:
|
||||
case NES_CM_STATE_LISTENING:
|
||||
cleanup_retrans_entry(cm_node);
|
||||
send_reset(cm_node, NULL);
|
||||
break;
|
||||
case NES_CM_STATE_MPAREJ_RCVD:
|
||||
case NES_CM_STATE_UNKNOWN:
|
||||
case NES_CM_STATE_INITED:
|
||||
case NES_CM_STATE_CLOSED:
|
||||
|
|
Loading…
Reference in New Issue