aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c111
1 files changed, 80 insertions, 31 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index f89570c54f54..ae98a72da11a 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -332,15 +332,16 @@ struct link *tipc_link_create(struct tipc_node *n_ptr,
332 332
333 l_ptr->addr = peer; 333 l_ptr->addr = peer;
334 if_name = strchr(b_ptr->name, ':') + 1; 334 if_name = strchr(b_ptr->name, ':') + 1;
335 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 335 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), 336 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
337 tipc_node(tipc_own_addr), 337 tipc_node(tipc_own_addr),
338 if_name, 338 if_name,
339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 339 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
340 /* note: peer i/f is appended to link name by reset/activate */ 340 /* note: peer i/f name is updated by reset/activate message */
341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 341 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
342 l_ptr->owner = n_ptr; 342 l_ptr->owner = n_ptr;
343 l_ptr->checkpoint = 1; 343 l_ptr->checkpoint = 1;
344 l_ptr->peer_session = INVALID_SESSION;
344 l_ptr->b_ptr = b_ptr; 345 l_ptr->b_ptr = b_ptr;
345 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 346 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
346 l_ptr->state = RESET_UNKNOWN; 347 l_ptr->state = RESET_UNKNOWN;
@@ -536,9 +537,6 @@ void tipc_link_stop(struct link *l_ptr)
536 l_ptr->proto_msg_queue = NULL; 537 l_ptr->proto_msg_queue = NULL;
537} 538}
538 539
539/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */
540#define link_send_event(fcn, l_ptr, up) do { } while (0)
541
542void tipc_link_reset(struct link *l_ptr) 540void tipc_link_reset(struct link *l_ptr)
543{ 541{
544 struct sk_buff *buf; 542 struct sk_buff *buf;
@@ -596,10 +594,6 @@ void tipc_link_reset(struct link *l_ptr)
596 l_ptr->fsm_msg_cnt = 0; 594 l_ptr->fsm_msg_cnt = 0;
597 l_ptr->stale_count = 0; 595 l_ptr->stale_count = 0;
598 link_reset_statistics(l_ptr); 596 link_reset_statistics(l_ptr);
599
600 link_send_event(tipc_cfg_link_event, l_ptr, 0);
601 if (!in_own_cluster(l_ptr->addr))
602 link_send_event(tipc_disc_link_event, l_ptr, 0);
603} 597}
604 598
605 599
@@ -608,9 +602,6 @@ static void link_activate(struct link *l_ptr)
608 l_ptr->next_in_no = l_ptr->stats.recv_info = 1; 602 l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
609 tipc_node_link_up(l_ptr->owner, l_ptr); 603 tipc_node_link_up(l_ptr->owner, l_ptr);
610 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr); 604 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
611 link_send_event(tipc_cfg_link_event, l_ptr, 1);
612 if (!in_own_cluster(l_ptr->addr))
613 link_send_event(tipc_disc_link_event, l_ptr, 1);
614} 605}
615 606
616/** 607/**
@@ -985,6 +976,51 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
985} 976}
986 977
987/* 978/*
979 * tipc_link_send_names - send name table entries to new neighbor
980 *
981 * Send routine for bulk delivery of name table messages when contact
982 * with a new neighbor occurs. No link congestion checking is performed
983 * because name table messages *must* be delivered. The messages must be
984 * small enough not to require fragmentation.
985 * Called without any locks held.
986 */
987
988void tipc_link_send_names(struct list_head *message_list, u32 dest)
989{
990 struct tipc_node *n_ptr;
991 struct link *l_ptr;
992 struct sk_buff *buf;
993 struct sk_buff *temp_buf;
994
995 if (list_empty(message_list))
996 return;
997
998 read_lock_bh(&tipc_net_lock);
999 n_ptr = tipc_node_find(dest);
1000 if (n_ptr) {
1001 tipc_node_lock(n_ptr);
1002 l_ptr = n_ptr->active_links[0];
1003 if (l_ptr) {
1004 /* convert circular list to linear list */
1005 ((struct sk_buff *)message_list->prev)->next = NULL;
1006 link_add_chain_to_outqueue(l_ptr,
1007 (struct sk_buff *)message_list->next, 0);
1008 tipc_link_push_queue(l_ptr);
1009 INIT_LIST_HEAD(message_list);
1010 }
1011 tipc_node_unlock(n_ptr);
1012 }
1013 read_unlock_bh(&tipc_net_lock);
1014
1015 /* discard the messages if they couldn't be sent */
1016
1017 list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {
1018 list_del((struct list_head *)buf);
1019 buf_discard(buf);
1020 }
1021}
1022
1023/*
988 * link_send_buf_fast: Entry for data messages where the 1024 * link_send_buf_fast: Entry for data messages where the
989 * destination link is known and the header is complete, 1025 * destination link is known and the header is complete,
990 * inclusive total message length. Very time critical. 1026 * inclusive total message length. Very time critical.
@@ -1031,9 +1067,6 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1031 u32 selector = msg_origport(buf_msg(buf)) & 1; 1067 u32 selector = msg_origport(buf_msg(buf)) & 1;
1032 u32 dummy; 1068 u32 dummy;
1033 1069
1034 if (destnode == tipc_own_addr)
1035 return tipc_port_recv_msg(buf);
1036
1037 read_lock_bh(&tipc_net_lock); 1070 read_lock_bh(&tipc_net_lock);
1038 n_ptr = tipc_node_find(destnode); 1071 n_ptr = tipc_node_find(destnode);
1039 if (likely(n_ptr)) { 1072 if (likely(n_ptr)) {
@@ -1658,19 +1691,12 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1658 continue; 1691 continue;
1659 } 1692 }
1660 1693
1694 /* Discard unicast link messages destined for another node */
1695
1661 if (unlikely(!msg_short(msg) && 1696 if (unlikely(!msg_short(msg) &&
1662 (msg_destnode(msg) != tipc_own_addr))) 1697 (msg_destnode(msg) != tipc_own_addr)))
1663 goto cont; 1698 goto cont;
1664 1699
1665 /* Discard non-routeable messages destined for another node */
1666
1667 if (unlikely(!msg_isdata(msg) &&
1668 (msg_destnode(msg) != tipc_own_addr))) {
1669 if ((msg_user(msg) != CONN_MANAGER) &&
1670 (msg_user(msg) != MSG_FRAGMENTER))
1671 goto cont;
1672 }
1673
1674 /* Locate neighboring node that sent message */ 1700 /* Locate neighboring node that sent message */
1675 1701
1676 n_ptr = tipc_node_find(msg_prevnode(msg)); 1702 n_ptr = tipc_node_find(msg_prevnode(msg));
@@ -1678,17 +1704,24 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1678 goto cont; 1704 goto cont;
1679 tipc_node_lock(n_ptr); 1705 tipc_node_lock(n_ptr);
1680 1706
1681 /* Don't talk to neighbor during cleanup after last session */ 1707 /* Locate unicast link endpoint that should handle message */
1682 1708
1683 if (n_ptr->cleanup_required) { 1709 l_ptr = n_ptr->links[b_ptr->identity];
1710 if (unlikely(!l_ptr)) {
1684 tipc_node_unlock(n_ptr); 1711 tipc_node_unlock(n_ptr);
1685 goto cont; 1712 goto cont;
1686 } 1713 }
1687 1714
1688 /* Locate unicast link endpoint that should handle message */ 1715 /* Verify that communication with node is currently allowed */
1689 1716
1690 l_ptr = n_ptr->links[b_ptr->identity]; 1717 if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
1691 if (unlikely(!l_ptr)) { 1718 msg_user(msg) == LINK_PROTOCOL &&
1719 (msg_type(msg) == RESET_MSG ||
1720 msg_type(msg) == ACTIVATE_MSG) &&
1721 !msg_redundant_link(msg))
1722 n_ptr->block_setup &= ~WAIT_PEER_DOWN;
1723
1724 if (n_ptr->block_setup) {
1692 tipc_node_unlock(n_ptr); 1725 tipc_node_unlock(n_ptr);
1693 goto cont; 1726 goto cont;
1694 } 1727 }
@@ -1923,6 +1956,12 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg,
1923 1956
1924 if (link_blocked(l_ptr)) 1957 if (link_blocked(l_ptr))
1925 return; 1958 return;
1959
1960 /* Abort non-RESET send if communication with node is prohibited */
1961
1962 if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG))
1963 return;
1964
1926 msg_set_type(msg, msg_typ); 1965 msg_set_type(msg, msg_typ);
1927 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); 1966 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
1928 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); 1967 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in));
@@ -2051,9 +2090,19 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2051 case RESET_MSG: 2090 case RESET_MSG:
2052 if (!link_working_unknown(l_ptr) && 2091 if (!link_working_unknown(l_ptr) &&
2053 (l_ptr->peer_session != INVALID_SESSION)) { 2092 (l_ptr->peer_session != INVALID_SESSION)) {
2054 if (msg_session(msg) == l_ptr->peer_session) 2093 if (less_eq(msg_session(msg), l_ptr->peer_session))
2055 break; /* duplicate: ignore */ 2094 break; /* duplicate or old reset: ignore */
2095 }
2096
2097 if (!msg_redundant_link(msg) && (link_working_working(l_ptr) ||
2098 link_working_unknown(l_ptr))) {
2099 /*
2100 * peer has lost contact -- don't allow peer's links
2101 * to reactivate before we recognize loss & clean up
2102 */
2103 l_ptr->owner->block_setup = WAIT_NODE_DOWN;
2056 } 2104 }
2105
2057 /* fall thru' */ 2106 /* fall thru' */
2058 case ACTIVATE_MSG: 2107 case ACTIVATE_MSG:
2059 /* Update link settings according other endpoint's values */ 2108 /* Update link settings according other endpoint's values */