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 | |
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>
-rw-r--r-- | include/uapi/linux/tipc_netlink.h | 1 | ||||
-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 |
5 files changed, 140 insertions, 0 deletions
diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index b9b710faa229..249ec7e9952c 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h | |||
@@ -43,6 +43,7 @@ enum { | |||
43 | TIPC_NL_LEGACY, | 43 | TIPC_NL_LEGACY, |
44 | TIPC_NL_BEARER_DISABLE, | 44 | TIPC_NL_BEARER_DISABLE, |
45 | TIPC_NL_BEARER_ENABLE, | 45 | TIPC_NL_BEARER_ENABLE, |
46 | TIPC_NL_BEARER_GET, | ||
46 | 47 | ||
47 | __TIPC_NL_CMD_MAX, | 48 | __TIPC_NL_CMD_MAX, |
48 | TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 | 49 | TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 |
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 |