diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 111 |
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 | |||
542 | void tipc_link_reset(struct link *l_ptr) | 540 | void 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 | |||
988 | void 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 */ |