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