1ad68147eSTom Herbert // SPDX-License-Identifier: GPL-2.0
2ad68147eSTom Herbert #include <net/genetlink.h>
3ad68147eSTom Herbert #include <net/netns/generic.h>
4ad68147eSTom Herbert #include <uapi/linux/genetlink.h>
5ad68147eSTom Herbert #include "ila.h"
6ad68147eSTom Herbert
7ad68147eSTom Herbert static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
8ad68147eSTom Herbert [ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
9ad68147eSTom Herbert [ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, },
10ad68147eSTom Herbert [ILA_ATTR_IFINDEX] = { .type = NLA_U32, },
11ad68147eSTom Herbert [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
12ad68147eSTom Herbert [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
13ad68147eSTom Herbert };
14ad68147eSTom Herbert
15ad68147eSTom Herbert static const struct genl_ops ila_nl_ops[] = {
16ad68147eSTom Herbert {
17ad68147eSTom Herbert .cmd = ILA_CMD_ADD,
18ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
19ad68147eSTom Herbert .doit = ila_xlat_nl_cmd_add_mapping,
20ad68147eSTom Herbert .flags = GENL_ADMIN_PERM,
21ad68147eSTom Herbert },
22ad68147eSTom Herbert {
23ad68147eSTom Herbert .cmd = ILA_CMD_DEL,
24ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
25ad68147eSTom Herbert .doit = ila_xlat_nl_cmd_del_mapping,
26ad68147eSTom Herbert .flags = GENL_ADMIN_PERM,
27ad68147eSTom Herbert },
28ad68147eSTom Herbert {
29b6e71bdeSTom Herbert .cmd = ILA_CMD_FLUSH,
30ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
31b6e71bdeSTom Herbert .doit = ila_xlat_nl_cmd_flush,
32b6e71bdeSTom Herbert .flags = GENL_ADMIN_PERM,
33b6e71bdeSTom Herbert },
34b6e71bdeSTom Herbert {
35ad68147eSTom Herbert .cmd = ILA_CMD_GET,
36ef6243acSJohannes Berg .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
37ad68147eSTom Herbert .doit = ila_xlat_nl_cmd_get_mapping,
38ad68147eSTom Herbert .start = ila_xlat_nl_dump_start,
39ad68147eSTom Herbert .dumpit = ila_xlat_nl_dump,
40ad68147eSTom Herbert .done = ila_xlat_nl_dump_done,
41ad68147eSTom Herbert },
42ad68147eSTom Herbert };
43ad68147eSTom Herbert
44ad68147eSTom Herbert unsigned int ila_net_id;
45ad68147eSTom Herbert
46ad68147eSTom Herbert struct genl_family ila_nl_family __ro_after_init = {
47ad68147eSTom Herbert .hdrsize = 0,
48ad68147eSTom Herbert .name = ILA_GENL_NAME,
49ad68147eSTom Herbert .version = ILA_GENL_VERSION,
50ad68147eSTom Herbert .maxattr = ILA_ATTR_MAX,
513b0f31f2SJohannes Berg .policy = ila_nl_policy,
52ad68147eSTom Herbert .netnsok = true,
53ad68147eSTom Herbert .parallel_ops = true,
54ad68147eSTom Herbert .module = THIS_MODULE,
55ad68147eSTom Herbert .ops = ila_nl_ops,
56ad68147eSTom Herbert .n_ops = ARRAY_SIZE(ila_nl_ops),
579c5d03d3SJakub Kicinski .resv_start_op = ILA_CMD_FLUSH + 1,
58ad68147eSTom Herbert };
59ad68147eSTom Herbert
ila_init_net(struct net * net)60ad68147eSTom Herbert static __net_init int ila_init_net(struct net *net)
61ad68147eSTom Herbert {
62ad68147eSTom Herbert int err;
63ad68147eSTom Herbert
64ad68147eSTom Herbert err = ila_xlat_init_net(net);
65ad68147eSTom Herbert if (err)
66ad68147eSTom Herbert goto ila_xlat_init_fail;
67ad68147eSTom Herbert
68ad68147eSTom Herbert return 0;
69ad68147eSTom Herbert
70ad68147eSTom Herbert ila_xlat_init_fail:
71ad68147eSTom Herbert return err;
72ad68147eSTom Herbert }
73ad68147eSTom Herbert
ila_pre_exit_net(struct net * net)74*18a5a169SEric Dumazet static __net_exit void ila_pre_exit_net(struct net *net)
75*18a5a169SEric Dumazet {
76*18a5a169SEric Dumazet ila_xlat_pre_exit_net(net);
77*18a5a169SEric Dumazet }
78*18a5a169SEric Dumazet
ila_exit_net(struct net * net)79ad68147eSTom Herbert static __net_exit void ila_exit_net(struct net *net)
80ad68147eSTom Herbert {
81ad68147eSTom Herbert ila_xlat_exit_net(net);
82ad68147eSTom Herbert }
83ad68147eSTom Herbert
84ad68147eSTom Herbert static struct pernet_operations ila_net_ops = {
85ad68147eSTom Herbert .init = ila_init_net,
86*18a5a169SEric Dumazet .pre_exit = ila_pre_exit_net,
87ad68147eSTom Herbert .exit = ila_exit_net,
88ad68147eSTom Herbert .id = &ila_net_id,
89ad68147eSTom Herbert .size = sizeof(struct ila_net),
90ad68147eSTom Herbert };
91ad68147eSTom Herbert
ila_init(void)92ad68147eSTom Herbert static int __init ila_init(void)
93ad68147eSTom Herbert {
94ad68147eSTom Herbert int ret;
95ad68147eSTom Herbert
96ad68147eSTom Herbert ret = register_pernet_device(&ila_net_ops);
97ad68147eSTom Herbert if (ret)
98ad68147eSTom Herbert goto register_device_fail;
99ad68147eSTom Herbert
100ad68147eSTom Herbert ret = genl_register_family(&ila_nl_family);
101ad68147eSTom Herbert if (ret)
102ad68147eSTom Herbert goto register_family_fail;
103ad68147eSTom Herbert
104ad68147eSTom Herbert ret = ila_lwt_init();
105ad68147eSTom Herbert if (ret)
106ad68147eSTom Herbert goto fail_lwt;
107ad68147eSTom Herbert
108ad68147eSTom Herbert return 0;
109ad68147eSTom Herbert
110ad68147eSTom Herbert fail_lwt:
111ad68147eSTom Herbert genl_unregister_family(&ila_nl_family);
112ad68147eSTom Herbert register_family_fail:
113ad68147eSTom Herbert unregister_pernet_device(&ila_net_ops);
114ad68147eSTom Herbert register_device_fail:
115ad68147eSTom Herbert return ret;
116ad68147eSTom Herbert }
117ad68147eSTom Herbert
ila_fini(void)118ad68147eSTom Herbert static void __exit ila_fini(void)
119ad68147eSTom Herbert {
120ad68147eSTom Herbert ila_lwt_fini();
121ad68147eSTom Herbert genl_unregister_family(&ila_nl_family);
122ad68147eSTom Herbert unregister_pernet_device(&ila_net_ops);
123ad68147eSTom Herbert }
124ad68147eSTom Herbert
125ad68147eSTom Herbert module_init(ila_init);
126ad68147eSTom Herbert module_exit(ila_fini);
127ad68147eSTom Herbert MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>");
128ad68147eSTom Herbert MODULE_LICENSE("GPL");
12967c20de3SRob Gill MODULE_DESCRIPTION("IPv6: Identifier Locator Addressing (ILA)");
130