diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 89fbb6d6e956..43639ff1cbec 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -293,19 +293,35 @@ static void link_set_timer(struct link *l_ptr, u32 time) | |||
293 | 293 | ||
294 | /** | 294 | /** |
295 | * tipc_link_create - create a new link | 295 | * tipc_link_create - create a new link |
296 | * @n_ptr: pointer to associated node | ||
296 | * @b_ptr: pointer to associated bearer | 297 | * @b_ptr: pointer to associated bearer |
297 | * @peer: network address of node at other end of link | ||
298 | * @media_addr: media address to use when sending messages over link | 298 | * @media_addr: media address to use when sending messages over link |
299 | * | 299 | * |
300 | * Returns pointer to link. | 300 | * Returns pointer to link. |
301 | */ | 301 | */ |
302 | 302 | ||
303 | struct link *tipc_link_create(struct tipc_bearer *b_ptr, const u32 peer, | 303 | struct link *tipc_link_create(struct tipc_node *n_ptr, |
304 | struct tipc_bearer *b_ptr, | ||
304 | const struct tipc_media_addr *media_addr) | 305 | const struct tipc_media_addr *media_addr) |
305 | { | 306 | { |
306 | struct link *l_ptr; | 307 | struct link *l_ptr; |
307 | struct tipc_msg *msg; | 308 | struct tipc_msg *msg; |
308 | char *if_name; | 309 | char *if_name; |
310 | char addr_string[16]; | ||
311 | u32 peer = n_ptr->addr; | ||
312 | |||
313 | if (n_ptr->link_cnt >= 2) { | ||
314 | tipc_addr_string_fill(addr_string, n_ptr->addr); | ||
315 | err("Attempt to establish third link to %s\n", addr_string); | ||
316 | return NULL; | ||
317 | } | ||
318 | |||
319 | if (n_ptr->links[b_ptr->identity]) { | ||
320 | tipc_addr_string_fill(addr_string, n_ptr->addr); | ||
321 | err("Attempt to establish second link on <%s> to %s\n", | ||
322 | b_ptr->name, addr_string); | ||
323 | return NULL; | ||
324 | } | ||
309 | 325 | ||
310 | l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); | 326 | l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); |
311 | if (!l_ptr) { | 327 | if (!l_ptr) { |
@@ -322,6 +338,7 @@ struct link *tipc_link_create(struct tipc_bearer *b_ptr, const u32 peer, | |||
322 | tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); | 338 | tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); |
323 | /* note: peer i/f is appended to link name by reset/activate */ | 339 | /* note: peer i/f is appended to link name by reset/activate */ |
324 | memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); | 340 | memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); |
341 | l_ptr->owner = n_ptr; | ||
325 | l_ptr->checkpoint = 1; | 342 | l_ptr->checkpoint = 1; |
326 | l_ptr->b_ptr = b_ptr; | 343 | l_ptr->b_ptr = b_ptr; |
327 | link_set_supervision_props(l_ptr, b_ptr->media->tolerance); | 344 | link_set_supervision_props(l_ptr, b_ptr->media->tolerance); |
@@ -345,11 +362,7 @@ struct link *tipc_link_create(struct tipc_bearer *b_ptr, const u32 peer, | |||
345 | 362 | ||
346 | link_reset_statistics(l_ptr); | 363 | link_reset_statistics(l_ptr); |
347 | 364 | ||
348 | l_ptr->owner = tipc_node_attach_link(l_ptr); | 365 | tipc_node_attach_link(n_ptr, l_ptr); |
349 | if (!l_ptr->owner) { | ||
350 | kfree(l_ptr); | ||
351 | return NULL; | ||
352 | } | ||
353 | 366 | ||
354 | k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); | 367 | k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); |
355 | list_add_tail(&l_ptr->link_list, &b_ptr->links); | 368 | list_add_tail(&l_ptr->link_list, &b_ptr->links); |
@@ -548,7 +561,7 @@ void tipc_link_reset(struct link *l_ptr) | |||
548 | tipc_node_link_down(l_ptr->owner, l_ptr); | 561 | tipc_node_link_down(l_ptr->owner, l_ptr); |
549 | tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); | 562 | tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); |
550 | 563 | ||
551 | if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && | 564 | if (was_active_link && tipc_node_active_links(l_ptr->owner) && |
552 | l_ptr->owner->permit_changeover) { | 565 | l_ptr->owner->permit_changeover) { |
553 | l_ptr->reset_checkpoint = checkpoint; | 566 | l_ptr->reset_checkpoint = checkpoint; |
554 | l_ptr->exp_msg_count = START_CHANGEOVER; | 567 | l_ptr->exp_msg_count = START_CHANGEOVER; |
@@ -1733,10 +1746,6 @@ deliver: | |||
1733 | tipc_node_unlock(n_ptr); | 1746 | tipc_node_unlock(n_ptr); |
1734 | tipc_link_recv_bundle(buf); | 1747 | tipc_link_recv_bundle(buf); |
1735 | continue; | 1748 | continue; |
1736 | case ROUTE_DISTRIBUTOR: | ||
1737 | tipc_node_unlock(n_ptr); | ||
1738 | buf_discard(buf); | ||
1739 | continue; | ||
1740 | case NAME_DISTRIBUTOR: | 1749 | case NAME_DISTRIBUTOR: |
1741 | tipc_node_unlock(n_ptr); | 1750 | tipc_node_unlock(n_ptr); |
1742 | tipc_named_recv(buf); | 1751 | tipc_named_recv(buf); |
@@ -1763,6 +1772,10 @@ deliver: | |||
1763 | goto protocol_check; | 1772 | goto protocol_check; |
1764 | } | 1773 | } |
1765 | break; | 1774 | break; |
1775 | default: | ||
1776 | buf_discard(buf); | ||
1777 | buf = NULL; | ||
1778 | break; | ||
1766 | } | 1779 | } |
1767 | } | 1780 | } |
1768 | tipc_node_unlock(n_ptr); | 1781 | tipc_node_unlock(n_ptr); |
@@ -1898,6 +1911,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
1898 | struct sk_buff *buf = NULL; | 1911 | struct sk_buff *buf = NULL; |
1899 | struct tipc_msg *msg = l_ptr->pmsg; | 1912 | struct tipc_msg *msg = l_ptr->pmsg; |
1900 | u32 msg_size = sizeof(l_ptr->proto_msg); | 1913 | u32 msg_size = sizeof(l_ptr->proto_msg); |
1914 | int r_flag; | ||
1901 | 1915 | ||
1902 | if (link_blocked(l_ptr)) | 1916 | if (link_blocked(l_ptr)) |
1903 | return; | 1917 | return; |
@@ -1954,10 +1968,8 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
1954 | msg_set_max_pkt(msg, l_ptr->max_pkt_target); | 1968 | msg_set_max_pkt(msg, l_ptr->max_pkt_target); |
1955 | } | 1969 | } |
1956 | 1970 | ||
1957 | if (tipc_node_has_redundant_links(l_ptr->owner)) | 1971 | r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); |
1958 | msg_set_redundant_link(msg); | 1972 | msg_set_redundant_link(msg, r_flag); |
1959 | else | ||
1960 | msg_clear_redundant_link(msg); | ||
1961 | msg_set_linkprio(msg, l_ptr->priority); | 1973 | msg_set_linkprio(msg, l_ptr->priority); |
1962 | 1974 | ||
1963 | /* Ensure sequence number will not fit : */ | 1975 | /* Ensure sequence number will not fit : */ |
@@ -1977,7 +1989,6 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
1977 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 1989 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
1978 | return; | 1990 | return; |
1979 | } | 1991 | } |
1980 | msg_set_timestamp(msg, jiffies_to_msecs(jiffies)); | ||
1981 | 1992 | ||
1982 | /* Message can be sent */ | 1993 | /* Message can be sent */ |
1983 | 1994 | ||
@@ -2065,7 +2076,7 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2065 | l_ptr->peer_bearer_id = msg_bearer_id(msg); | 2076 | l_ptr->peer_bearer_id = msg_bearer_id(msg); |
2066 | 2077 | ||
2067 | /* Synchronize broadcast sequence numbers */ | 2078 | /* Synchronize broadcast sequence numbers */ |
2068 | if (!tipc_node_has_redundant_links(l_ptr->owner)) | 2079 | if (!tipc_node_redundant_links(l_ptr->owner)) |
2069 | l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); | 2080 | l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); |
2070 | break; | 2081 | break; |
2071 | case STATE_MSG: | 2082 | case STATE_MSG: |
@@ -2412,9 +2423,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2412 | else | 2423 | else |
2413 | destaddr = msg_destnode(inmsg); | 2424 | destaddr = msg_destnode(inmsg); |
2414 | 2425 | ||
2415 | if (msg_routed(inmsg)) | ||
2416 | msg_set_prevnode(inmsg, tipc_own_addr); | ||
2417 | |||
2418 | /* Prepare reusable fragment header: */ | 2426 | /* Prepare reusable fragment header: */ |
2419 | 2427 | ||
2420 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 2428 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |