diff options
-rw-r--r-- | net/tipc/link.c | 61 | ||||
-rw-r--r-- | net/tipc/node.c | 5 |
2 files changed, 60 insertions, 6 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 20f128fc2be1..87bf5aad704b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/link.c: TIPC link code | 2 | * net/tipc/link.c: TIPC link code |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2007, Ericsson AB | 4 | * Copyright (c) 1996-2007, 2012, Ericsson AB |
5 | * Copyright (c) 2004-2007, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2004-2007, 2010-2011, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -103,6 +103,8 @@ static void link_reset_statistics(struct tipc_link *l_ptr); | |||
103 | static void link_print(struct tipc_link *l_ptr, const char *str); | 103 | static void link_print(struct tipc_link *l_ptr, const char *str); |
104 | static void link_start(struct tipc_link *l_ptr); | 104 | static void link_start(struct tipc_link *l_ptr); |
105 | static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf); | 105 | static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf); |
106 | static void tipc_link_send_sync(struct tipc_link *l); | ||
107 | static void tipc_link_recv_sync(struct tipc_node *n, struct sk_buff *buf); | ||
106 | 108 | ||
107 | /* | 109 | /* |
108 | * Simple link routines | 110 | * Simple link routines |
@@ -712,6 +714,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
712 | link_activate(l_ptr); | 714 | link_activate(l_ptr); |
713 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); | 715 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); |
714 | l_ptr->fsm_msg_cnt++; | 716 | l_ptr->fsm_msg_cnt++; |
717 | if (l_ptr->owner->working_links == 1) | ||
718 | tipc_link_send_sync(l_ptr); | ||
715 | link_set_timer(l_ptr, cont_intv); | 719 | link_set_timer(l_ptr, cont_intv); |
716 | break; | 720 | break; |
717 | case RESET_MSG: | 721 | case RESET_MSG: |
@@ -745,6 +749,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
745 | link_activate(l_ptr); | 749 | link_activate(l_ptr); |
746 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); | 750 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); |
747 | l_ptr->fsm_msg_cnt++; | 751 | l_ptr->fsm_msg_cnt++; |
752 | if (l_ptr->owner->working_links == 1) | ||
753 | tipc_link_send_sync(l_ptr); | ||
748 | link_set_timer(l_ptr, cont_intv); | 754 | link_set_timer(l_ptr, cont_intv); |
749 | break; | 755 | break; |
750 | case RESET_MSG: | 756 | case RESET_MSG: |
@@ -941,7 +947,48 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) | |||
941 | return res; | 947 | return res; |
942 | } | 948 | } |
943 | 949 | ||
944 | /** | 950 | /* |
951 | * tipc_link_send_sync - synchronize broadcast link endpoints. | ||
952 | * | ||
953 | * Give a newly added peer node the sequence number where it should | ||
954 | * start receiving and acking broadcast packets. | ||
955 | * | ||
956 | * Called with node locked | ||
957 | */ | ||
958 | static void tipc_link_send_sync(struct tipc_link *l) | ||
959 | { | ||
960 | struct sk_buff *buf; | ||
961 | struct tipc_msg *msg; | ||
962 | |||
963 | buf = tipc_buf_acquire(INT_H_SIZE); | ||
964 | if (!buf) | ||
965 | return; | ||
966 | |||
967 | msg = buf_msg(buf); | ||
968 | tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, l->addr); | ||
969 | msg_set_last_bcast(msg, l->owner->bclink.acked); | ||
970 | link_add_chain_to_outqueue(l, buf, 0); | ||
971 | tipc_link_push_queue(l); | ||
972 | } | ||
973 | |||
974 | /* | ||
975 | * tipc_link_recv_sync - synchronize broadcast link endpoints. | ||
976 | * Receive the sequence number where we should start receiving and | ||
977 | * acking broadcast packets from a newly added peer node, and open | ||
978 | * up for reception of such packets. | ||
979 | * | ||
980 | * Called with node locked | ||
981 | */ | ||
982 | static void tipc_link_recv_sync(struct tipc_node *n, struct sk_buff *buf) | ||
983 | { | ||
984 | struct tipc_msg *msg = buf_msg(buf); | ||
985 | |||
986 | n->bclink.last_sent = n->bclink.last_in = msg_last_bcast(msg); | ||
987 | n->bclink.recv_permitted = true; | ||
988 | kfree_skb(buf); | ||
989 | } | ||
990 | |||
991 | /* | ||
945 | * tipc_link_send_names - send name table entries to new neighbor | 992 | * tipc_link_send_names - send name table entries to new neighbor |
946 | * | 993 | * |
947 | * Send routine for bulk delivery of name table messages when contact | 994 | * Send routine for bulk delivery of name table messages when contact |
@@ -1691,9 +1738,14 @@ deliver: | |||
1691 | tipc_link_recv_bundle(buf); | 1738 | tipc_link_recv_bundle(buf); |
1692 | continue; | 1739 | continue; |
1693 | case NAME_DISTRIBUTOR: | 1740 | case NAME_DISTRIBUTOR: |
1741 | n_ptr->bclink.recv_permitted = true; | ||
1694 | tipc_node_unlock(n_ptr); | 1742 | tipc_node_unlock(n_ptr); |
1695 | tipc_named_recv(buf); | 1743 | tipc_named_recv(buf); |
1696 | continue; | 1744 | continue; |
1745 | case BCAST_PROTOCOL: | ||
1746 | tipc_link_recv_sync(n_ptr, buf); | ||
1747 | tipc_node_unlock(n_ptr); | ||
1748 | continue; | ||
1697 | case CONN_MANAGER: | 1749 | case CONN_MANAGER: |
1698 | tipc_node_unlock(n_ptr); | 1750 | tipc_node_unlock(n_ptr); |
1699 | tipc_port_recv_proto_msg(buf); | 1751 | tipc_port_recv_proto_msg(buf); |
@@ -1736,16 +1788,19 @@ deliver: | |||
1736 | continue; | 1788 | continue; |
1737 | } | 1789 | } |
1738 | 1790 | ||
1791 | /* Link is not in state WORKING_WORKING */ | ||
1739 | if (msg_user(msg) == LINK_PROTOCOL) { | 1792 | if (msg_user(msg) == LINK_PROTOCOL) { |
1740 | link_recv_proto_msg(l_ptr, buf); | 1793 | link_recv_proto_msg(l_ptr, buf); |
1741 | head = link_insert_deferred_queue(l_ptr, head); | 1794 | head = link_insert_deferred_queue(l_ptr, head); |
1742 | tipc_node_unlock(n_ptr); | 1795 | tipc_node_unlock(n_ptr); |
1743 | continue; | 1796 | continue; |
1744 | } | 1797 | } |
1798 | |||
1799 | /* Traffic message. Conditionally activate link */ | ||
1745 | link_state_event(l_ptr, TRAFFIC_MSG_EVT); | 1800 | link_state_event(l_ptr, TRAFFIC_MSG_EVT); |
1746 | 1801 | ||
1747 | if (link_working_working(l_ptr)) { | 1802 | if (link_working_working(l_ptr)) { |
1748 | /* Re-insert in front of queue */ | 1803 | /* Re-insert buffer in front of queue */ |
1749 | buf->next = head; | 1804 | buf->next = head; |
1750 | head = buf; | 1805 | head = buf; |
1751 | tipc_node_unlock(n_ptr); | 1806 | tipc_node_unlock(n_ptr); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index 283a59f0f1c8..48f39dd3eae8 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/node.c: TIPC node management routines | 2 | * net/tipc/node.c: TIPC node management routines |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2006, Ericsson AB | 4 | * Copyright (c) 2000-2006, 2012 Ericsson AB |
5 | * Copyright (c) 2005-2006, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2005-2006, 2010-2011, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -263,10 +263,9 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) | |||
263 | static void node_established_contact(struct tipc_node *n_ptr) | 263 | static void node_established_contact(struct tipc_node *n_ptr) |
264 | { | 264 | { |
265 | tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); | 265 | tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); |
266 | 266 | n_ptr->bclink.oos_state = 0; | |
267 | n_ptr->bclink.acked = tipc_bclink_get_last_sent(); | 267 | n_ptr->bclink.acked = tipc_bclink_get_last_sent(); |
268 | tipc_bclink_add_node(n_ptr->addr); | 268 | tipc_bclink_add_node(n_ptr->addr); |
269 | n_ptr->bclink.recv_permitted = true; | ||
270 | } | 269 | } |
271 | 270 | ||
272 | static void node_name_purge_complete(unsigned long node_addr) | 271 | static void node_name_purge_complete(unsigned long node_addr) |