RDMA/nes: Fix TCP compliance test failures

ANVL testing showed we are not handling all cm_node states during
connection establishment.  Add missing state handlers and fix sequence
number send reset in handle_tcp_options().

Signed-off-by: Faisal Latif <faisal.latif@intel.com>
Signed-off-by: Chien Tung <chien.tin.tung@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index f34fa6f..0997c7b 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1508,7 +1508,7 @@
 	int optionsize;
 
 	optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
-	skb_pull(skb, tcph->doff << 2);
+	skb_trim(skb, 0);
 	inc_sequence = ntohl(tcph->seq);
 
 	switch (cm_node->state) {
@@ -1541,6 +1541,10 @@
 		cm_node->state = NES_CM_STATE_SYN_RCVD;
 		send_syn(cm_node, 1, skb);
 		break;
+	case NES_CM_STATE_CLOSED:
+		cleanup_retrans_entry(cm_node);
+		send_reset(cm_node, skb);
+		break;
 	case NES_CM_STATE_TSA:
 	case NES_CM_STATE_ESTABLISHED:
 	case NES_CM_STATE_FIN_WAIT1:
@@ -1549,7 +1553,6 @@
 	case NES_CM_STATE_LAST_ACK:
 	case NES_CM_STATE_CLOSING:
 	case NES_CM_STATE_UNKNOWN:
-	case NES_CM_STATE_CLOSED:
 	default:
 		drop_packet(skb);
 		break;
@@ -1565,7 +1568,7 @@
 	int optionsize;
 
 	optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
-	skb_pull(skb, tcph->doff << 2);
+	skb_trim(skb, 0);
 	inc_sequence = ntohl(tcph->seq);
 	switch (cm_node->state) {
 	case NES_CM_STATE_SYN_SENT:
@@ -1589,6 +1592,12 @@
 		/* passive open, so should not be here */
 		passive_open_err(cm_node, skb, 1);
 		break;
+	case NES_CM_STATE_LISTENING:
+	case NES_CM_STATE_CLOSED:
+		cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
+		cleanup_retrans_entry(cm_node);
+		send_reset(cm_node, skb);
+		break;
 	case NES_CM_STATE_ESTABLISHED:
 	case NES_CM_STATE_FIN_WAIT1:
 	case NES_CM_STATE_FIN_WAIT2:
@@ -1596,7 +1605,6 @@
 	case NES_CM_STATE_TSA:
 	case NES_CM_STATE_CLOSING:
 	case NES_CM_STATE_UNKNOWN:
-	case NES_CM_STATE_CLOSED:
 	case NES_CM_STATE_MPAREQ_SENT:
 	default:
 		drop_packet(skb);
@@ -1611,6 +1619,13 @@
 	u32 inc_sequence;
 	u32 rem_seq_ack;
 	u32 rem_seq;
+	int ret;
+	int optionsize;
+	u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
+
+	optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
+	cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
+
 	if (check_seq(cm_node, tcph, skb))
 		return;
 
@@ -1623,7 +1638,18 @@
 	switch (cm_node->state) {
 	case NES_CM_STATE_SYN_RCVD:
 		/* Passive OPEN */
+		ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1);
+		if (ret)
+			break;
 		cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
+		cm_node->tcp_cntxt.loc_seq_num = temp_seq;
+		if (cm_node->tcp_cntxt.rem_ack_num !=
+		    cm_node->tcp_cntxt.loc_seq_num) {
+			nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
+			cleanup_retrans_entry(cm_node);
+			send_reset(cm_node, skb);
+			return;
+		}
 		cm_node->state = NES_CM_STATE_ESTABLISHED;
 		if (datasize) {
 			cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
@@ -1655,11 +1681,15 @@
 			dev_kfree_skb_any(skb);
 		}
 		break;
+	case NES_CM_STATE_LISTENING:
+	case NES_CM_STATE_CLOSED:
+		cleanup_retrans_entry(cm_node);
+		send_reset(cm_node, skb);
+		break;
 	case NES_CM_STATE_FIN_WAIT1:
 	case NES_CM_STATE_SYN_SENT:
 	case NES_CM_STATE_FIN_WAIT2:
 	case NES_CM_STATE_TSA:
-	case NES_CM_STATE_CLOSED:
 	case NES_CM_STATE_MPAREQ_RCVD:
 	case NES_CM_STATE_LAST_ACK:
 	case NES_CM_STATE_CLOSING:
@@ -1682,9 +1712,9 @@
 			nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n",
 				__func__, cm_node);
 			if (passive)
-				passive_open_err(cm_node, skb, 0);
+				passive_open_err(cm_node, skb, 1);
 			else
-				active_open_err(cm_node, skb, 0);
+				active_open_err(cm_node, skb, 1);
 			return 1;
 		}
 	}