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