diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 56 |
1 files changed, 25 insertions, 31 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 4969c386785e..2c90b38daef1 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -1326,18 +1326,20 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) | |||
1326 | nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " | 1326 | nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. " |
1327 | "refcnt=%d\n", cm_node, cm_node->state, | 1327 | "refcnt=%d\n", cm_node, cm_node->state, |
1328 | atomic_read(&cm_node->ref_count)); | 1328 | atomic_read(&cm_node->ref_count)); |
1329 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1330 | cleanup_retrans_entry(cm_node); | ||
1331 | switch (cm_node->state) { | 1329 | switch (cm_node->state) { |
1332 | case NES_CM_STATE_SYN_RCVD: | 1330 | case NES_CM_STATE_SYN_RCVD: |
1333 | case NES_CM_STATE_SYN_SENT: | 1331 | case NES_CM_STATE_SYN_SENT: |
1334 | case NES_CM_STATE_ESTABLISHED: | 1332 | case NES_CM_STATE_ESTABLISHED: |
1335 | case NES_CM_STATE_MPAREQ_SENT: | 1333 | case NES_CM_STATE_MPAREQ_SENT: |
1336 | case NES_CM_STATE_MPAREJ_RCVD: | 1334 | case NES_CM_STATE_MPAREJ_RCVD: |
1335 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1336 | cleanup_retrans_entry(cm_node); | ||
1337 | cm_node->state = NES_CM_STATE_LAST_ACK; | 1337 | cm_node->state = NES_CM_STATE_LAST_ACK; |
1338 | send_fin(cm_node, NULL); | 1338 | send_fin(cm_node, NULL); |
1339 | break; | 1339 | break; |
1340 | case NES_CM_STATE_FIN_WAIT1: | 1340 | case NES_CM_STATE_FIN_WAIT1: |
1341 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1342 | cleanup_retrans_entry(cm_node); | ||
1341 | cm_node->state = NES_CM_STATE_CLOSING; | 1343 | cm_node->state = NES_CM_STATE_CLOSING; |
1342 | send_ack(cm_node, NULL); | 1344 | send_ack(cm_node, NULL); |
1343 | /* Wait for ACK as this is simultanous close.. | 1345 | /* Wait for ACK as this is simultanous close.. |
@@ -1345,11 +1347,15 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) | |||
1345 | * Just rm the node.. Done.. */ | 1347 | * Just rm the node.. Done.. */ |
1346 | break; | 1348 | break; |
1347 | case NES_CM_STATE_FIN_WAIT2: | 1349 | case NES_CM_STATE_FIN_WAIT2: |
1350 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1351 | cleanup_retrans_entry(cm_node); | ||
1348 | cm_node->state = NES_CM_STATE_TIME_WAIT; | 1352 | cm_node->state = NES_CM_STATE_TIME_WAIT; |
1349 | send_ack(cm_node, NULL); | 1353 | send_ack(cm_node, NULL); |
1350 | schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0); | 1354 | schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0); |
1351 | break; | 1355 | break; |
1352 | case NES_CM_STATE_TIME_WAIT: | 1356 | case NES_CM_STATE_TIME_WAIT: |
1357 | cm_node->tcp_cntxt.rcv_nxt++; | ||
1358 | cleanup_retrans_entry(cm_node); | ||
1353 | cm_node->state = NES_CM_STATE_CLOSED; | 1359 | cm_node->state = NES_CM_STATE_CLOSED; |
1354 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 1360 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
1355 | break; | 1361 | break; |
@@ -1385,7 +1391,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1385 | passive_state = atomic_add_return(1, &cm_node->passive_state); | 1391 | passive_state = atomic_add_return(1, &cm_node->passive_state); |
1386 | if (passive_state == NES_SEND_RESET_EVENT) | 1392 | if (passive_state == NES_SEND_RESET_EVENT) |
1387 | create_event(cm_node, NES_CM_EVENT_RESET); | 1393 | create_event(cm_node, NES_CM_EVENT_RESET); |
1388 | cleanup_retrans_entry(cm_node); | ||
1389 | cm_node->state = NES_CM_STATE_CLOSED; | 1394 | cm_node->state = NES_CM_STATE_CLOSED; |
1390 | dev_kfree_skb_any(skb); | 1395 | dev_kfree_skb_any(skb); |
1391 | break; | 1396 | break; |
@@ -1399,17 +1404,16 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1399 | active_open_err(cm_node, skb, reset); | 1404 | active_open_err(cm_node, skb, reset); |
1400 | break; | 1405 | break; |
1401 | case NES_CM_STATE_CLOSED: | 1406 | case NES_CM_STATE_CLOSED: |
1402 | cleanup_retrans_entry(cm_node); | ||
1403 | drop_packet(skb); | 1407 | drop_packet(skb); |
1404 | break; | 1408 | break; |
1409 | case NES_CM_STATE_LAST_ACK: | ||
1410 | cm_node->cm_id->rem_ref(cm_node->cm_id); | ||
1405 | case NES_CM_STATE_TIME_WAIT: | 1411 | case NES_CM_STATE_TIME_WAIT: |
1406 | cleanup_retrans_entry(cm_node); | ||
1407 | cm_node->state = NES_CM_STATE_CLOSED; | 1412 | cm_node->state = NES_CM_STATE_CLOSED; |
1408 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 1413 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
1409 | drop_packet(skb); | 1414 | drop_packet(skb); |
1410 | break; | 1415 | break; |
1411 | case NES_CM_STATE_FIN_WAIT1: | 1416 | case NES_CM_STATE_FIN_WAIT1: |
1412 | cleanup_retrans_entry(cm_node); | ||
1413 | nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__); | 1417 | nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__); |
1414 | default: | 1418 | default: |
1415 | drop_packet(skb); | 1419 | drop_packet(skb); |
@@ -1456,6 +1460,7 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb) | |||
1456 | NES_PASSIVE_STATE_INDICATED); | 1460 | NES_PASSIVE_STATE_INDICATED); |
1457 | break; | 1461 | break; |
1458 | case NES_CM_STATE_MPAREQ_SENT: | 1462 | case NES_CM_STATE_MPAREQ_SENT: |
1463 | cleanup_retrans_entry(cm_node); | ||
1459 | if (res_type == NES_MPA_REQUEST_REJECT) { | 1464 | if (res_type == NES_MPA_REQUEST_REJECT) { |
1460 | type = NES_CM_EVENT_MPA_REJECT; | 1465 | type = NES_CM_EVENT_MPA_REJECT; |
1461 | cm_node->state = NES_CM_STATE_MPAREJ_RCVD; | 1466 | cm_node->state = NES_CM_STATE_MPAREJ_RCVD; |
@@ -1653,49 +1658,39 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1653 | } | 1658 | } |
1654 | } | 1659 | } |
1655 | 1660 | ||
1656 | static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | 1661 | static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, |
1657 | struct tcphdr *tcph) | 1662 | struct tcphdr *tcph) |
1658 | { | 1663 | { |
1659 | int datasize = 0; | 1664 | int datasize = 0; |
1660 | u32 inc_sequence; | 1665 | u32 inc_sequence; |
1661 | u32 rem_seq_ack; | 1666 | u32 rem_seq_ack; |
1662 | u32 rem_seq; | 1667 | u32 rem_seq; |
1663 | int ret; | 1668 | int ret = 0; |
1664 | int optionsize; | 1669 | int optionsize; |
1665 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); | 1670 | optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); |
1666 | 1671 | ||
1667 | if (check_seq(cm_node, tcph, skb)) | 1672 | if (check_seq(cm_node, tcph, skb)) |
1668 | return; | 1673 | return -EINVAL; |
1669 | 1674 | ||
1670 | skb_pull(skb, tcph->doff << 2); | 1675 | skb_pull(skb, tcph->doff << 2); |
1671 | inc_sequence = ntohl(tcph->seq); | 1676 | inc_sequence = ntohl(tcph->seq); |
1672 | rem_seq = ntohl(tcph->seq); | 1677 | rem_seq = ntohl(tcph->seq); |
1673 | rem_seq_ack = ntohl(tcph->ack_seq); | 1678 | rem_seq_ack = ntohl(tcph->ack_seq); |
1674 | datasize = skb->len; | 1679 | datasize = skb->len; |
1675 | cleanup_retrans_entry(cm_node); | ||
1676 | switch (cm_node->state) { | 1680 | switch (cm_node->state) { |
1677 | case NES_CM_STATE_SYN_RCVD: | 1681 | case NES_CM_STATE_SYN_RCVD: |
1678 | /* Passive OPEN */ | 1682 | /* Passive OPEN */ |
1683 | cleanup_retrans_entry(cm_node); | ||
1679 | ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1); | 1684 | ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 1); |
1680 | if (ret) | 1685 | if (ret) |
1681 | break; | 1686 | break; |
1682 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); | 1687 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); |
1683 | if (cm_node->tcp_cntxt.rem_ack_num != | ||
1684 | cm_node->tcp_cntxt.loc_seq_num) { | ||
1685 | nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n"); | ||
1686 | cleanup_retrans_entry(cm_node); | ||
1687 | send_reset(cm_node, skb); | ||
1688 | return; | ||
1689 | } | ||
1690 | cm_node->state = NES_CM_STATE_ESTABLISHED; | 1688 | cm_node->state = NES_CM_STATE_ESTABLISHED; |
1691 | cleanup_retrans_entry(cm_node); | ||
1692 | if (datasize) { | 1689 | if (datasize) { |
1693 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; | 1690 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; |
1694 | handle_rcv_mpa(cm_node, skb); | 1691 | handle_rcv_mpa(cm_node, skb); |
1695 | } else { /* rcvd ACK only */ | 1692 | } else /* rcvd ACK only */ |
1696 | dev_kfree_skb_any(skb); | 1693 | dev_kfree_skb_any(skb); |
1697 | cleanup_retrans_entry(cm_node); | ||
1698 | } | ||
1699 | break; | 1694 | break; |
1700 | case NES_CM_STATE_ESTABLISHED: | 1695 | case NES_CM_STATE_ESTABLISHED: |
1701 | /* Passive OPEN */ | 1696 | /* Passive OPEN */ |
@@ -1707,15 +1702,12 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1707 | drop_packet(skb); | 1702 | drop_packet(skb); |
1708 | break; | 1703 | break; |
1709 | case NES_CM_STATE_MPAREQ_SENT: | 1704 | case NES_CM_STATE_MPAREQ_SENT: |
1710 | cleanup_retrans_entry(cm_node); | ||
1711 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); | 1705 | cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); |
1712 | if (datasize) { | 1706 | if (datasize) { |
1713 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; | 1707 | cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; |
1714 | handle_rcv_mpa(cm_node, skb); | 1708 | handle_rcv_mpa(cm_node, skb); |
1715 | } else { /* Could be just an ack pkt.. */ | 1709 | } else /* Could be just an ack pkt.. */ |
1716 | cleanup_retrans_entry(cm_node); | ||
1717 | dev_kfree_skb_any(skb); | 1710 | dev_kfree_skb_any(skb); |
1718 | } | ||
1719 | break; | 1711 | break; |
1720 | case NES_CM_STATE_LISTENING: | 1712 | case NES_CM_STATE_LISTENING: |
1721 | case NES_CM_STATE_CLOSED: | 1713 | case NES_CM_STATE_CLOSED: |
@@ -1723,11 +1715,10 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1723 | send_reset(cm_node, skb); | 1715 | send_reset(cm_node, skb); |
1724 | break; | 1716 | break; |
1725 | case NES_CM_STATE_LAST_ACK: | 1717 | case NES_CM_STATE_LAST_ACK: |
1718 | case NES_CM_STATE_CLOSING: | ||
1726 | cleanup_retrans_entry(cm_node); | 1719 | cleanup_retrans_entry(cm_node); |
1727 | cm_node->state = NES_CM_STATE_CLOSED; | 1720 | cm_node->state = NES_CM_STATE_CLOSED; |
1728 | cm_node->cm_id->rem_ref(cm_node->cm_id); | 1721 | cm_node->cm_id->rem_ref(cm_node->cm_id); |
1729 | case NES_CM_STATE_CLOSING: | ||
1730 | cleanup_retrans_entry(cm_node); | ||
1731 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 1722 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
1732 | drop_packet(skb); | 1723 | drop_packet(skb); |
1733 | break; | 1724 | break; |
@@ -1742,9 +1733,11 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1742 | case NES_CM_STATE_MPAREQ_RCVD: | 1733 | case NES_CM_STATE_MPAREQ_RCVD: |
1743 | case NES_CM_STATE_UNKNOWN: | 1734 | case NES_CM_STATE_UNKNOWN: |
1744 | default: | 1735 | default: |
1736 | cleanup_retrans_entry(cm_node); | ||
1745 | drop_packet(skb); | 1737 | drop_packet(skb); |
1746 | break; | 1738 | break; |
1747 | } | 1739 | } |
1740 | return ret; | ||
1748 | } | 1741 | } |
1749 | 1742 | ||
1750 | 1743 | ||
@@ -1850,6 +1843,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1850 | enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; | 1843 | enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN; |
1851 | struct tcphdr *tcph = tcp_hdr(skb); | 1844 | struct tcphdr *tcph = tcp_hdr(skb); |
1852 | u32 fin_set = 0; | 1845 | u32 fin_set = 0; |
1846 | int ret = 0; | ||
1853 | skb_pull(skb, ip_hdr(skb)->ihl << 2); | 1847 | skb_pull(skb, ip_hdr(skb)->ihl << 2); |
1854 | 1848 | ||
1855 | nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d " | 1849 | nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d " |
@@ -1875,17 +1869,17 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1875 | handle_synack_pkt(cm_node, skb, tcph); | 1869 | handle_synack_pkt(cm_node, skb, tcph); |
1876 | break; | 1870 | break; |
1877 | case NES_PKT_TYPE_ACK: | 1871 | case NES_PKT_TYPE_ACK: |
1878 | handle_ack_pkt(cm_node, skb, tcph); | 1872 | ret = handle_ack_pkt(cm_node, skb, tcph); |
1879 | if (fin_set) | 1873 | if (fin_set && !ret) |
1880 | handle_fin_pkt(cm_node); | 1874 | handle_fin_pkt(cm_node); |
1881 | break; | 1875 | break; |
1882 | case NES_PKT_TYPE_RST: | 1876 | case NES_PKT_TYPE_RST: |
1883 | handle_rst_pkt(cm_node, skb, tcph); | 1877 | handle_rst_pkt(cm_node, skb, tcph); |
1884 | break; | 1878 | break; |
1885 | default: | 1879 | default: |
1886 | drop_packet(skb); | 1880 | if ((fin_set) && (!check_seq(cm_node, tcph, skb))) |
1887 | if (fin_set) | ||
1888 | handle_fin_pkt(cm_node); | 1881 | handle_fin_pkt(cm_node); |
1882 | drop_packet(skb); | ||
1889 | break; | 1883 | break; |
1890 | } | 1884 | } |
1891 | } | 1885 | } |