@@ -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 */
@@ -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;
@@ -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;
@@ -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);
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(-)