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, |
| 19 | .doit = ila_xlat_nl_cmd_add_mapping, |
| 20 | .policy = ila_nl_policy, |
| 21 | .flags = GENL_ADMIN_PERM, |
| 22 | }, |
| 23 | { |
| 24 | .cmd = ILA_CMD_DEL, |
| 25 | .doit = ila_xlat_nl_cmd_del_mapping, |
| 26 | .policy = ila_nl_policy, |
| 27 | .flags = GENL_ADMIN_PERM, |
| 28 | }, |
| 29 | { |
| 30 | .cmd = ILA_CMD_FLUSH, |
| 31 | .doit = ila_xlat_nl_cmd_flush, |
| 32 | .policy = ila_nl_policy, |
| 33 | .flags = GENL_ADMIN_PERM, |
| 34 | }, |
| 35 | { |
| 36 | .cmd = ILA_CMD_GET, |
| 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 | .policy = ila_nl_policy, |
| 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, |
| 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 | }; |
| 58 | |
| 59 | static __net_init int ila_init_net(struct net *net) |
| 60 | { |
| 61 | int err; |
| 62 | |
| 63 | err = ila_xlat_init_net(net); |
| 64 | if (err) |
| 65 | goto ila_xlat_init_fail; |
| 66 | |
| 67 | return 0; |
| 68 | |
| 69 | ila_xlat_init_fail: |
| 70 | return err; |
| 71 | } |
| 72 | |
| 73 | static __net_exit void ila_exit_net(struct net *net) |
| 74 | { |
| 75 | ila_xlat_exit_net(net); |
| 76 | } |
| 77 | |
| 78 | static struct pernet_operations ila_net_ops = { |
| 79 | .init = ila_init_net, |
| 80 | .exit = ila_exit_net, |
| 81 | .id = &ila_net_id, |
| 82 | .size = sizeof(struct ila_net), |
| 83 | }; |
| 84 | |
| 85 | static int __init ila_init(void) |
| 86 | { |
| 87 | int ret; |
| 88 | |
| 89 | ret = register_pernet_device(&ila_net_ops); |
| 90 | if (ret) |
| 91 | goto register_device_fail; |
| 92 | |
| 93 | ret = genl_register_family(&ila_nl_family); |
| 94 | if (ret) |
| 95 | goto register_family_fail; |
| 96 | |
| 97 | ret = ila_lwt_init(); |
| 98 | if (ret) |
| 99 | goto fail_lwt; |
| 100 | |
| 101 | return 0; |
| 102 | |
| 103 | fail_lwt: |
| 104 | genl_unregister_family(&ila_nl_family); |
| 105 | register_family_fail: |
| 106 | unregister_pernet_device(&ila_net_ops); |
| 107 | register_device_fail: |
| 108 | return ret; |
| 109 | } |
| 110 | |
| 111 | static void __exit ila_fini(void) |
| 112 | { |
| 113 | ila_lwt_fini(); |
| 114 | genl_unregister_family(&ila_nl_family); |
| 115 | unregister_pernet_device(&ila_net_ops); |
| 116 | } |
| 117 | |
| 118 | module_init(ila_init); |
| 119 | module_exit(ila_fini); |
| 120 | MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>"); |
| 121 | MODULE_LICENSE("GPL"); |