|
@@ -42,6 +42,11 @@
|
|
|
#include "node.h"
|
|
|
#include "config.h"
|
|
|
|
|
|
+static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
|
|
|
+ [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC },
|
|
|
+ [TIPC_NLA_NET_ID] = { .type = NLA_U32 }
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* The TIPC locking policy is designed to ensure a very fine locking
|
|
|
* granularity, permitting complete parallel access to individual
|
|
@@ -138,3 +143,57 @@ void tipc_net_stop(void)
|
|
|
|
|
|
pr_info("Left network mode\n");
|
|
|
}
|
|
|
+
|
|
|
+static int __tipc_nl_add_net(struct tipc_nl_msg *msg)
|
|
|
+{
|
|
|
+ void *hdr;
|
|
|
+ struct nlattr *attrs;
|
|
|
+
|
|
|
+ hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family,
|
|
|
+ NLM_F_MULTI, TIPC_NL_NET_GET);
|
|
|
+ if (!hdr)
|
|
|
+ return -EMSGSIZE;
|
|
|
+
|
|
|
+ attrs = nla_nest_start(msg->skb, TIPC_NLA_NET);
|
|
|
+ if (!attrs)
|
|
|
+ goto msg_full;
|
|
|
+
|
|
|
+ if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tipc_net_id))
|
|
|
+ goto attr_msg_full;
|
|
|
+
|
|
|
+ nla_nest_end(msg->skb, attrs);
|
|
|
+ genlmsg_end(msg->skb, hdr);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+attr_msg_full:
|
|
|
+ nla_nest_cancel(msg->skb, attrs);
|
|
|
+msg_full:
|
|
|
+ genlmsg_cancel(msg->skb, hdr);
|
|
|
+
|
|
|
+ return -EMSGSIZE;
|
|
|
+}
|
|
|
+
|
|
|
+int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
+{
|
|
|
+ int err;
|
|
|
+ int done = cb->args[0];
|
|
|
+ struct tipc_nl_msg msg;
|
|
|
+
|
|
|
+ if (done)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ msg.skb = skb;
|
|
|
+ msg.portid = NETLINK_CB(cb->skb).portid;
|
|
|
+ msg.seq = cb->nlh->nlmsg_seq;
|
|
|
+
|
|
|
+ err = __tipc_nl_add_net(&msg);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ done = 1;
|
|
|
+out:
|
|
|
+ cb->args[0] = done;
|
|
|
+
|
|
|
+ return skb->len;
|
|
|
+}
|