aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2008-11-21 21:50:52 -0500
committerRoland Dreier <rolandd@cisco.com>2008-12-05 14:00:19 -0500
commitabb77256761bc3ee7a21cc28f6f12a938964e83f (patch)
tree33d435dfedb2bac2d74a515d04e817d8be90833b /drivers/infiniband
parent4a14f6a79f5110c6033f0c61d77d07c449c2d083 (diff)
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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index f34fa6f77a81..0997c7b8cd9b 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1508,7 +1508,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1508 int optionsize; 1508 int optionsize;
1509 1509
1510 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); 1510 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1511 skb_pull(skb, tcph->doff << 2); 1511 skb_trim(skb, 0);
1512 inc_sequence = ntohl(tcph->seq); 1512 inc_sequence = ntohl(tcph->seq);
1513 1513
1514 switch (cm_node->state) { 1514 switch (cm_node->state) {
@@ -1541,6 +1541,10 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1541 cm_node->state = NES_CM_STATE_SYN_RCVD; 1541 cm_node->state = NES_CM_STATE_SYN_RCVD;
1542 send_syn(cm_node, 1, skb); 1542 send_syn(cm_node, 1, skb);
1543 break; 1543 break;
1544 case NES_CM_STATE_CLOSED:
1545 cleanup_retrans_entry(cm_node);
1546 send_reset(cm_node, skb);
1547 break;
1544 case NES_CM_STATE_TSA: 1548 case NES_CM_STATE_TSA:
1545 case NES_CM_STATE_ESTABLISHED: 1549 case NES_CM_STATE_ESTABLISHED:
1546 case NES_CM_STATE_FIN_WAIT1: 1550 case NES_CM_STATE_FIN_WAIT1:
@@ -1549,7 +1553,6 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1549 case NES_CM_STATE_LAST_ACK: 1553 case NES_CM_STATE_LAST_ACK:
1550 case NES_CM_STATE_CLOSING: 1554 case NES_CM_STATE_CLOSING:
1551 case NES_CM_STATE_UNKNOWN: 1555 case NES_CM_STATE_UNKNOWN:
1552 case NES_CM_STATE_CLOSED:
1553 default: 1556 default:
1554 drop_packet(skb); 1557 drop_packet(skb);
1555 break; 1558 break;
@@ -1565,7 +1568,7 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1565 int optionsize; 1568 int optionsize;
1566 1569
1567 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); 1570 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1568 skb_pull(skb, tcph->doff << 2); 1571 skb_trim(skb, 0);
1569 inc_sequence = ntohl(tcph->seq); 1572 inc_sequence = ntohl(tcph->seq);
1570 switch (cm_node->state) { 1573 switch (cm_node->state) {
1571 case NES_CM_STATE_SYN_SENT: 1574 case NES_CM_STATE_SYN_SENT:
@@ -1589,6 +1592,12 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1589 /* passive open, so should not be here */ 1592 /* passive open, so should not be here */
1590 passive_open_err(cm_node, skb, 1); 1593 passive_open_err(cm_node, skb, 1);
1591 break; 1594 break;
1595 case NES_CM_STATE_LISTENING:
1596 case NES_CM_STATE_CLOSED:
1597 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1598 cleanup_retrans_entry(cm_node);
1599 send_reset(cm_node, skb);
1600 break;
1592 case NES_CM_STATE_ESTABLISHED: 1601 case NES_CM_STATE_ESTABLISHED:
1593 case NES_CM_STATE_FIN_WAIT1: 1602 case NES_CM_STATE_FIN_WAIT1:
1594 case NES_CM_STATE_FIN_WAIT2: 1603 case NES_CM_STATE_FIN_WAIT2:
@@ -1596,7 +1605,6 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1596 case NES_CM_STATE_TSA: 1605 case NES_CM_STATE_TSA:
1597 case NES_CM_STATE_CLOSING: 1606 case NES_CM_STATE_CLOSING:
1598 case NES_CM_STATE_UNKNOWN: 1607 case NES_CM_STATE_UNKNOWN:
1599 case NES_CM_STATE_CLOSED:
1600 case NES_CM_STATE_MPAREQ_SENT: 1608 case NES_CM_STATE_MPAREQ_SENT:
1601 default: 1609 default:
1602 drop_packet(skb); 1610 drop_packet(skb);
@@ -1611,6 +1619,13 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1611 u32 inc_sequence; 1619 u32 inc_sequence;
1612 u32 rem_seq_ack; 1620 u32 rem_seq_ack;
1613 u32 rem_seq; 1621 u32 rem_seq;
1622 int ret;
1623 int optionsize;
1624 u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
1625
1626 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1627 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1628
1614 if (check_seq(cm_node, tcph, skb)) 1629 if (check_seq(cm_node, tcph, skb))
1615 return; 1630 return;
1616 1631
@@ -1623,7 +1638,18 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1623 switch (cm_node->state) { 1638 switch (cm_node->state) {
1624 case NES_CM_STATE_SYN_RCVD: 1639 case NES_CM_STATE_SYN_RCVD:
1625 /* Passive OPEN */ 1640 /* Passive OPEN */
1641 ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1);
1642 if (ret)
1643 break;
1626 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1644 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1645 cm_node->tcp_cntxt.loc_seq_num = temp_seq;
1646 if (cm_node->tcp_cntxt.rem_ack_num !=
1647 cm_node->tcp_cntxt.loc_seq_num) {
1648 nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
1649 cleanup_retrans_entry(cm_node);
1650 send_reset(cm_node, skb);
1651 return;
1652 }
1627 cm_node->state = NES_CM_STATE_ESTABLISHED; 1653 cm_node->state = NES_CM_STATE_ESTABLISHED;
1628 if (datasize) { 1654 if (datasize) {
1629 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1655 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
@@ -1655,11 +1681,15 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1655 dev_kfree_skb_any(skb); 1681 dev_kfree_skb_any(skb);
1656 } 1682 }
1657 break; 1683 break;
1684 case NES_CM_STATE_LISTENING:
1685 case NES_CM_STATE_CLOSED:
1686 cleanup_retrans_entry(cm_node);
1687 send_reset(cm_node, skb);
1688 break;
1658 case NES_CM_STATE_FIN_WAIT1: 1689 case NES_CM_STATE_FIN_WAIT1:
1659 case NES_CM_STATE_SYN_SENT: 1690 case NES_CM_STATE_SYN_SENT:
1660 case NES_CM_STATE_FIN_WAIT2: 1691 case NES_CM_STATE_FIN_WAIT2:
1661 case NES_CM_STATE_TSA: 1692 case NES_CM_STATE_TSA:
1662 case NES_CM_STATE_CLOSED:
1663 case NES_CM_STATE_MPAREQ_RCVD: 1693 case NES_CM_STATE_MPAREQ_RCVD:
1664 case NES_CM_STATE_LAST_ACK: 1694 case NES_CM_STATE_LAST_ACK:
1665 case NES_CM_STATE_CLOSING: 1695 case NES_CM_STATE_CLOSING:
@@ -1682,9 +1712,9 @@ static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1682 nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", 1712 nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n",
1683 __func__, cm_node); 1713 __func__, cm_node);
1684 if (passive) 1714 if (passive)
1685 passive_open_err(cm_node, skb, 0); 1715 passive_open_err(cm_node, skb, 1);
1686 else 1716 else
1687 active_open_err(cm_node, skb, 0); 1717 active_open_err(cm_node, skb, 1);
1688 return 1; 1718 return 1;
1689 } 1719 }
1690 } 1720 }