diff options
author | Richard Alpe <richard.alpe@ericsson.com> | 2016-08-18 04:33:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-08-19 02:36:07 -0400 |
commit | b34040227be7da760cc72ef3c807e0985e7f0f16 (patch) | |
tree | 19043619527b69595286b449bc132201de8ac08d /net/tipc/node.c | |
parent | 36a6503feddadbbad415fb3891e80f94c10a9b21 (diff) |
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>
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 21974191e425..7e8b75fd1a02 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1553,6 +1553,69 @@ discard: | |||
1553 | kfree_skb(skb); | 1553 | kfree_skb(skb); |
1554 | } | 1554 | } |
1555 | 1555 | ||
1556 | int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info) | ||
1557 | { | ||
1558 | struct net *net = sock_net(skb->sk); | ||
1559 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
1560 | struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; | ||
1561 | struct tipc_node *peer; | ||
1562 | u32 addr; | ||
1563 | int err; | ||
1564 | int i; | ||
1565 | |||
1566 | /* We identify the peer by its net */ | ||
1567 | if (!info->attrs[TIPC_NLA_NET]) | ||
1568 | return -EINVAL; | ||
1569 | |||
1570 | err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX, | ||
1571 | info->attrs[TIPC_NLA_NET], | ||
1572 | tipc_nl_net_policy); | ||
1573 | if (err) | ||
1574 | return err; | ||
1575 | |||
1576 | if (!attrs[TIPC_NLA_NET_ADDR]) | ||
1577 | return -EINVAL; | ||
1578 | |||
1579 | addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]); | ||
1580 | |||
1581 | if (in_own_node(net, addr)) | ||
1582 | return -ENOTSUPP; | ||
1583 | |||
1584 | spin_lock_bh(&tn->node_list_lock); | ||
1585 | peer = tipc_node_find(net, addr); | ||
1586 | if (!peer) { | ||
1587 | spin_unlock_bh(&tn->node_list_lock); | ||
1588 | return -ENXIO; | ||
1589 | } | ||
1590 | |||
1591 | tipc_node_write_lock(peer); | ||
1592 | if (peer->state != SELF_DOWN_PEER_DOWN && | ||
1593 | peer->state != SELF_DOWN_PEER_LEAVING) { | ||
1594 | tipc_node_write_unlock(peer); | ||
1595 | err = -EBUSY; | ||
1596 | goto err_out; | ||
1597 | } | ||
1598 | |||
1599 | for (i = 0; i < MAX_BEARERS; i++) { | ||
1600 | struct tipc_link_entry *le = &peer->links[i]; | ||
1601 | |||
1602 | if (le->link) { | ||
1603 | kfree(le->link); | ||
1604 | le->link = NULL; | ||
1605 | peer->link_cnt--; | ||
1606 | } | ||
1607 | } | ||
1608 | tipc_node_write_unlock(peer); | ||
1609 | tipc_node_delete(peer); | ||
1610 | |||
1611 | err = 0; | ||
1612 | err_out: | ||
1613 | tipc_node_put(peer); | ||
1614 | spin_unlock_bh(&tn->node_list_lock); | ||
1615 | |||
1616 | return err; | ||
1617 | } | ||
1618 | |||
1556 | int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) | 1619 | int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) |
1557 | { | 1620 | { |
1558 | int err; | 1621 | int err; |