diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a3616b99529..b8cf1e9d0b8 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -239,13 +239,13 @@ int tipc_link_is_up(struct link *l_ptr) | |||
239 | { | 239 | { |
240 | if (!l_ptr) | 240 | if (!l_ptr) |
241 | return 0; | 241 | return 0; |
242 | return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); | 242 | return link_working_working(l_ptr) || link_working_unknown(l_ptr); |
243 | } | 243 | } |
244 | 244 | ||
245 | int tipc_link_is_active(struct link *l_ptr) | 245 | int tipc_link_is_active(struct link *l_ptr) |
246 | { | 246 | { |
247 | return ((l_ptr->owner->active_links[0] == l_ptr) || | 247 | return (l_ptr->owner->active_links[0] == l_ptr) || |
248 | (l_ptr->owner->active_links[1] == l_ptr)); | 248 | (l_ptr->owner->active_links[1] == l_ptr); |
249 | } | 249 | } |
250 | 250 | ||
251 | /** | 251 | /** |
@@ -1802,6 +1802,15 @@ static int link_recv_buf_validate(struct sk_buff *buf) | |||
1802 | return pskb_may_pull(buf, hdr_size); | 1802 | return pskb_may_pull(buf, hdr_size); |
1803 | } | 1803 | } |
1804 | 1804 | ||
1805 | /** | ||
1806 | * tipc_recv_msg - process TIPC messages arriving from off-node | ||
1807 | * @head: pointer to message buffer chain | ||
1808 | * @tb_ptr: pointer to bearer message arrived on | ||
1809 | * | ||
1810 | * Invoked with no locks held. Bearer pointer must point to a valid bearer | ||
1811 | * structure (i.e. cannot be NULL), but bearer can be inactive. | ||
1812 | */ | ||
1813 | |||
1805 | void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | 1814 | void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) |
1806 | { | 1815 | { |
1807 | read_lock_bh(&tipc_net_lock); | 1816 | read_lock_bh(&tipc_net_lock); |
@@ -1819,6 +1828,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1819 | 1828 | ||
1820 | head = head->next; | 1829 | head = head->next; |
1821 | 1830 | ||
1831 | /* Ensure bearer is still enabled */ | ||
1832 | |||
1833 | if (unlikely(!b_ptr->active)) | ||
1834 | goto cont; | ||
1835 | |||
1822 | /* Ensure message is well-formed */ | 1836 | /* Ensure message is well-formed */ |
1823 | 1837 | ||
1824 | if (unlikely(!link_recv_buf_validate(buf))) | 1838 | if (unlikely(!link_recv_buf_validate(buf))) |
@@ -1855,13 +1869,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1855 | goto cont; | 1869 | goto cont; |
1856 | } | 1870 | } |
1857 | 1871 | ||
1858 | /* Locate unicast link endpoint that should handle message */ | 1872 | /* Locate neighboring node that sent message */ |
1859 | 1873 | ||
1860 | n_ptr = tipc_node_find(msg_prevnode(msg)); | 1874 | n_ptr = tipc_node_find(msg_prevnode(msg)); |
1861 | if (unlikely(!n_ptr)) | 1875 | if (unlikely(!n_ptr)) |
1862 | goto cont; | 1876 | goto cont; |
1863 | tipc_node_lock(n_ptr); | 1877 | tipc_node_lock(n_ptr); |
1864 | 1878 | ||
1879 | /* Don't talk to neighbor during cleanup after last session */ | ||
1880 | |||
1881 | if (n_ptr->cleanup_required) { | ||
1882 | tipc_node_unlock(n_ptr); | ||
1883 | goto cont; | ||
1884 | } | ||
1885 | |||
1886 | /* Locate unicast link endpoint that should handle message */ | ||
1887 | |||
1865 | l_ptr = n_ptr->links[b_ptr->identity]; | 1888 | l_ptr = n_ptr->links[b_ptr->identity]; |
1866 | if (unlikely(!l_ptr)) { | 1889 | if (unlikely(!l_ptr)) { |
1867 | tipc_node_unlock(n_ptr); | 1890 | tipc_node_unlock(n_ptr); |