mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
tipc: add peer removal functionality
Add TIPC_NL_PEER_REMOVE netlink command. This command can remove an offline peer node from the internal data structures. This will be supported by the tipc user space tool in iproute2. Signed-off-by: Richard Alpe <richard.alpe@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>
This commit is contained in:
parent
36a6503fed
commit
b34040227b
@ -59,6 +59,7 @@ enum {
|
||||
TIPC_NL_MON_SET,
|
||||
TIPC_NL_MON_GET,
|
||||
TIPC_NL_MON_PEER_GET,
|
||||
TIPC_NL_PEER_REMOVE,
|
||||
|
||||
__TIPC_NL_CMD_MAX,
|
||||
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include <net/genetlink.h>
|
||||
|
||||
extern const struct nla_policy tipc_nl_net_policy[];
|
||||
|
||||
int tipc_net_start(struct net *net, u32 addr);
|
||||
|
||||
void tipc_net_stop(struct net *net);
|
||||
|
@ -238,6 +238,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
.dumpit = tipc_nl_node_dump_monitor_peer,
|
||||
.policy = tipc_nl_policy,
|
||||
},
|
||||
{
|
||||
.cmd = TIPC_NL_PEER_REMOVE,
|
||||
.doit = tipc_nl_peer_rm,
|
||||
.policy = tipc_nl_policy,
|
||||
}
|
||||
};
|
||||
|
||||
int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
|
||||
|
@ -1553,6 +1553,69 @@ discard:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct tipc_net *tn = net_generic(net, tipc_net_id);
|
||||
struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
|
||||
struct tipc_node *peer;
|
||||
u32 addr;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
/* We identify the peer by its net */
|
||||
if (!info->attrs[TIPC_NLA_NET])
|
||||
return -EINVAL;
|
||||
|
||||
err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX,
|
||||
info->attrs[TIPC_NLA_NET],
|
||||
tipc_nl_net_policy);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!attrs[TIPC_NLA_NET_ADDR])
|
||||
return -EINVAL;
|
||||
|
||||
addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
|
||||
|
||||
if (in_own_node(net, addr))
|
||||
return -ENOTSUPP;
|
||||
|
||||
spin_lock_bh(&tn->node_list_lock);
|
||||
peer = tipc_node_find(net, addr);
|
||||
if (!peer) {
|
||||
spin_unlock_bh(&tn->node_list_lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
tipc_node_write_lock(peer);
|
||||
if (peer->state != SELF_DOWN_PEER_DOWN &&
|
||||
peer->state != SELF_DOWN_PEER_LEAVING) {
|
||||
tipc_node_write_unlock(peer);
|
||||
err = -EBUSY;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_BEARERS; i++) {
|
||||
struct tipc_link_entry *le = &peer->links[i];
|
||||
|
||||
if (le->link) {
|
||||
kfree(le->link);
|
||||
le->link = NULL;
|
||||
peer->link_cnt--;
|
||||
}
|
||||
}
|
||||
tipc_node_write_unlock(peer);
|
||||
tipc_node_delete(peer);
|
||||
|
||||
err = 0;
|
||||
err_out:
|
||||
tipc_node_put(peer);
|
||||
spin_unlock_bh(&tn->node_list_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
int err;
|
||||
|
@ -77,6 +77,7 @@ int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info);
|
||||
int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info);
|
||||
int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);
|
||||
int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info);
|
||||
|
||||
int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info);
|
||||
int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info);
|
||||
|
Loading…
Reference in New Issue
Block a user