diff mbox series

[v3,net-next,9/9] ila: add netlink control ILA resolver

Message ID 20171211203837.2540-10-tom@quantonium.net
State Rejected, archived
Delegated to: David Miller
Headers show
Series net: Generic network resolver backend and ILA resolver | expand

Commit Message

Tom Herbert Dec. 11, 2017, 8:38 p.m. UTC
Add a netlink family to processe netlinkf for the ILA resolver.
This calls the net resolver netlink functions.

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 include/uapi/linux/ila.h    | 11 ++++++++
 net/ipv6/ila/ila.h          |  8 ++++++
 net/ipv6/ila/ila_main.c     | 26 ++++++++++++++++++
 net/ipv6/ila/ila_resolver.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 111 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h
index 66557265bf5b..2481dab25d57 100644
--- a/include/uapi/linux/ila.h
+++ b/include/uapi/linux/ila.h
@@ -19,6 +19,8 @@  enum {
 	ILA_ATTR_CSUM_MODE,			/* u8 */
 	ILA_ATTR_IDENT_TYPE,			/* u8 */
 	ILA_ATTR_HOOK_TYPE,			/* u8 */
+	ILA_RSLV_ATTR_DST,			/* IPv6 address */
+	ILA_RSLV_ATTR_TIMEOUT,			/* u32 */
 
 	__ILA_ATTR_MAX,
 };
@@ -31,6 +33,10 @@  enum {
 	ILA_CMD_DEL,
 	ILA_CMD_GET,
 	ILA_CMD_FLUSH,
+	ILA_RSLV_CMD_ADD,
+	ILA_RSLV_CMD_DEL,
+	ILA_RSLV_CMD_GET,
+	ILA_RSLV_CMD_FLUSH,
 
 	__ILA_CMD_MAX,
 };
@@ -68,10 +74,15 @@  enum {
 enum {
 	ILA_NOTIFY_ATTR_UNSPEC,
 	ILA_NOTIFY_ATTR_TIMEOUT,		/* u32 */
+	ILA_NOTIFY_ATTR_DST,			/* Binary address */
 
 	__ILA_NOTIFY_ATTR_MAX,
 };
 
 #define ILA_NOTIFY_ATTR_MAX	(__ILA_NOTIFY_ATTR_MAX - 1)
 
+/* NETLINK_GENERIC related info */
+#define ILA_RSLV_GENL_NAME	"ila-rslv"
+#define ILA_RSLV_GENL_VERSION	0x1
+
 #endif /* _UAPI_LINUX_ILA_H */
diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h
index 02a800c71796..0aa99e359a38 100644
--- a/net/ipv6/ila/ila.h
+++ b/net/ipv6/ila/ila.h
@@ -137,6 +137,14 @@  int ila_xlat_nl_dump_start(struct netlink_callback *cb);
 int ila_xlat_nl_dump_done(struct netlink_callback *cb);
 int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb);
 
+int ila_rslv_nl_cmd_add(struct sk_buff *skb, struct genl_info *info);
+int ila_rslv_nl_cmd_del(struct sk_buff *skb, struct genl_info *info);
+int ila_rslv_nl_cmd_get(struct sk_buff *skb, struct genl_info *info);
+int ila_rslv_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info);
+int ila_rslv_nl_dump_start(struct netlink_callback *cb);
+int ila_rslv_nl_dump_done(struct netlink_callback *cb);
+int ila_rslv_nl_dump(struct sk_buff *skb, struct netlink_callback *cb);
+
 extern unsigned int ila_net_id;
 
 extern struct genl_family ila_nl_family;
diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c
index 411d3d112157..8589d422568b 100644
--- a/net/ipv6/ila/ila_main.c
+++ b/net/ipv6/ila/ila_main.c
@@ -40,6 +40,32 @@  static const struct genl_ops ila_nl_ops[] = {
 		.done = ila_xlat_nl_dump_done,
 		.policy = ila_nl_policy,
 	},
+	{
+		.cmd = ILA_RSLV_CMD_ADD,
+		.doit = ila_rslv_nl_cmd_add,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_RSLV_CMD_DEL,
+		.doit = ila_rslv_nl_cmd_del,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_RSLV_CMD_FLUSH,
+		.doit = ila_rslv_nl_cmd_flush,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_RSLV_CMD_GET,
+		.doit = ila_rslv_nl_cmd_get,
+		.start = ila_rslv_nl_dump_start,
+		.dumpit = ila_rslv_nl_dump,
+		.done = ila_rslv_nl_dump_done,
+		.policy = ila_nl_policy,
+	},
 };
 
 unsigned int ila_net_id;
diff --git a/net/ipv6/ila/ila_resolver.c b/net/ipv6/ila/ila_resolver.c
index 2aebc0526221..3278e93bb799 100644
--- a/net/ipv6/ila/ila_resolver.c
+++ b/net/ipv6/ila/ila_resolver.c
@@ -209,6 +209,13 @@  static const struct lwtunnel_encap_ops ila_rslv_ops = {
 
 #define ILA_MAX_SIZE 8192
 
+static struct net_rslv_netlink_map ila_netlink_map = {
+	.dst_attr = ILA_RSLV_ATTR_DST,
+	.timo_attr = ILA_RSLV_ATTR_TIMEOUT,
+	.get_cmd = ILA_RSLV_CMD_GET,
+	.genl_family = &ila_nl_family,
+};
+
 int ila_rslv_init_net(struct net *net)
 {
 	struct ila_net *ilan = net_generic(net, ila_net_id);
@@ -216,7 +223,7 @@  int ila_rslv_init_net(struct net *net)
 
 	nrslv = net_rslv_create(sizeof(struct ila_addr),
 				sizeof(struct ila_addr), ILA_MAX_SIZE, NULL,
-				NULL);
+				&ila_netlink_map);
 
 	if (IS_ERR(nrslv))
 		return PTR_ERR(nrslv);
@@ -234,6 +241,64 @@  void ila_rslv_exit_net(struct net *net)
 		net_rslv_destroy(ilan->rslv.nrslv);
 }
 
+/* Netlink access */
+
+int ila_rslv_nl_cmd_add(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = sock_net(skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_cmd_add(ilan->rslv.nrslv, skb, info);
+}
+
+int ila_rslv_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = sock_net(skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_cmd_del(ilan->rslv.nrslv, skb, info);
+}
+
+int ila_rslv_nl_cmd_get(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = sock_net(skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_cmd_get(ilan->rslv.nrslv, skb, info);
+}
+
+int ila_rslv_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = sock_net(skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_cmd_flush(ilan->rslv.nrslv, skb, info);
+}
+
+int ila_rslv_nl_dump_start(struct netlink_callback *cb)
+{
+	struct net *net = sock_net(cb->skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_dump_start(ilan->rslv.nrslv, cb);
+}
+
+int ila_rslv_nl_dump_done(struct netlink_callback *cb)
+{
+	struct net *net = sock_net(cb->skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_dump_done(ilan->rslv.nrslv, cb);
+}
+
+int ila_rslv_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net *net = sock_net(cb->skb->sk);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+
+	return net_rslv_nl_dump(ilan->rslv.nrslv, skb, cb);
+}
+
 int ila_rslv_init(void)
 {
 	return lwtunnel_encap_add_ops(&ila_rslv_ops, LWTUNNEL_ENCAP_ILA_NOTIFY);