diff options
Diffstat (limited to 'net/tipc/link.c')
| -rw-r--r-- | net/tipc/link.c | 299 |
1 files changed, 156 insertions, 143 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index ac1832a66f8a..b4b9b30167a3 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -484,7 +484,7 @@ static void link_release_outqueue(struct tipc_link *l_ptr) | |||
| 484 | 484 | ||
| 485 | while (buf) { | 485 | while (buf) { |
| 486 | next = buf->next; | 486 | next = buf->next; |
| 487 | buf_discard(buf); | 487 | kfree_skb(buf); |
| 488 | buf = next; | 488 | buf = next; |
| 489 | } | 489 | } |
| 490 | l_ptr->first_out = NULL; | 490 | l_ptr->first_out = NULL; |
| @@ -503,7 +503,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr) | |||
| 503 | 503 | ||
| 504 | while (buf) { | 504 | while (buf) { |
| 505 | next = buf->next; | 505 | next = buf->next; |
| 506 | buf_discard(buf); | 506 | kfree_skb(buf); |
| 507 | buf = next; | 507 | buf = next; |
| 508 | } | 508 | } |
| 509 | l_ptr->defragm_buf = NULL; | 509 | l_ptr->defragm_buf = NULL; |
| @@ -522,20 +522,20 @@ void tipc_link_stop(struct tipc_link *l_ptr) | |||
| 522 | buf = l_ptr->oldest_deferred_in; | 522 | buf = l_ptr->oldest_deferred_in; |
| 523 | while (buf) { | 523 | while (buf) { |
| 524 | next = buf->next; | 524 | next = buf->next; |
| 525 | buf_discard(buf); | 525 | kfree_skb(buf); |
| 526 | buf = next; | 526 | buf = next; |
| 527 | } | 527 | } |
| 528 | 528 | ||
| 529 | buf = l_ptr->first_out; | 529 | buf = l_ptr->first_out; |
| 530 | while (buf) { | 530 | while (buf) { |
| 531 | next = buf->next; | 531 | next = buf->next; |
| 532 | buf_discard(buf); | 532 | kfree_skb(buf); |
| 533 | buf = next; | 533 | buf = next; |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | tipc_link_reset_fragments(l_ptr); | 536 | tipc_link_reset_fragments(l_ptr); |
| 537 | 537 | ||
| 538 | buf_discard(l_ptr->proto_msg_queue); | 538 | kfree_skb(l_ptr->proto_msg_queue); |
| 539 | l_ptr->proto_msg_queue = NULL; | 539 | l_ptr->proto_msg_queue = NULL; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| @@ -571,12 +571,12 @@ void tipc_link_reset(struct tipc_link *l_ptr) | |||
| 571 | /* Clean up all queues: */ | 571 | /* Clean up all queues: */ |
| 572 | 572 | ||
| 573 | link_release_outqueue(l_ptr); | 573 | link_release_outqueue(l_ptr); |
| 574 | buf_discard(l_ptr->proto_msg_queue); | 574 | kfree_skb(l_ptr->proto_msg_queue); |
| 575 | l_ptr->proto_msg_queue = NULL; | 575 | l_ptr->proto_msg_queue = NULL; |
| 576 | buf = l_ptr->oldest_deferred_in; | 576 | buf = l_ptr->oldest_deferred_in; |
| 577 | while (buf) { | 577 | while (buf) { |
| 578 | struct sk_buff *next = buf->next; | 578 | struct sk_buff *next = buf->next; |
| 579 | buf_discard(buf); | 579 | kfree_skb(buf); |
| 580 | buf = next; | 580 | buf = next; |
| 581 | } | 581 | } |
| 582 | if (!list_empty(&l_ptr->waiting_ports)) | 582 | if (!list_empty(&l_ptr->waiting_ports)) |
| @@ -810,7 +810,7 @@ static int link_bundle_buf(struct tipc_link *l_ptr, | |||
| 810 | skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); | 810 | skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); |
| 811 | msg_set_size(bundler_msg, to_pos + size); | 811 | msg_set_size(bundler_msg, to_pos + size); |
| 812 | msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); | 812 | msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); |
| 813 | buf_discard(buf); | 813 | kfree_skb(buf); |
| 814 | l_ptr->stats.sent_bundled++; | 814 | l_ptr->stats.sent_bundled++; |
| 815 | return 1; | 815 | return 1; |
| 816 | } | 816 | } |
| @@ -871,17 +871,15 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 871 | u32 queue_limit = l_ptr->queue_limit[imp]; | 871 | u32 queue_limit = l_ptr->queue_limit[imp]; |
| 872 | u32 max_packet = l_ptr->max_pkt; | 872 | u32 max_packet = l_ptr->max_pkt; |
| 873 | 873 | ||
| 874 | msg_set_prevnode(msg, tipc_own_addr); /* If routed message */ | ||
| 875 | |||
| 876 | /* Match msg importance against queue limits: */ | 874 | /* Match msg importance against queue limits: */ |
| 877 | 875 | ||
| 878 | if (unlikely(queue_size >= queue_limit)) { | 876 | if (unlikely(queue_size >= queue_limit)) { |
| 879 | if (imp <= TIPC_CRITICAL_IMPORTANCE) { | 877 | if (imp <= TIPC_CRITICAL_IMPORTANCE) { |
| 880 | link_schedule_port(l_ptr, msg_origport(msg), size); | 878 | link_schedule_port(l_ptr, msg_origport(msg), size); |
| 881 | buf_discard(buf); | 879 | kfree_skb(buf); |
| 882 | return -ELINKCONG; | 880 | return -ELINKCONG; |
| 883 | } | 881 | } |
| 884 | buf_discard(buf); | 882 | kfree_skb(buf); |
| 885 | if (imp > CONN_MANAGER) { | 883 | if (imp > CONN_MANAGER) { |
| 886 | warn("Resetting link <%s>, send queue full", l_ptr->name); | 884 | warn("Resetting link <%s>, send queue full", l_ptr->name); |
| 887 | tipc_link_reset(l_ptr); | 885 | tipc_link_reset(l_ptr); |
| @@ -968,10 +966,10 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) | |||
| 968 | if (l_ptr) | 966 | if (l_ptr) |
| 969 | res = tipc_link_send_buf(l_ptr, buf); | 967 | res = tipc_link_send_buf(l_ptr, buf); |
| 970 | else | 968 | else |
| 971 | buf_discard(buf); | 969 | kfree_skb(buf); |
| 972 | tipc_node_unlock(n_ptr); | 970 | tipc_node_unlock(n_ptr); |
| 973 | } else { | 971 | } else { |
| 974 | buf_discard(buf); | 972 | kfree_skb(buf); |
| 975 | } | 973 | } |
| 976 | read_unlock_bh(&tipc_net_lock); | 974 | read_unlock_bh(&tipc_net_lock); |
| 977 | return res; | 975 | return res; |
| @@ -1018,7 +1016,7 @@ void tipc_link_send_names(struct list_head *message_list, u32 dest) | |||
| 1018 | 1016 | ||
| 1019 | list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) { | 1017 | list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) { |
| 1020 | list_del((struct list_head *)buf); | 1018 | list_del((struct list_head *)buf); |
| 1021 | buf_discard(buf); | 1019 | kfree_skb(buf); |
| 1022 | } | 1020 | } |
| 1023 | } | 1021 | } |
| 1024 | 1022 | ||
| @@ -1262,7 +1260,7 @@ again: | |||
| 1262 | error: | 1260 | error: |
| 1263 | for (; buf_chain; buf_chain = buf) { | 1261 | for (; buf_chain; buf_chain = buf) { |
| 1264 | buf = buf_chain->next; | 1262 | buf = buf_chain->next; |
| 1265 | buf_discard(buf_chain); | 1263 | kfree_skb(buf_chain); |
| 1266 | } | 1264 | } |
| 1267 | return -EFAULT; | 1265 | return -EFAULT; |
| 1268 | } | 1266 | } |
| @@ -1316,7 +1314,7 @@ error: | |||
| 1316 | tipc_node_unlock(node); | 1314 | tipc_node_unlock(node); |
| 1317 | for (; buf_chain; buf_chain = buf) { | 1315 | for (; buf_chain; buf_chain = buf) { |
| 1318 | buf = buf_chain->next; | 1316 | buf = buf_chain->next; |
| 1319 | buf_discard(buf_chain); | 1317 | kfree_skb(buf_chain); |
| 1320 | } | 1318 | } |
| 1321 | goto again; | 1319 | goto again; |
| 1322 | } | 1320 | } |
| @@ -1324,7 +1322,7 @@ error: | |||
| 1324 | reject: | 1322 | reject: |
| 1325 | for (; buf_chain; buf_chain = buf) { | 1323 | for (; buf_chain; buf_chain = buf) { |
| 1326 | buf = buf_chain->next; | 1324 | buf = buf_chain->next; |
| 1327 | buf_discard(buf_chain); | 1325 | kfree_skb(buf_chain); |
| 1328 | } | 1326 | } |
| 1329 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, | 1327 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, |
| 1330 | total_len, TIPC_ERR_NO_NODE); | 1328 | total_len, TIPC_ERR_NO_NODE); |
| @@ -1390,7 +1388,7 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
| 1390 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); | 1388 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
| 1391 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1389 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { |
| 1392 | l_ptr->unacked_window = 0; | 1390 | l_ptr->unacked_window = 0; |
| 1393 | buf_discard(buf); | 1391 | kfree_skb(buf); |
| 1394 | l_ptr->proto_msg_queue = NULL; | 1392 | l_ptr->proto_msg_queue = NULL; |
| 1395 | return 0; | 1393 | return 0; |
| 1396 | } else { | 1394 | } else { |
| @@ -1501,13 +1499,13 @@ static void link_retransmit_failure(struct tipc_link *l_ptr, | |||
| 1501 | tipc_node_lock(n_ptr); | 1499 | tipc_node_lock(n_ptr); |
| 1502 | 1500 | ||
| 1503 | tipc_addr_string_fill(addr_string, n_ptr->addr); | 1501 | tipc_addr_string_fill(addr_string, n_ptr->addr); |
| 1504 | info("Multicast link info for %s\n", addr_string); | 1502 | info("Broadcast link info for %s\n", addr_string); |
| 1503 | info("Supportable: %d, ", n_ptr->bclink.supportable); | ||
| 1505 | info("Supported: %d, ", n_ptr->bclink.supported); | 1504 | info("Supported: %d, ", n_ptr->bclink.supported); |
| 1506 | info("Acked: %u\n", n_ptr->bclink.acked); | 1505 | info("Acked: %u\n", n_ptr->bclink.acked); |
| 1507 | info("Last in: %u, ", n_ptr->bclink.last_in); | 1506 | info("Last in: %u, ", n_ptr->bclink.last_in); |
| 1508 | info("Gap after: %u, ", n_ptr->bclink.gap_after); | 1507 | info("Oos state: %u, ", n_ptr->bclink.oos_state); |
| 1509 | info("Gap to: %u\n", n_ptr->bclink.gap_to); | 1508 | info("Last sent: %u\n", n_ptr->bclink.last_sent); |
| 1510 | info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync); | ||
| 1511 | 1509 | ||
| 1512 | tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); | 1510 | tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); |
| 1513 | 1511 | ||
| @@ -1679,7 +1677,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
| 1679 | 1677 | ||
| 1680 | /* Ensure message data is a single contiguous unit */ | 1678 | /* Ensure message data is a single contiguous unit */ |
| 1681 | 1679 | ||
| 1682 | if (unlikely(buf_linearize(buf))) | 1680 | if (unlikely(skb_linearize(buf))) |
| 1683 | goto cont; | 1681 | goto cont; |
| 1684 | 1682 | ||
| 1685 | /* Handle arrival of a non-unicast link message */ | 1683 | /* Handle arrival of a non-unicast link message */ |
| @@ -1736,7 +1734,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
| 1736 | 1734 | ||
| 1737 | /* Release acked messages */ | 1735 | /* Release acked messages */ |
| 1738 | 1736 | ||
| 1739 | if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported) | 1737 | if (n_ptr->bclink.supported) |
| 1740 | tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); | 1738 | tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); |
| 1741 | 1739 | ||
| 1742 | crs = l_ptr->first_out; | 1740 | crs = l_ptr->first_out; |
| @@ -1744,7 +1742,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
| 1744 | less_eq(buf_seqno(crs), ackd)) { | 1742 | less_eq(buf_seqno(crs), ackd)) { |
| 1745 | struct sk_buff *next = crs->next; | 1743 | struct sk_buff *next = crs->next; |
| 1746 | 1744 | ||
| 1747 | buf_discard(crs); | 1745 | kfree_skb(crs); |
| 1748 | crs = next; | 1746 | crs = next; |
| 1749 | released++; | 1747 | released++; |
| 1750 | } | 1748 | } |
| @@ -1773,52 +1771,56 @@ protocol_check: | |||
| 1773 | if (unlikely(l_ptr->oldest_deferred_in)) | 1771 | if (unlikely(l_ptr->oldest_deferred_in)) |
| 1774 | head = link_insert_deferred_queue(l_ptr, | 1772 | head = link_insert_deferred_queue(l_ptr, |
| 1775 | head); | 1773 | head); |
| 1776 | if (likely(msg_is_dest(msg, tipc_own_addr))) { | ||
| 1777 | deliver: | 1774 | deliver: |
| 1778 | if (likely(msg_isdata(msg))) { | 1775 | if (likely(msg_isdata(msg))) { |
| 1779 | tipc_node_unlock(n_ptr); | 1776 | tipc_node_unlock(n_ptr); |
| 1780 | tipc_port_recv_msg(buf); | 1777 | tipc_port_recv_msg(buf); |
| 1781 | continue; | 1778 | continue; |
| 1779 | } | ||
| 1780 | switch (msg_user(msg)) { | ||
| 1781 | int ret; | ||
| 1782 | case MSG_BUNDLER: | ||
| 1783 | l_ptr->stats.recv_bundles++; | ||
| 1784 | l_ptr->stats.recv_bundled += | ||
| 1785 | msg_msgcnt(msg); | ||
| 1786 | tipc_node_unlock(n_ptr); | ||
| 1787 | tipc_link_recv_bundle(buf); | ||
| 1788 | continue; | ||
| 1789 | case NAME_DISTRIBUTOR: | ||
| 1790 | tipc_node_unlock(n_ptr); | ||
| 1791 | tipc_named_recv(buf); | ||
| 1792 | continue; | ||
| 1793 | case CONN_MANAGER: | ||
| 1794 | tipc_node_unlock(n_ptr); | ||
| 1795 | tipc_port_recv_proto_msg(buf); | ||
| 1796 | continue; | ||
| 1797 | case MSG_FRAGMENTER: | ||
| 1798 | l_ptr->stats.recv_fragments++; | ||
| 1799 | ret = tipc_link_recv_fragment( | ||
| 1800 | &l_ptr->defragm_buf, | ||
| 1801 | &buf, &msg); | ||
| 1802 | if (ret == 1) { | ||
| 1803 | l_ptr->stats.recv_fragmented++; | ||
| 1804 | goto deliver; | ||
| 1782 | } | 1805 | } |
| 1783 | switch (msg_user(msg)) { | 1806 | if (ret == -1) |
| 1784 | case MSG_BUNDLER: | 1807 | l_ptr->next_in_no--; |
| 1785 | l_ptr->stats.recv_bundles++; | 1808 | break; |
| 1786 | l_ptr->stats.recv_bundled += | 1809 | case CHANGEOVER_PROTOCOL: |
| 1787 | msg_msgcnt(msg); | 1810 | type = msg_type(msg); |
| 1788 | tipc_node_unlock(n_ptr); | 1811 | if (link_recv_changeover_msg(&l_ptr, |
| 1789 | tipc_link_recv_bundle(buf); | 1812 | &buf)) { |
| 1790 | continue; | 1813 | msg = buf_msg(buf); |
| 1791 | case NAME_DISTRIBUTOR: | 1814 | seq_no = msg_seqno(msg); |
| 1792 | tipc_node_unlock(n_ptr); | 1815 | if (type == ORIGINAL_MSG) |
| 1793 | tipc_named_recv(buf); | ||
| 1794 | continue; | ||
| 1795 | case CONN_MANAGER: | ||
| 1796 | tipc_node_unlock(n_ptr); | ||
| 1797 | tipc_port_recv_proto_msg(buf); | ||
| 1798 | continue; | ||
| 1799 | case MSG_FRAGMENTER: | ||
| 1800 | l_ptr->stats.recv_fragments++; | ||
| 1801 | if (tipc_link_recv_fragment(&l_ptr->defragm_buf, | ||
| 1802 | &buf, &msg)) { | ||
| 1803 | l_ptr->stats.recv_fragmented++; | ||
| 1804 | goto deliver; | 1816 | goto deliver; |
| 1805 | } | 1817 | goto protocol_check; |
| 1806 | break; | ||
| 1807 | case CHANGEOVER_PROTOCOL: | ||
| 1808 | type = msg_type(msg); | ||
| 1809 | if (link_recv_changeover_msg(&l_ptr, &buf)) { | ||
| 1810 | msg = buf_msg(buf); | ||
| 1811 | seq_no = msg_seqno(msg); | ||
| 1812 | if (type == ORIGINAL_MSG) | ||
| 1813 | goto deliver; | ||
| 1814 | goto protocol_check; | ||
| 1815 | } | ||
| 1816 | break; | ||
| 1817 | default: | ||
| 1818 | buf_discard(buf); | ||
| 1819 | buf = NULL; | ||
| 1820 | break; | ||
| 1821 | } | 1818 | } |
| 1819 | break; | ||
| 1820 | default: | ||
| 1821 | kfree_skb(buf); | ||
| 1822 | buf = NULL; | ||
| 1823 | break; | ||
| 1822 | } | 1824 | } |
| 1823 | tipc_node_unlock(n_ptr); | 1825 | tipc_node_unlock(n_ptr); |
| 1824 | tipc_net_route_msg(buf); | 1826 | tipc_net_route_msg(buf); |
| @@ -1847,23 +1849,22 @@ deliver: | |||
| 1847 | } | 1849 | } |
| 1848 | tipc_node_unlock(n_ptr); | 1850 | tipc_node_unlock(n_ptr); |
| 1849 | cont: | 1851 | cont: |
| 1850 | buf_discard(buf); | 1852 | kfree_skb(buf); |
| 1851 | } | 1853 | } |
| 1852 | read_unlock_bh(&tipc_net_lock); | 1854 | read_unlock_bh(&tipc_net_lock); |
| 1853 | } | 1855 | } |
| 1854 | 1856 | ||
| 1855 | /* | 1857 | /* |
| 1856 | * link_defer_buf(): Sort a received out-of-sequence packet | 1858 | * tipc_link_defer_pkt - Add out-of-sequence message to deferred reception queue |
| 1857 | * into the deferred reception queue. | 1859 | * |
| 1858 | * Returns the increase of the queue length,i.e. 0 or 1 | 1860 | * Returns increase in queue length (i.e. 0 or 1) |
| 1859 | */ | 1861 | */ |
| 1860 | 1862 | ||
| 1861 | u32 tipc_link_defer_pkt(struct sk_buff **head, | 1863 | u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, |
| 1862 | struct sk_buff **tail, | ||
| 1863 | struct sk_buff *buf) | 1864 | struct sk_buff *buf) |
| 1864 | { | 1865 | { |
| 1865 | struct sk_buff *prev = NULL; | 1866 | struct sk_buff *queue_buf; |
| 1866 | struct sk_buff *crs = *head; | 1867 | struct sk_buff **prev; |
| 1867 | u32 seq_no = buf_seqno(buf); | 1868 | u32 seq_no = buf_seqno(buf); |
| 1868 | 1869 | ||
| 1869 | buf->next = NULL; | 1870 | buf->next = NULL; |
| @@ -1881,31 +1882,30 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, | |||
| 1881 | return 1; | 1882 | return 1; |
| 1882 | } | 1883 | } |
| 1883 | 1884 | ||
| 1884 | /* Scan through queue and sort it in */ | 1885 | /* Locate insertion point in queue, then insert; discard if duplicate */ |
| 1885 | do { | 1886 | prev = head; |
| 1886 | struct tipc_msg *msg = buf_msg(crs); | 1887 | queue_buf = *head; |
| 1888 | for (;;) { | ||
| 1889 | u32 curr_seqno = buf_seqno(queue_buf); | ||
| 1887 | 1890 | ||
| 1888 | if (less(seq_no, msg_seqno(msg))) { | 1891 | if (seq_no == curr_seqno) { |
| 1889 | buf->next = crs; | 1892 | kfree_skb(buf); |
| 1890 | if (prev) | 1893 | return 0; |
| 1891 | prev->next = buf; | ||
| 1892 | else | ||
| 1893 | *head = buf; | ||
| 1894 | return 1; | ||
| 1895 | } | 1894 | } |
| 1896 | if (seq_no == msg_seqno(msg)) | 1895 | |
| 1896 | if (less(seq_no, curr_seqno)) | ||
| 1897 | break; | 1897 | break; |
| 1898 | prev = crs; | ||
| 1899 | crs = crs->next; | ||
| 1900 | } while (crs); | ||
| 1901 | 1898 | ||
| 1902 | /* Message is a duplicate of an existing message */ | 1899 | prev = &queue_buf->next; |
| 1900 | queue_buf = queue_buf->next; | ||
| 1901 | } | ||
| 1903 | 1902 | ||
| 1904 | buf_discard(buf); | 1903 | buf->next = queue_buf; |
| 1905 | return 0; | 1904 | *prev = buf; |
| 1905 | return 1; | ||
| 1906 | } | 1906 | } |
| 1907 | 1907 | ||
| 1908 | /** | 1908 | /* |
| 1909 | * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet | 1909 | * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet |
| 1910 | */ | 1910 | */ |
| 1911 | 1911 | ||
| @@ -1930,7 +1930,7 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, | |||
| 1930 | 1930 | ||
| 1931 | if (less(seq_no, mod(l_ptr->next_in_no))) { | 1931 | if (less(seq_no, mod(l_ptr->next_in_no))) { |
| 1932 | l_ptr->stats.duplicates++; | 1932 | l_ptr->stats.duplicates++; |
| 1933 | buf_discard(buf); | 1933 | kfree_skb(buf); |
| 1934 | return; | 1934 | return; |
| 1935 | } | 1935 | } |
| 1936 | 1936 | ||
| @@ -1956,6 +1956,13 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
| 1956 | u32 msg_size = sizeof(l_ptr->proto_msg); | 1956 | u32 msg_size = sizeof(l_ptr->proto_msg); |
| 1957 | int r_flag; | 1957 | int r_flag; |
| 1958 | 1958 | ||
| 1959 | /* Discard any previous message that was deferred due to congestion */ | ||
| 1960 | |||
| 1961 | if (l_ptr->proto_msg_queue) { | ||
| 1962 | kfree_skb(l_ptr->proto_msg_queue); | ||
| 1963 | l_ptr->proto_msg_queue = NULL; | ||
| 1964 | } | ||
| 1965 | |||
| 1959 | if (link_blocked(l_ptr)) | 1966 | if (link_blocked(l_ptr)) |
| 1960 | return; | 1967 | return; |
| 1961 | 1968 | ||
| @@ -1964,9 +1971,11 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
| 1964 | if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG)) | 1971 | if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG)) |
| 1965 | return; | 1972 | return; |
| 1966 | 1973 | ||
| 1974 | /* Create protocol message with "out-of-sequence" sequence number */ | ||
| 1975 | |||
| 1967 | msg_set_type(msg, msg_typ); | 1976 | msg_set_type(msg, msg_typ); |
| 1968 | msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); | 1977 | msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); |
| 1969 | msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); | 1978 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
| 1970 | msg_set_last_bcast(msg, tipc_bclink_get_last_sent()); | 1979 | msg_set_last_bcast(msg, tipc_bclink_get_last_sent()); |
| 1971 | 1980 | ||
| 1972 | if (msg_typ == STATE_MSG) { | 1981 | if (msg_typ == STATE_MSG) { |
| @@ -2020,44 +2029,36 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
| 2020 | r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); | 2029 | r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); |
| 2021 | msg_set_redundant_link(msg, r_flag); | 2030 | msg_set_redundant_link(msg, r_flag); |
| 2022 | msg_set_linkprio(msg, l_ptr->priority); | 2031 | msg_set_linkprio(msg, l_ptr->priority); |
| 2023 | 2032 | msg_set_size(msg, msg_size); | |
| 2024 | /* Ensure sequence number will not fit : */ | ||
| 2025 | 2033 | ||
| 2026 | msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2))); | 2034 | msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2))); |
| 2027 | 2035 | ||
| 2028 | /* Congestion? */ | ||
| 2029 | |||
| 2030 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | ||
| 2031 | if (!l_ptr->proto_msg_queue) { | ||
| 2032 | l_ptr->proto_msg_queue = | ||
| 2033 | tipc_buf_acquire(sizeof(l_ptr->proto_msg)); | ||
| 2034 | } | ||
| 2035 | buf = l_ptr->proto_msg_queue; | ||
| 2036 | if (!buf) | ||
| 2037 | return; | ||
| 2038 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | ||
| 2039 | return; | ||
| 2040 | } | ||
| 2041 | |||
| 2042 | /* Message can be sent */ | ||
| 2043 | |||
| 2044 | buf = tipc_buf_acquire(msg_size); | 2036 | buf = tipc_buf_acquire(msg_size); |
| 2045 | if (!buf) | 2037 | if (!buf) |
| 2046 | return; | 2038 | return; |
| 2047 | 2039 | ||
| 2048 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 2040 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
| 2049 | msg_set_size(buf_msg(buf), msg_size); | ||
| 2050 | 2041 | ||
| 2051 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 2042 | /* Defer message if bearer is already congested */ |
| 2052 | l_ptr->unacked_window = 0; | 2043 | |
| 2053 | buf_discard(buf); | 2044 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { |
| 2045 | l_ptr->proto_msg_queue = buf; | ||
| 2054 | return; | 2046 | return; |
| 2055 | } | 2047 | } |
| 2056 | 2048 | ||
| 2057 | /* New congestion */ | 2049 | /* Defer message if attempting to send results in bearer congestion */ |
| 2058 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | 2050 | |
| 2059 | l_ptr->proto_msg_queue = buf; | 2051 | if (!tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { |
| 2060 | l_ptr->stats.bearer_congs++; | 2052 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); |
| 2053 | l_ptr->proto_msg_queue = buf; | ||
| 2054 | l_ptr->stats.bearer_congs++; | ||
| 2055 | return; | ||
| 2056 | } | ||
| 2057 | |||
| 2058 | /* Discard message if it was sent successfully */ | ||
| 2059 | |||
| 2060 | l_ptr->unacked_window = 0; | ||
| 2061 | kfree_skb(buf); | ||
| 2061 | } | 2062 | } |
| 2062 | 2063 | ||
| 2063 | /* | 2064 | /* |
| @@ -2105,6 +2106,8 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2105 | l_ptr->owner->block_setup = WAIT_NODE_DOWN; | 2106 | l_ptr->owner->block_setup = WAIT_NODE_DOWN; |
| 2106 | } | 2107 | } |
| 2107 | 2108 | ||
| 2109 | link_state_event(l_ptr, RESET_MSG); | ||
| 2110 | |||
| 2108 | /* fall thru' */ | 2111 | /* fall thru' */ |
| 2109 | case ACTIVATE_MSG: | 2112 | case ACTIVATE_MSG: |
| 2110 | /* Update link settings according other endpoint's values */ | 2113 | /* Update link settings according other endpoint's values */ |
| @@ -2127,16 +2130,22 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2127 | } else { | 2130 | } else { |
| 2128 | l_ptr->max_pkt = l_ptr->max_pkt_target; | 2131 | l_ptr->max_pkt = l_ptr->max_pkt_target; |
| 2129 | } | 2132 | } |
| 2130 | l_ptr->owner->bclink.supported = (max_pkt_info != 0); | 2133 | l_ptr->owner->bclink.supportable = (max_pkt_info != 0); |
| 2131 | 2134 | ||
| 2132 | link_state_event(l_ptr, msg_type(msg)); | 2135 | /* Synchronize broadcast link info, if not done previously */ |
| 2136 | |||
| 2137 | if (!tipc_node_is_up(l_ptr->owner)) { | ||
| 2138 | l_ptr->owner->bclink.last_sent = | ||
| 2139 | l_ptr->owner->bclink.last_in = | ||
| 2140 | msg_last_bcast(msg); | ||
| 2141 | l_ptr->owner->bclink.oos_state = 0; | ||
| 2142 | } | ||
| 2133 | 2143 | ||
| 2134 | l_ptr->peer_session = msg_session(msg); | 2144 | l_ptr->peer_session = msg_session(msg); |
| 2135 | l_ptr->peer_bearer_id = msg_bearer_id(msg); | 2145 | l_ptr->peer_bearer_id = msg_bearer_id(msg); |
| 2136 | 2146 | ||
| 2137 | /* Synchronize broadcast sequence numbers */ | 2147 | if (msg_type(msg) == ACTIVATE_MSG) |
| 2138 | if (!tipc_node_redundant_links(l_ptr->owner)) | 2148 | link_state_event(l_ptr, ACTIVATE_MSG); |
| 2139 | l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); | ||
| 2140 | break; | 2149 | break; |
| 2141 | case STATE_MSG: | 2150 | case STATE_MSG: |
| 2142 | 2151 | ||
| @@ -2177,7 +2186,9 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2177 | 2186 | ||
| 2178 | /* Protocol message before retransmits, reduce loss risk */ | 2187 | /* Protocol message before retransmits, reduce loss risk */ |
| 2179 | 2188 | ||
| 2180 | tipc_bclink_check_gap(l_ptr->owner, msg_last_bcast(msg)); | 2189 | if (l_ptr->owner->bclink.supported) |
| 2190 | tipc_bclink_update_link_state(l_ptr->owner, | ||
| 2191 | msg_last_bcast(msg)); | ||
| 2181 | 2192 | ||
| 2182 | if (rec_gap || (msg_probe(msg))) { | 2193 | if (rec_gap || (msg_probe(msg))) { |
| 2183 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, | 2194 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, |
| @@ -2191,7 +2202,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2191 | break; | 2202 | break; |
| 2192 | } | 2203 | } |
| 2193 | exit: | 2204 | exit: |
| 2194 | buf_discard(buf); | 2205 | kfree_skb(buf); |
| 2195 | } | 2206 | } |
| 2196 | 2207 | ||
| 2197 | 2208 | ||
| @@ -2389,7 +2400,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, | |||
| 2389 | warn("Link changeover error, duplicate msg dropped\n"); | 2400 | warn("Link changeover error, duplicate msg dropped\n"); |
| 2390 | goto exit; | 2401 | goto exit; |
| 2391 | } | 2402 | } |
| 2392 | buf_discard(tunnel_buf); | 2403 | kfree_skb(tunnel_buf); |
| 2393 | return 1; | 2404 | return 1; |
| 2394 | } | 2405 | } |
| 2395 | 2406 | ||
| @@ -2421,7 +2432,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, | |||
| 2421 | } else { | 2432 | } else { |
| 2422 | *buf = buf_extract(tunnel_buf, INT_H_SIZE); | 2433 | *buf = buf_extract(tunnel_buf, INT_H_SIZE); |
| 2423 | if (*buf != NULL) { | 2434 | if (*buf != NULL) { |
| 2424 | buf_discard(tunnel_buf); | 2435 | kfree_skb(tunnel_buf); |
| 2425 | return 1; | 2436 | return 1; |
| 2426 | } else { | 2437 | } else { |
| 2427 | warn("Link changeover error, original msg dropped\n"); | 2438 | warn("Link changeover error, original msg dropped\n"); |
| @@ -2429,7 +2440,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr, | |||
| 2429 | } | 2440 | } |
| 2430 | exit: | 2441 | exit: |
| 2431 | *buf = NULL; | 2442 | *buf = NULL; |
| 2432 | buf_discard(tunnel_buf); | 2443 | kfree_skb(tunnel_buf); |
| 2433 | return 0; | 2444 | return 0; |
| 2434 | } | 2445 | } |
| 2435 | 2446 | ||
| @@ -2451,7 +2462,7 @@ void tipc_link_recv_bundle(struct sk_buff *buf) | |||
| 2451 | pos += align(msg_size(buf_msg(obuf))); | 2462 | pos += align(msg_size(buf_msg(obuf))); |
| 2452 | tipc_net_route_msg(obuf); | 2463 | tipc_net_route_msg(obuf); |
| 2453 | } | 2464 | } |
| 2454 | buf_discard(buf); | 2465 | kfree_skb(buf); |
| 2455 | } | 2466 | } |
| 2456 | 2467 | ||
| 2457 | /* | 2468 | /* |
| @@ -2500,11 +2511,11 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2500 | } | 2511 | } |
| 2501 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); | 2512 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
| 2502 | if (fragm == NULL) { | 2513 | if (fragm == NULL) { |
| 2503 | buf_discard(buf); | 2514 | kfree_skb(buf); |
| 2504 | while (buf_chain) { | 2515 | while (buf_chain) { |
| 2505 | buf = buf_chain; | 2516 | buf = buf_chain; |
| 2506 | buf_chain = buf_chain->next; | 2517 | buf_chain = buf_chain->next; |
| 2507 | buf_discard(buf); | 2518 | kfree_skb(buf); |
| 2508 | } | 2519 | } |
| 2509 | return -ENOMEM; | 2520 | return -ENOMEM; |
| 2510 | } | 2521 | } |
| @@ -2521,7 +2532,7 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2521 | crs += fragm_sz; | 2532 | crs += fragm_sz; |
| 2522 | msg_set_type(&fragm_hdr, FRAGMENT); | 2533 | msg_set_type(&fragm_hdr, FRAGMENT); |
| 2523 | } | 2534 | } |
| 2524 | buf_discard(buf); | 2535 | kfree_skb(buf); |
| 2525 | 2536 | ||
| 2526 | /* Append chain of fragments to send queue & send them */ | 2537 | /* Append chain of fragments to send queue & send them */ |
| 2527 | 2538 | ||
| @@ -2608,7 +2619,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
| 2608 | if (msg_type(imsg) == TIPC_MCAST_MSG) | 2619 | if (msg_type(imsg) == TIPC_MCAST_MSG) |
| 2609 | max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; | 2620 | max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; |
| 2610 | if (msg_size(imsg) > max) { | 2621 | if (msg_size(imsg) > max) { |
| 2611 | buf_discard(fbuf); | 2622 | kfree_skb(fbuf); |
| 2612 | return 0; | 2623 | return 0; |
| 2613 | } | 2624 | } |
| 2614 | pbuf = tipc_buf_acquire(msg_size(imsg)); | 2625 | pbuf = tipc_buf_acquire(msg_size(imsg)); |
| @@ -2623,9 +2634,11 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
| 2623 | set_fragm_size(pbuf, fragm_sz); | 2634 | set_fragm_size(pbuf, fragm_sz); |
| 2624 | set_expected_frags(pbuf, exp_fragm_cnt - 1); | 2635 | set_expected_frags(pbuf, exp_fragm_cnt - 1); |
| 2625 | } else { | 2636 | } else { |
| 2626 | warn("Link unable to reassemble fragmented message\n"); | 2637 | dbg("Link unable to reassemble fragmented message\n"); |
| 2638 | kfree_skb(fbuf); | ||
| 2639 | return -1; | ||
| 2627 | } | 2640 | } |
| 2628 | buf_discard(fbuf); | 2641 | kfree_skb(fbuf); |
| 2629 | return 0; | 2642 | return 0; |
| 2630 | } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) { | 2643 | } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) { |
| 2631 | u32 dsz = msg_data_sz(fragm); | 2644 | u32 dsz = msg_data_sz(fragm); |
| @@ -2634,7 +2647,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
| 2634 | u32 exp_frags = get_expected_frags(pbuf) - 1; | 2647 | u32 exp_frags = get_expected_frags(pbuf) - 1; |
| 2635 | skb_copy_to_linear_data_offset(pbuf, crs, | 2648 | skb_copy_to_linear_data_offset(pbuf, crs, |
| 2636 | msg_data(fragm), dsz); | 2649 | msg_data(fragm), dsz); |
| 2637 | buf_discard(fbuf); | 2650 | kfree_skb(fbuf); |
| 2638 | 2651 | ||
| 2639 | /* Is message complete? */ | 2652 | /* Is message complete? */ |
| 2640 | 2653 | ||
| @@ -2651,7 +2664,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
| 2651 | set_expected_frags(pbuf, exp_frags); | 2664 | set_expected_frags(pbuf, exp_frags); |
| 2652 | return 0; | 2665 | return 0; |
| 2653 | } | 2666 | } |
| 2654 | buf_discard(fbuf); | 2667 | kfree_skb(fbuf); |
| 2655 | return 0; | 2668 | return 0; |
| 2656 | } | 2669 | } |
| 2657 | 2670 | ||
| @@ -2682,7 +2695,7 @@ static void link_check_defragm_bufs(struct tipc_link *l_ptr) | |||
| 2682 | prev->next = buf->next; | 2695 | prev->next = buf->next; |
| 2683 | else | 2696 | else |
| 2684 | l_ptr->defragm_buf = buf->next; | 2697 | l_ptr->defragm_buf = buf->next; |
| 2685 | buf_discard(buf); | 2698 | kfree_skb(buf); |
| 2686 | } | 2699 | } |
| 2687 | buf = next; | 2700 | buf = next; |
| 2688 | } | 2701 | } |
| @@ -3057,7 +3070,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s | |||
| 3057 | str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), | 3070 | str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), |
| 3058 | (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); | 3071 | (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); |
| 3059 | if (!str_len) { | 3072 | if (!str_len) { |
| 3060 | buf_discard(buf); | 3073 | kfree_skb(buf); |
| 3061 | return tipc_cfg_reply_error_string("link not found"); | 3074 | return tipc_cfg_reply_error_string("link not found"); |
| 3062 | } | 3075 | } |
| 3063 | 3076 | ||
