aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
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
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')
-rw-r--r--net/tipc/net.h2
-rw-r--r--net/tipc/netlink.c5
-rw-r--r--net/tipc/node.c63
-rw-r--r--net/tipc/node.h1
4 files changed, 71 insertions, 0 deletions
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 77a7a118911d..c7c254902873 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -39,6 +39,8 @@
39 39
40#include <net/genetlink.h> 40#include <net/genetlink.h>
41 41
42extern const struct nla_policy tipc_nl_net_policy[];
43
42int tipc_net_start(struct net *net, u32 addr); 44int tipc_net_start(struct net *net, u32 addr);
43 45
44void tipc_net_stop(struct net *net); 46void tipc_net_stop(struct net *net);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index a84daec0afe9..2718de667828 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -238,6 +238,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
238 .dumpit = tipc_nl_node_dump_monitor_peer, 238 .dumpit = tipc_nl_node_dump_monitor_peer,
239 .policy = tipc_nl_policy, 239 .policy = tipc_nl_policy,
240 }, 240 },
241 {
242 .cmd = TIPC_NL_PEER_REMOVE,
243 .doit = tipc_nl_peer_rm,
244 .policy = tipc_nl_policy,
245 }
241}; 246};
242 247
243int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr) 248int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
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;
diff --git a/net/tipc/node.h b/net/tipc/node.h
index d69fdfcc0ec9..4578b34c7dca 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -77,6 +77,7 @@ int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb);
77int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info); 77int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info);
78int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info); 78int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info);
79int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info); 79int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);
80int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info);
80 81
81int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info); 82int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info);
82int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info); 83int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info);