diff options
| author | Richard Alpe <richard.alpe@ericsson.com> | 2014-11-20 04:29:08 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-11-21 15:01:29 -0500 |
| commit | 35b9dd7607f049466a66427e58818b29aeae9ea7 (patch) | |
| tree | a196d3a4323d4fe9bf265858fad61e7b5aebcb85 /net/tipc | |
| parent | 0655f6a8635b1b66f2434d5556b1044c14b1ccaf (diff) | |
tipc: add bearer get/dump to new netlink api
Add TIPC_NL_BEARER_GET command to the new tipc netlink API.
This command supports dumping all data about all bearers or getting
all information about a specific bearer.
The information about a bearer includes name, link priorities and
domain.
Netlink logical layout of bearer get message:
-> bearer
-> name
Netlink logical layout of returned bearer information:
-> bearer
-> name
-> link properties
-> priority
-> tolerance
-> window
-> domain
Signed-off-by: Richard Alpe <richard.alpe@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/bearer.c | 125 | ||||
| -rw-r--r-- | net/tipc/bearer.h | 2 | ||||
| -rw-r--r-- | net/tipc/netlink.c | 6 | ||||
| -rw-r--r-- | net/tipc/netlink.h | 6 |
4 files changed, 139 insertions, 0 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 59815be0ab98..d49b8c25dd11 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
| @@ -640,6 +640,131 @@ void tipc_bearer_stop(void) | |||
| 640 | } | 640 | } |
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | /* Caller should hold rtnl_lock to protect the bearer */ | ||
| 644 | int __tipc_nl_add_bearer(struct tipc_nl_msg *msg, struct tipc_bearer *bearer) | ||
| 645 | { | ||
| 646 | void *hdr; | ||
| 647 | struct nlattr *attrs; | ||
| 648 | struct nlattr *prop; | ||
| 649 | |||
| 650 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family, | ||
| 651 | NLM_F_MULTI, TIPC_NL_BEARER_GET); | ||
| 652 | if (!hdr) | ||
| 653 | return -EMSGSIZE; | ||
| 654 | |||
| 655 | attrs = nla_nest_start(msg->skb, TIPC_NLA_BEARER); | ||
| 656 | if (!attrs) | ||
| 657 | goto msg_full; | ||
| 658 | |||
| 659 | if (nla_put_string(msg->skb, TIPC_NLA_BEARER_NAME, bearer->name)) | ||
| 660 | goto attr_msg_full; | ||
| 661 | |||
| 662 | prop = nla_nest_start(msg->skb, TIPC_NLA_BEARER_PROP); | ||
| 663 | if (!prop) | ||
| 664 | goto prop_msg_full; | ||
| 665 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, bearer->priority)) | ||
| 666 | goto prop_msg_full; | ||
| 667 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, bearer->tolerance)) | ||
| 668 | goto prop_msg_full; | ||
| 669 | if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bearer->window)) | ||
| 670 | goto prop_msg_full; | ||
| 671 | |||
| 672 | nla_nest_end(msg->skb, prop); | ||
| 673 | nla_nest_end(msg->skb, attrs); | ||
| 674 | genlmsg_end(msg->skb, hdr); | ||
| 675 | |||
| 676 | return 0; | ||
| 677 | |||
| 678 | prop_msg_full: | ||
| 679 | nla_nest_cancel(msg->skb, prop); | ||
| 680 | attr_msg_full: | ||
| 681 | nla_nest_cancel(msg->skb, attrs); | ||
| 682 | msg_full: | ||
| 683 | genlmsg_cancel(msg->skb, hdr); | ||
| 684 | |||
| 685 | return -EMSGSIZE; | ||
| 686 | } | ||
| 687 | |||
| 688 | int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb) | ||
| 689 | { | ||
| 690 | int err; | ||
| 691 | int i = cb->args[0]; | ||
| 692 | struct tipc_bearer *bearer; | ||
| 693 | struct tipc_nl_msg msg; | ||
| 694 | |||
| 695 | if (i == MAX_BEARERS) | ||
| 696 | return 0; | ||
| 697 | |||
| 698 | msg.skb = skb; | ||
| 699 | msg.portid = NETLINK_CB(cb->skb).portid; | ||
| 700 | msg.seq = cb->nlh->nlmsg_seq; | ||
| 701 | |||
| 702 | rtnl_lock(); | ||
| 703 | for (i = 0; i < MAX_BEARERS; i++) { | ||
| 704 | bearer = rtnl_dereference(bearer_list[i]); | ||
| 705 | if (!bearer) | ||
| 706 | continue; | ||
| 707 | |||
| 708 | err = __tipc_nl_add_bearer(&msg, bearer); | ||
| 709 | if (err) | ||
| 710 | break; | ||
| 711 | } | ||
| 712 | rtnl_unlock(); | ||
| 713 | |||
| 714 | cb->args[0] = i; | ||
| 715 | return skb->len; | ||
| 716 | } | ||
| 717 | |||
| 718 | int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info) | ||
| 719 | { | ||
| 720 | int err; | ||
| 721 | char *name; | ||
| 722 | struct sk_buff *rep; | ||
| 723 | struct tipc_bearer *bearer; | ||
| 724 | struct tipc_nl_msg msg; | ||
| 725 | struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; | ||
| 726 | |||
| 727 | if (!info->attrs[TIPC_NLA_BEARER]) | ||
| 728 | return -EINVAL; | ||
| 729 | |||
| 730 | err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX, | ||
| 731 | info->attrs[TIPC_NLA_BEARER], | ||
| 732 | tipc_nl_bearer_policy); | ||
| 733 | if (err) | ||
| 734 | return err; | ||
| 735 | |||
| 736 | if (!attrs[TIPC_NLA_BEARER_NAME]) | ||
| 737 | return -EINVAL; | ||
| 738 | name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); | ||
| 739 | |||
| 740 | rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
| 741 | if (!rep) | ||
| 742 | return -ENOMEM; | ||
| 743 | |||
| 744 | msg.skb = rep; | ||
| 745 | msg.portid = info->snd_portid; | ||
| 746 | msg.seq = info->snd_seq; | ||
| 747 | |||
| 748 | rtnl_lock(); | ||
| 749 | bearer = tipc_bearer_find(name); | ||
| 750 | if (!bearer) { | ||
| 751 | err = -EINVAL; | ||
| 752 | goto err_out; | ||
| 753 | } | ||
| 754 | |||
| 755 | err = __tipc_nl_add_bearer(&msg, bearer); | ||
| 756 | if (err) | ||
| 757 | goto err_out; | ||
| 758 | rtnl_unlock(); | ||
| 759 | |||
| 760 | return genlmsg_reply(rep, info); | ||
| 761 | err_out: | ||
| 762 | rtnl_unlock(); | ||
| 763 | nlmsg_free(rep); | ||
| 764 | |||
| 765 | return err; | ||
| 766 | } | ||
| 767 | |||
| 643 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) | 768 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) |
| 644 | { | 769 | { |
| 645 | int err; | 770 | int err; |
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index a87e8c78d862..2d07e35f91fc 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
| @@ -180,6 +180,8 @@ extern struct tipc_media ib_media_info; | |||
| 180 | 180 | ||
| 181 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); | 181 | int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info); |
| 182 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); | 182 | int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info); |
| 183 | int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb); | ||
| 184 | int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info); | ||
| 183 | 185 | ||
| 184 | int tipc_media_set_priority(const char *name, u32 new_value); | 186 | int tipc_media_set_priority(const char *name, u32 new_value); |
| 185 | int tipc_media_set_window(const char *name, u32 new_value); | 187 | int tipc_media_set_window(const char *name, u32 new_value); |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index af506ae0a129..0c00422512fa 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
| @@ -112,6 +112,12 @@ static const struct genl_ops tipc_genl_v2_ops[] = { | |||
| 112 | .cmd = TIPC_NL_BEARER_ENABLE, | 112 | .cmd = TIPC_NL_BEARER_ENABLE, |
| 113 | .doit = tipc_nl_bearer_enable, | 113 | .doit = tipc_nl_bearer_enable, |
| 114 | .policy = tipc_nl_policy, | 114 | .policy = tipc_nl_policy, |
| 115 | }, | ||
| 116 | { | ||
| 117 | .cmd = TIPC_NL_BEARER_GET, | ||
| 118 | .doit = tipc_nl_bearer_get, | ||
| 119 | .dumpit = tipc_nl_bearer_dump, | ||
| 120 | .policy = tipc_nl_policy, | ||
| 115 | } | 121 | } |
| 116 | }; | 122 | }; |
| 117 | 123 | ||
diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h index e9980c0e2207..e34a3fca7d3d 100644 --- a/net/tipc/netlink.h +++ b/net/tipc/netlink.h | |||
| @@ -38,4 +38,10 @@ | |||
| 38 | 38 | ||
| 39 | extern struct genl_family tipc_genl_v2_family; | 39 | extern struct genl_family tipc_genl_v2_family; |
| 40 | 40 | ||
| 41 | struct tipc_nl_msg { | ||
| 42 | struct sk_buff *skb; | ||
| 43 | u32 portid; | ||
| 44 | u32 seq; | ||
| 45 | }; | ||
| 46 | |||
| 41 | #endif | 47 | #endif |
