aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorRichard Alpe <richard.alpe@ericsson.com>2016-08-18 04:33:52 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-19 02:36:07 -0400
commitb34040227be7da760cc72ef3c807e0985e7f0f16 (patch)
tree19043619527b69595286b449bc132201de8ac08d /net/tipc/node.c
parent36a6503feddadbbad415fb3891e80f94c10a9b21 (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.c63
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
1556int 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;
1612err_out:
1613 tipc_node_put(peer);
1614 spin_unlock_bh(&tn->node_list_lock);
1615
1616 return err;
1617}
1618
1556int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) 1619int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
1557{ 1620{
1558 int err; 1621 int err;