xref: /openbmc/linux/net/ipv6/ila/ila_main.c (revision ca2478a7d974f38d29d27acb42a952c7f168916e)
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