aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-12 17:27:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-12 17:27:40 -0400
commitf9da455b93f6ba076935b4ef4589f61e529ae046 (patch)
tree3c4e69ce1ba1d6bf65915b97a76ca2172105b278 /net/tipc/node.c
parent0e04c641b199435f3779454055f6a7de258ecdfc (diff)
parente5eca6d41f53db48edd8cf88a3f59d2c30227f8e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Seccomp BPF filters can now be JIT'd, from Alexei Starovoitov. 2) Multiqueue support in xen-netback and xen-netfront, from Andrew J Benniston. 3) Allow tweaking of aggregation settings in cdc_ncm driver, from Bjørn Mork. 4) BPF now has a "random" opcode, from Chema Gonzalez. 5) Add more BPF documentation and improve test framework, from Daniel Borkmann. 6) Support TCP fastopen over ipv6, from Daniel Lee. 7) Add software TSO helper functions and use them to support software TSO in mvneta and mv643xx_eth drivers. From Ezequiel Garcia. 8) Support software TSO in fec driver too, from Nimrod Andy. 9) Add Broadcom SYSTEMPORT driver, from Florian Fainelli. 10) Handle broadcasts more gracefully over macvlan when there are large numbers of interfaces configured, from Herbert Xu. 11) Allow more control over fwmark used for non-socket based responses, from Lorenzo Colitti. 12) Do TCP congestion window limiting based upon measurements, from Neal Cardwell. 13) Support busy polling in SCTP, from Neal Horman. 14) Allow RSS key to be configured via ethtool, from Venkata Duvvuru. 15) Bridge promisc mode handling improvements from Vlad Yasevich. 16) Don't use inetpeer entries to implement ID generation any more, it performs poorly, from Eric Dumazet. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1522 commits) rtnetlink: fix userspace API breakage for iproute2 < v3.9.0 tcp: fixing TLP's FIN recovery net: fec: Add software TSO support net: fec: Add Scatter/gather support net: fec: Increase buffer descriptor entry number net: fec: Factorize feature setting net: fec: Enable IP header hardware checksum net: fec: Factorize the .xmit transmit function bridge: fix compile error when compiling without IPv6 support bridge: fix smatch warning / potential null pointer dereference via-rhine: fix full-duplex with autoneg disable bnx2x: Enlarge the dorq threshold for VFs bnx2x: Check for UNDI in uncommon branch bnx2x: Fix 1G-baseT link bnx2x: Fix link for KR with swapped polarity lane sctp: Fix sk_ack_backlog wrap-around problem net/core: Add VF link state control policy net/fsl: xgmac_mdio is dependent on OF_MDIO net/fsl: Make xgmac_mdio read error message useful net_sched: drr: warn when qdisc is not work conserving ...
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c110
1 files changed, 80 insertions, 30 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 1d3a4999a70f..5b44c3041be4 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -108,7 +108,7 @@ struct tipc_node *tipc_node_create(u32 addr)
108 break; 108 break;
109 } 109 }
110 list_add_tail_rcu(&n_ptr->list, &temp_node->list); 110 list_add_tail_rcu(&n_ptr->list, &temp_node->list);
111 n_ptr->block_setup = WAIT_PEER_DOWN; 111 n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN;
112 n_ptr->signature = INVALID_NODE_SIG; 112 n_ptr->signature = INVALID_NODE_SIG;
113 113
114 tipc_num_nodes++; 114 tipc_num_nodes++;
@@ -144,11 +144,13 @@ void tipc_node_stop(void)
144void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 144void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
145{ 145{
146 struct tipc_link **active = &n_ptr->active_links[0]; 146 struct tipc_link **active = &n_ptr->active_links[0];
147 u32 addr = n_ptr->addr;
147 148
148 n_ptr->working_links++; 149 n_ptr->working_links++;
149 150 tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE,
151 l_ptr->bearer_id, addr);
150 pr_info("Established link <%s> on network plane %c\n", 152 pr_info("Established link <%s> on network plane %c\n",
151 l_ptr->name, l_ptr->b_ptr->net_plane); 153 l_ptr->name, l_ptr->net_plane);
152 154
153 if (!active[0]) { 155 if (!active[0]) {
154 active[0] = active[1] = l_ptr; 156 active[0] = active[1] = l_ptr;
@@ -203,16 +205,18 @@ static void node_select_active_links(struct tipc_node *n_ptr)
203void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 205void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
204{ 206{
205 struct tipc_link **active; 207 struct tipc_link **active;
208 u32 addr = n_ptr->addr;
206 209
207 n_ptr->working_links--; 210 n_ptr->working_links--;
211 tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr);
208 212
209 if (!tipc_link_is_active(l_ptr)) { 213 if (!tipc_link_is_active(l_ptr)) {
210 pr_info("Lost standby link <%s> on network plane %c\n", 214 pr_info("Lost standby link <%s> on network plane %c\n",
211 l_ptr->name, l_ptr->b_ptr->net_plane); 215 l_ptr->name, l_ptr->net_plane);
212 return; 216 return;
213 } 217 }
214 pr_info("Lost link <%s> on network plane %c\n", 218 pr_info("Lost link <%s> on network plane %c\n",
215 l_ptr->name, l_ptr->b_ptr->net_plane); 219 l_ptr->name, l_ptr->net_plane);
216 220
217 active = &n_ptr->active_links[0]; 221 active = &n_ptr->active_links[0];
218 if (active[0] == l_ptr) 222 if (active[0] == l_ptr)
@@ -239,7 +243,7 @@ int tipc_node_is_up(struct tipc_node *n_ptr)
239 243
240void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 244void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
241{ 245{
242 n_ptr->links[l_ptr->b_ptr->identity] = l_ptr; 246 n_ptr->links[l_ptr->bearer_id] = l_ptr;
243 spin_lock_bh(&node_list_lock); 247 spin_lock_bh(&node_list_lock);
244 tipc_num_links++; 248 tipc_num_links++;
245 spin_unlock_bh(&node_list_lock); 249 spin_unlock_bh(&node_list_lock);
@@ -263,26 +267,12 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
263 267
264static void node_established_contact(struct tipc_node *n_ptr) 268static void node_established_contact(struct tipc_node *n_ptr)
265{ 269{
266 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); 270 n_ptr->action_flags |= TIPC_NOTIFY_NODE_UP;
267 n_ptr->bclink.oos_state = 0; 271 n_ptr->bclink.oos_state = 0;
268 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 272 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
269 tipc_bclink_add_node(n_ptr->addr); 273 tipc_bclink_add_node(n_ptr->addr);
270} 274}
271 275
272static void node_name_purge_complete(unsigned long node_addr)
273{
274 struct tipc_node *n_ptr;
275
276 read_lock_bh(&tipc_net_lock);
277 n_ptr = tipc_node_find(node_addr);
278 if (n_ptr) {
279 tipc_node_lock(n_ptr);
280 n_ptr->block_setup &= ~WAIT_NAMES_GONE;
281 tipc_node_unlock(n_ptr);
282 }
283 read_unlock_bh(&tipc_net_lock);
284}
285
286static void node_lost_contact(struct tipc_node *n_ptr) 276static void node_lost_contact(struct tipc_node *n_ptr)
287{ 277{
288 char addr_string[16]; 278 char addr_string[16];
@@ -296,10 +286,9 @@ static void node_lost_contact(struct tipc_node *n_ptr)
296 kfree_skb_list(n_ptr->bclink.deferred_head); 286 kfree_skb_list(n_ptr->bclink.deferred_head);
297 n_ptr->bclink.deferred_size = 0; 287 n_ptr->bclink.deferred_size = 0;
298 288
299 if (n_ptr->bclink.reasm_head) { 289 if (n_ptr->bclink.reasm_buf) {
300 kfree_skb(n_ptr->bclink.reasm_head); 290 kfree_skb(n_ptr->bclink.reasm_buf);
301 n_ptr->bclink.reasm_head = NULL; 291 n_ptr->bclink.reasm_buf = NULL;
302 n_ptr->bclink.reasm_tail = NULL;
303 } 292 }
304 293
305 tipc_bclink_remove_node(n_ptr->addr); 294 tipc_bclink_remove_node(n_ptr->addr);
@@ -318,12 +307,13 @@ static void node_lost_contact(struct tipc_node *n_ptr)
318 tipc_link_reset_fragments(l_ptr); 307 tipc_link_reset_fragments(l_ptr);
319 } 308 }
320 309
321 /* Notify subscribers */ 310 n_ptr->action_flags &= ~TIPC_WAIT_OWN_LINKS_DOWN;
322 tipc_nodesub_notify(n_ptr);
323 311
324 /* Prevent re-contact with node until cleanup is done */ 312 /* Notify subscribers and prevent re-contact with node until
325 n_ptr->block_setup = WAIT_PEER_DOWN | WAIT_NAMES_GONE; 313 * cleanup is done.
326 tipc_k_signal((Handler)node_name_purge_complete, n_ptr->addr); 314 */
315 n_ptr->action_flags |= TIPC_WAIT_PEER_LINKS_DOWN |
316 TIPC_NOTIFY_NODE_DOWN;
327} 317}
328 318
329struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) 319struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
@@ -436,3 +426,63 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
436 rcu_read_unlock(); 426 rcu_read_unlock();
437 return buf; 427 return buf;
438} 428}
429
430/**
431 * tipc_node_get_linkname - get the name of a link
432 *
433 * @bearer_id: id of the bearer
434 * @node: peer node address
435 * @linkname: link name output buffer
436 *
437 * Returns 0 on success
438 */
439int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
440{
441 struct tipc_link *link;
442 struct tipc_node *node = tipc_node_find(addr);
443
444 if ((bearer_id >= MAX_BEARERS) || !node)
445 return -EINVAL;
446 tipc_node_lock(node);
447 link = node->links[bearer_id];
448 if (link) {
449 strncpy(linkname, link->name, len);
450 tipc_node_unlock(node);
451 return 0;
452 }
453 tipc_node_unlock(node);
454 return -EINVAL;
455}
456
457void tipc_node_unlock(struct tipc_node *node)
458{
459 LIST_HEAD(nsub_list);
460 struct tipc_link *link;
461 int pkt_sz = 0;
462 u32 addr = 0;
463
464 if (likely(!node->action_flags)) {
465 spin_unlock_bh(&node->lock);
466 return;
467 }
468
469 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
470 list_replace_init(&node->nsub, &nsub_list);
471 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
472 }
473 if (node->action_flags & TIPC_NOTIFY_NODE_UP) {
474 link = node->active_links[0];
475 node->action_flags &= ~TIPC_NOTIFY_NODE_UP;
476 if (link) {
477 pkt_sz = ((link->max_pkt - INT_H_SIZE) / ITEM_SIZE) *
478 ITEM_SIZE;
479 addr = node->addr;
480 }
481 }
482 spin_unlock_bh(&node->lock);
483
484 if (!list_empty(&nsub_list))
485 tipc_nodesub_notify(&nsub_list);
486 if (pkt_sz)
487 tipc_named_node_up(pkt_sz, addr);
488}