Add a netlink family to processe netlinkf for the ILA resolver.
This calls the net resolver netlink functions.

Signed-off-by: Tom Herbert <t...@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 --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);
-- 
2.11.0

Reply via email to