diff options
Diffstat (limited to 'drivers')
| -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 | } |
