diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 9aaa1bc566ae..d903f560e2fd 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, 2012-2015, Ericsson AB | 4 | * Copyright (c) 2000-2006, 2012-2016, Ericsson AB |
5 | * Copyright (c) 2005-2006, 2010-2014, Wind River Systems | 5 | * Copyright (c) 2005-2006, 2010-2014, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -191,6 +191,20 @@ int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel) | |||
191 | tipc_node_put(n); | 191 | tipc_node_put(n); |
192 | return mtu; | 192 | return mtu; |
193 | } | 193 | } |
194 | |||
195 | u16 tipc_node_get_capabilities(struct net *net, u32 addr) | ||
196 | { | ||
197 | struct tipc_node *n; | ||
198 | u16 caps; | ||
199 | |||
200 | n = tipc_node_find(net, addr); | ||
201 | if (unlikely(!n)) | ||
202 | return TIPC_NODE_CAPABILITIES; | ||
203 | caps = n->capabilities; | ||
204 | tipc_node_put(n); | ||
205 | return caps; | ||
206 | } | ||
207 | |||
194 | /* | 208 | /* |
195 | * A trivial power-of-two bitmask technique is used for speed, since this | 209 | * A trivial power-of-two bitmask technique is used for speed, since this |
196 | * operation is done for every incoming TIPC packet. The number of hash table | 210 | * operation is done for every incoming TIPC packet. The number of hash table |
@@ -304,8 +318,11 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities) | |||
304 | 318 | ||
305 | spin_lock_bh(&tn->node_list_lock); | 319 | spin_lock_bh(&tn->node_list_lock); |
306 | n = tipc_node_find(net, addr); | 320 | n = tipc_node_find(net, addr); |
307 | if (n) | 321 | if (n) { |
322 | /* Same node may come back with new capabilities */ | ||
323 | n->capabilities = capabilities; | ||
308 | goto exit; | 324 | goto exit; |
325 | } | ||
309 | n = kzalloc(sizeof(*n), GFP_ATOMIC); | 326 | n = kzalloc(sizeof(*n), GFP_ATOMIC); |
310 | if (!n) { | 327 | if (!n) { |
311 | pr_warn("Node creation failed, no memory\n"); | 328 | pr_warn("Node creation failed, no memory\n"); |
@@ -545,12 +562,16 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
545 | pr_debug("Established link <%s> on network plane %c\n", | 562 | pr_debug("Established link <%s> on network plane %c\n", |
546 | tipc_link_name(nl), tipc_link_plane(nl)); | 563 | tipc_link_name(nl), tipc_link_plane(nl)); |
547 | 564 | ||
565 | /* Ensure that a STATE message goes first */ | ||
566 | tipc_link_build_state_msg(nl, xmitq); | ||
567 | |||
548 | /* First link? => give it both slots */ | 568 | /* First link? => give it both slots */ |
549 | if (!ol) { | 569 | if (!ol) { |
550 | *slot0 = bearer_id; | 570 | *slot0 = bearer_id; |
551 | *slot1 = bearer_id; | 571 | *slot1 = bearer_id; |
552 | tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT); | 572 | tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT); |
553 | n->action_flags |= TIPC_NOTIFY_NODE_UP; | 573 | n->action_flags |= TIPC_NOTIFY_NODE_UP; |
574 | tipc_link_set_active(nl, true); | ||
554 | tipc_bcast_add_peer(n->net, nl, xmitq); | 575 | tipc_bcast_add_peer(n->net, nl, xmitq); |
555 | return; | 576 | return; |
556 | } | 577 | } |
@@ -581,8 +602,12 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
581 | static void tipc_node_link_up(struct tipc_node *n, int bearer_id, | 602 | static void tipc_node_link_up(struct tipc_node *n, int bearer_id, |
582 | struct sk_buff_head *xmitq) | 603 | struct sk_buff_head *xmitq) |
583 | { | 604 | { |
605 | struct tipc_media_addr *maddr; | ||
606 | |||
584 | tipc_node_write_lock(n); | 607 | tipc_node_write_lock(n); |
585 | __tipc_node_link_up(n, bearer_id, xmitq); | 608 | __tipc_node_link_up(n, bearer_id, xmitq); |
609 | maddr = &n->links[bearer_id].maddr; | ||
610 | tipc_bearer_xmit(n->net, bearer_id, xmitq, maddr); | ||
586 | tipc_node_write_unlock(n); | 611 | tipc_node_write_unlock(n); |
587 | } | 612 | } |
588 | 613 | ||
@@ -1279,7 +1304,7 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id | |||
1279 | /* Broadcast ACKs are sent on a unicast link */ | 1304 | /* Broadcast ACKs are sent on a unicast link */ |
1280 | if (rc & TIPC_LINK_SND_BC_ACK) { | 1305 | if (rc & TIPC_LINK_SND_BC_ACK) { |
1281 | tipc_node_read_lock(n); | 1306 | tipc_node_read_lock(n); |
1282 | tipc_link_build_ack_msg(le->link, &xmitq); | 1307 | tipc_link_build_state_msg(le->link, &xmitq); |
1283 | tipc_node_read_unlock(n); | 1308 | tipc_node_read_unlock(n); |
1284 | } | 1309 | } |
1285 | 1310 | ||