aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-02-09 16:20:53 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-09 16:20:53 -0500
commit9dce285b70c157754d753203112cfef22770b1f9 (patch)
tree4859799a8311ecd637e2a582600af1057a78e08b /net/tipc/node.c
parentc8ac18f2006b2926ce375c01646b2f487d1c33b2 (diff)
parent941787b82982b3f33ac398c8c00035ddd0f8c514 (diff)
Merge branch 'tipc-next'
Richard Alpe says: ==================== tipc: new compat layer for the legacy NL API This is a compatibility / transcoding layer for the old netlink API. It relies on the new netlink API to collect data or perform actions (dumpit / doit). The main benefit of this compat layer is that it removes a lot of complex code from the tipc core as only the new API needs to be able harness data or perform actions. I.e. the compat layer isn't concerned with locking or how the internal data-structures look. As long as the new API stays relatively intact the compat layer should be fine. The main challenge in this compat layer is the randomness of the legacy API. Some commands send binary data and some send ASCII data, some are very picky in optimizing there buffer sizes and some just don't care. Most legacy commands put there data in a single TLV (data container) but some segment the data into multiple TLV's. This list of randomness goes on and on.. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c131
1 files changed, 2 insertions, 129 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 52308498f208..86152de8248d 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "core.h" 37#include "core.h"
38#include "config.h" 38#include "link.h"
39#include "node.h" 39#include "node.h"
40#include "name_distr.h" 40#include "name_distr.h"
41#include "socket.h" 41#include "socket.h"
@@ -120,7 +120,6 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
120 list_add_tail_rcu(&n_ptr->list, &temp_node->list); 120 list_add_tail_rcu(&n_ptr->list, &temp_node->list);
121 n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN; 121 n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN;
122 n_ptr->signature = INVALID_NODE_SIG; 122 n_ptr->signature = INVALID_NODE_SIG;
123 tn->num_nodes++;
124exit: 123exit:
125 spin_unlock_bh(&tn->node_list_lock); 124 spin_unlock_bh(&tn->node_list_lock);
126 return n_ptr; 125 return n_ptr;
@@ -131,8 +130,6 @@ static void tipc_node_delete(struct tipc_net *tn, struct tipc_node *n_ptr)
131 list_del_rcu(&n_ptr->list); 130 list_del_rcu(&n_ptr->list);
132 hlist_del_rcu(&n_ptr->hash); 131 hlist_del_rcu(&n_ptr->hash);
133 kfree_rcu(n_ptr, rcu); 132 kfree_rcu(n_ptr, rcu);
134
135 tn->num_nodes--;
136} 133}
137 134
138void tipc_node_stop(struct net *net) 135void tipc_node_stop(struct net *net)
@@ -319,27 +316,18 @@ int tipc_node_is_up(struct tipc_node *n_ptr)
319 316
320void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 317void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
321{ 318{
322 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id);
323
324 n_ptr->links[l_ptr->bearer_id] = l_ptr; 319 n_ptr->links[l_ptr->bearer_id] = l_ptr;
325 spin_lock_bh(&tn->node_list_lock);
326 tn->num_links++;
327 spin_unlock_bh(&tn->node_list_lock);
328 n_ptr->link_cnt++; 320 n_ptr->link_cnt++;
329} 321}
330 322
331void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 323void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
332{ 324{
333 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id);
334 int i; 325 int i;
335 326
336 for (i = 0; i < MAX_BEARERS; i++) { 327 for (i = 0; i < MAX_BEARERS; i++) {
337 if (l_ptr != n_ptr->links[i]) 328 if (l_ptr != n_ptr->links[i])
338 continue; 329 continue;
339 n_ptr->links[i] = NULL; 330 n_ptr->links[i] = NULL;
340 spin_lock_bh(&tn->node_list_lock);
341 tn->num_links--;
342 spin_unlock_bh(&tn->node_list_lock);
343 n_ptr->link_cnt--; 331 n_ptr->link_cnt--;
344 } 332 }
345} 333}
@@ -416,121 +404,6 @@ static void node_lost_contact(struct tipc_node *n_ptr)
416 } 404 }
417} 405}
418 406
419struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area,
420 int req_tlv_space)
421{
422 struct tipc_net *tn = net_generic(net, tipc_net_id);
423 u32 domain;
424 struct sk_buff *buf;
425 struct tipc_node *n_ptr;
426 struct tipc_node_info node_info;
427 u32 payload_size;
428
429 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
430 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
431
432 domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
433 if (!tipc_addr_domain_valid(domain))
434 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
435 " (network address)");
436
437 spin_lock_bh(&tn->node_list_lock);
438 if (!tn->num_nodes) {
439 spin_unlock_bh(&tn->node_list_lock);
440 return tipc_cfg_reply_none();
441 }
442
443 /* For now, get space for all other nodes */
444 payload_size = TLV_SPACE(sizeof(node_info)) * tn->num_nodes;
445 if (payload_size > 32768u) {
446 spin_unlock_bh(&tn->node_list_lock);
447 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
448 " (too many nodes)");
449 }
450 spin_unlock_bh(&tn->node_list_lock);
451
452 buf = tipc_cfg_reply_alloc(payload_size);
453 if (!buf)
454 return NULL;
455
456 /* Add TLVs for all nodes in scope */
457 rcu_read_lock();
458 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
459 if (!tipc_in_scope(domain, n_ptr->addr))
460 continue;
461 node_info.addr = htonl(n_ptr->addr);
462 node_info.up = htonl(tipc_node_is_up(n_ptr));
463 tipc_cfg_append_tlv(buf, TIPC_TLV_NODE_INFO,
464 &node_info, sizeof(node_info));
465 }
466 rcu_read_unlock();
467 return buf;
468}
469
470struct sk_buff *tipc_node_get_links(struct net *net, const void *req_tlv_area,
471 int req_tlv_space)
472{
473 struct tipc_net *tn = net_generic(net, tipc_net_id);
474 u32 domain;
475 struct sk_buff *buf;
476 struct tipc_node *n_ptr;
477 struct tipc_link_info link_info;
478 u32 payload_size;
479
480 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
481 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
482
483 domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
484 if (!tipc_addr_domain_valid(domain))
485 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
486 " (network address)");
487
488 if (!tn->own_addr)
489 return tipc_cfg_reply_none();
490
491 spin_lock_bh(&tn->node_list_lock);
492 /* Get space for all unicast links + broadcast link */
493 payload_size = TLV_SPACE((sizeof(link_info)) * (tn->num_links + 1));
494 if (payload_size > 32768u) {
495 spin_unlock_bh(&tn->node_list_lock);
496 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
497 " (too many links)");
498 }
499 spin_unlock_bh(&tn->node_list_lock);
500
501 buf = tipc_cfg_reply_alloc(payload_size);
502 if (!buf)
503 return NULL;
504
505 /* Add TLV for broadcast link */
506 link_info.dest = htonl(tipc_cluster_mask(tn->own_addr));
507 link_info.up = htonl(1);
508 strlcpy(link_info.str, tipc_bclink_name, TIPC_MAX_LINK_NAME);
509 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
510
511 /* Add TLVs for any other links in scope */
512 rcu_read_lock();
513 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
514 u32 i;
515
516 if (!tipc_in_scope(domain, n_ptr->addr))
517 continue;
518 tipc_node_lock(n_ptr);
519 for (i = 0; i < MAX_BEARERS; i++) {
520 if (!n_ptr->links[i])
521 continue;
522 link_info.dest = htonl(n_ptr->addr);
523 link_info.up = htonl(tipc_link_is_up(n_ptr->links[i]));
524 strcpy(link_info.str, n_ptr->links[i]->name);
525 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO,
526 &link_info, sizeof(link_info));
527 }
528 tipc_node_unlock(n_ptr);
529 }
530 rcu_read_unlock();
531 return buf;
532}
533
534/** 407/**
535 * tipc_node_get_linkname - get the name of a link 408 * tipc_node_get_linkname - get the name of a link
536 * 409 *
@@ -623,7 +496,7 @@ static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
623 void *hdr; 496 void *hdr;
624 struct nlattr *attrs; 497 struct nlattr *attrs;
625 498
626 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, 499 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
627 NLM_F_MULTI, TIPC_NL_NODE_GET); 500 NLM_F_MULTI, TIPC_NL_NODE_GET);
628 if (!hdr) 501 if (!hdr)
629 return -EMSGSIZE; 502 return -EMSGSIZE;