Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <net/genetlink.h> |
| 3 | #include <net/ila.h> |
| 4 | #include <net/netns/generic.h> |
| 5 | #include <uapi/linux/genetlink.h> |
| 6 | #include "ila.h" |
| 7 | |
| 8 | static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { |
| 9 | [ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, |
| 10 | [ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, }, |
| 11 | [ILA_ATTR_IFINDEX] = { .type = NLA_U32, }, |
| 12 | [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, |
| 13 | [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, }, |
| 14 | }; |
| 15 | |
| 16 | static const struct genl_ops ila_nl_ops[] = { |
| 17 | { |
| 18 | .cmd = ILA_CMD_ADD, |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 19 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 20 | .doit = ila_xlat_nl_cmd_add_mapping, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 21 | .flags = GENL_ADMIN_PERM, |
| 22 | }, |
| 23 | { |
| 24 | .cmd = ILA_CMD_DEL, |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 25 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 26 | .doit = ila_xlat_nl_cmd_del_mapping, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 27 | .flags = GENL_ADMIN_PERM, |
| 28 | }, |
| 29 | { |
| 30 | .cmd = ILA_CMD_FLUSH, |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 31 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 32 | .doit = ila_xlat_nl_cmd_flush, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 33 | .flags = GENL_ADMIN_PERM, |
| 34 | }, |
| 35 | { |
| 36 | .cmd = ILA_CMD_GET, |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 37 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 38 | .doit = ila_xlat_nl_cmd_get_mapping, |
| 39 | .start = ila_xlat_nl_dump_start, |
| 40 | .dumpit = ila_xlat_nl_dump, |
| 41 | .done = ila_xlat_nl_dump_done, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 42 | }, |
| 43 | }; |
| 44 | |
| 45 | unsigned int ila_net_id; |
| 46 | |
| 47 | struct genl_family ila_nl_family __ro_after_init = { |
| 48 | .hdrsize = 0, |
| 49 | .name = ILA_GENL_NAME, |
| 50 | .version = ILA_GENL_VERSION, |
| 51 | .maxattr = ILA_ATTR_MAX, |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 52 | .policy = ila_nl_policy, |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 53 | .netnsok = true, |
| 54 | .parallel_ops = true, |
| 55 | .module = THIS_MODULE, |
| 56 | .ops = ila_nl_ops, |
| 57 | .n_ops = ARRAY_SIZE(ila_nl_ops), |
| 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(&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(&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(&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"); |