tipc: add support for broadcast rcv stats dumping
This commit enables dumping the statistics of a broadcast-receiver link like the traditional 'broadcast-link' one (which is for broadcast- sender). The link dumping can be triggered via netlink (e.g. the iproute2/tipc tool) by the link flag - 'TIPC_NLA_LINK_BROADCAST' as the indicator. The name of a broadcast-receiver link of a specific peer will be in the format: 'broadcast-link:<peer-id>'. For example: Link <broadcast-link:1001002> Window:50 packets RX packets:7841 fragments:2408/440 bundles:0/0 TX packets:0 fragments:0/0 bundles:0/0 RX naks:0 defs:124 dups:0 TX naks:21 acks:0 retrans:0 Congestion link:0 Send queue max:0 avg:0 In addition, the broadcast-receiver link statistics can be reset in the usual way via netlink by specifying that link name in command. Note: the 'tipc_link_name_ext()' is removed because the link name can now be retrieved simply via the 'l->name'. Acked-by: Ying Xue <ying.xue@windriver.com> Acked-by: Jon Maloy <jmaloy@redhat.com> Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
a91d55d162
commit
03b6fefd9b
@@ -1138,7 +1138,7 @@ void tipc_node_check_dest(struct net *net, u32 addr,
|
||||
if (unlikely(!n->bc_entry.link)) {
|
||||
snd_l = tipc_bc_sndlink(net);
|
||||
if (!tipc_link_bc_create(net, tipc_own_addr(net),
|
||||
addr, U16_MAX,
|
||||
addr, peer_id, U16_MAX,
|
||||
tipc_link_min_win(snd_l),
|
||||
tipc_link_max_win(snd_l),
|
||||
n->capabilities,
|
||||
@@ -2435,7 +2435,7 @@ int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info)
|
||||
return -ENOMEM;
|
||||
|
||||
if (strcmp(name, tipc_bclink_name) == 0) {
|
||||
err = tipc_nl_add_bc_link(net, &msg);
|
||||
err = tipc_nl_add_bc_link(net, &msg, tipc_net(net)->bcl);
|
||||
if (err)
|
||||
goto err_free;
|
||||
} else {
|
||||
@@ -2479,6 +2479,7 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
|
||||
struct tipc_node *node;
|
||||
struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct tipc_net *tn = tipc_net(net);
|
||||
struct tipc_link_entry *le;
|
||||
|
||||
if (!info->attrs[TIPC_NLA_LINK])
|
||||
@@ -2495,11 +2496,26 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
|
||||
|
||||
if (strcmp(link_name, tipc_bclink_name) == 0) {
|
||||
err = tipc_bclink_reset_stats(net);
|
||||
err = -EINVAL;
|
||||
if (!strcmp(link_name, tipc_bclink_name)) {
|
||||
err = tipc_bclink_reset_stats(net, tipc_bc_sndlink(net));
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
} else if (strstr(link_name, tipc_bclink_name)) {
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(node, &tn->node_list, list) {
|
||||
tipc_node_read_lock(node);
|
||||
link = node->bc_entry.link;
|
||||
if (link && !strcmp(link_name, tipc_link_name(link))) {
|
||||
err = tipc_bclink_reset_stats(net, link);
|
||||
tipc_node_read_unlock(node);
|
||||
break;
|
||||
}
|
||||
tipc_node_read_unlock(node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
node = tipc_node_find_by_name(net, link_name, &bearer_id);
|
||||
@@ -2523,7 +2539,8 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
/* Caller should hold node lock */
|
||||
static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
|
||||
struct tipc_node *node, u32 *prev_link)
|
||||
struct tipc_node *node, u32 *prev_link,
|
||||
bool bc_link)
|
||||
{
|
||||
u32 i;
|
||||
int err;
|
||||
@@ -2539,6 +2556,14 @@ static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (bc_link) {
|
||||
*prev_link = i;
|
||||
err = tipc_nl_add_bc_link(net, msg, node->bc_entry.link);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
*prev_link = 0;
|
||||
|
||||
return 0;
|
||||
@@ -2547,17 +2572,36 @@ static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
|
||||
int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct nlattr **attrs = genl_dumpit_info(cb)->attrs;
|
||||
struct nlattr *link[TIPC_NLA_LINK_MAX + 1];
|
||||
struct tipc_net *tn = net_generic(net, tipc_net_id);
|
||||
struct tipc_node *node;
|
||||
struct tipc_nl_msg msg;
|
||||
u32 prev_node = cb->args[0];
|
||||
u32 prev_link = cb->args[1];
|
||||
int done = cb->args[2];
|
||||
bool bc_link = cb->args[3];
|
||||
int err;
|
||||
|
||||
if (done)
|
||||
return 0;
|
||||
|
||||
if (!prev_node) {
|
||||
/* Check if broadcast-receiver links dumping is needed */
|
||||
if (attrs && attrs[TIPC_NLA_LINK]) {
|
||||
err = nla_parse_nested_deprecated(link,
|
||||
TIPC_NLA_LINK_MAX,
|
||||
attrs[TIPC_NLA_LINK],
|
||||
tipc_nl_link_policy,
|
||||
NULL);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
if (unlikely(!link[TIPC_NLA_LINK_BROADCAST]))
|
||||
return -EINVAL;
|
||||
bc_link = true;
|
||||
}
|
||||
}
|
||||
|
||||
msg.skb = skb;
|
||||
msg.portid = NETLINK_CB(cb->skb).portid;
|
||||
msg.seq = cb->nlh->nlmsg_seq;
|
||||
@@ -2581,7 +2625,7 @@ int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
list) {
|
||||
tipc_node_read_lock(node);
|
||||
err = __tipc_nl_add_node_links(net, &msg, node,
|
||||
&prev_link);
|
||||
&prev_link, bc_link);
|
||||
tipc_node_read_unlock(node);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -2589,14 +2633,14 @@ int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
prev_node = node->addr;
|
||||
}
|
||||
} else {
|
||||
err = tipc_nl_add_bc_link(net, &msg);
|
||||
err = tipc_nl_add_bc_link(net, &msg, tn->bcl);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
list_for_each_entry_rcu(node, &tn->node_list, list) {
|
||||
tipc_node_read_lock(node);
|
||||
err = __tipc_nl_add_node_links(net, &msg, node,
|
||||
&prev_link);
|
||||
&prev_link, bc_link);
|
||||
tipc_node_read_unlock(node);
|
||||
if (err)
|
||||
goto out;
|
||||
@@ -2611,6 +2655,7 @@ out:
|
||||
cb->args[0] = prev_node;
|
||||
cb->args[1] = prev_link;
|
||||
cb->args[2] = done;
|
||||
cb->args[3] = bc_link;
|
||||
|
||||
return skb->len;
|
||||
}
|
||||
|
Reference in New Issue
Block a user