18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <net/genetlink.h> 38c2ecf20Sopenharmony_ci#include <net/ila.h> 48c2ecf20Sopenharmony_ci#include <net/netns/generic.h> 58c2ecf20Sopenharmony_ci#include <uapi/linux/genetlink.h> 68c2ecf20Sopenharmony_ci#include "ila.h" 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_cistatic const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { 98c2ecf20Sopenharmony_ci [ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, 108c2ecf20Sopenharmony_ci [ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, }, 118c2ecf20Sopenharmony_ci [ILA_ATTR_IFINDEX] = { .type = NLA_U32, }, 128c2ecf20Sopenharmony_ci [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, 138c2ecf20Sopenharmony_ci [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, }, 148c2ecf20Sopenharmony_ci}; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic const struct genl_ops ila_nl_ops[] = { 178c2ecf20Sopenharmony_ci { 188c2ecf20Sopenharmony_ci .cmd = ILA_CMD_ADD, 198c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 208c2ecf20Sopenharmony_ci .doit = ila_xlat_nl_cmd_add_mapping, 218c2ecf20Sopenharmony_ci .flags = GENL_ADMIN_PERM, 228c2ecf20Sopenharmony_ci }, 238c2ecf20Sopenharmony_ci { 248c2ecf20Sopenharmony_ci .cmd = ILA_CMD_DEL, 258c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 268c2ecf20Sopenharmony_ci .doit = ila_xlat_nl_cmd_del_mapping, 278c2ecf20Sopenharmony_ci .flags = GENL_ADMIN_PERM, 288c2ecf20Sopenharmony_ci }, 298c2ecf20Sopenharmony_ci { 308c2ecf20Sopenharmony_ci .cmd = ILA_CMD_FLUSH, 318c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 328c2ecf20Sopenharmony_ci .doit = ila_xlat_nl_cmd_flush, 338c2ecf20Sopenharmony_ci .flags = GENL_ADMIN_PERM, 348c2ecf20Sopenharmony_ci }, 358c2ecf20Sopenharmony_ci { 368c2ecf20Sopenharmony_ci .cmd = ILA_CMD_GET, 378c2ecf20Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 388c2ecf20Sopenharmony_ci .doit = ila_xlat_nl_cmd_get_mapping, 398c2ecf20Sopenharmony_ci .start = ila_xlat_nl_dump_start, 408c2ecf20Sopenharmony_ci .dumpit = ila_xlat_nl_dump, 418c2ecf20Sopenharmony_ci .done = ila_xlat_nl_dump_done, 428c2ecf20Sopenharmony_ci }, 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ciunsigned int ila_net_id; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistruct genl_family ila_nl_family __ro_after_init = { 488c2ecf20Sopenharmony_ci .hdrsize = 0, 498c2ecf20Sopenharmony_ci .name = ILA_GENL_NAME, 508c2ecf20Sopenharmony_ci .version = ILA_GENL_VERSION, 518c2ecf20Sopenharmony_ci .maxattr = ILA_ATTR_MAX, 528c2ecf20Sopenharmony_ci .policy = ila_nl_policy, 538c2ecf20Sopenharmony_ci .netnsok = true, 548c2ecf20Sopenharmony_ci .parallel_ops = true, 558c2ecf20Sopenharmony_ci .module = THIS_MODULE, 568c2ecf20Sopenharmony_ci .ops = ila_nl_ops, 578c2ecf20Sopenharmony_ci .n_ops = ARRAY_SIZE(ila_nl_ops), 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic __net_init int ila_init_net(struct net *net) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci int err; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci err = ila_xlat_init_net(net); 658c2ecf20Sopenharmony_ci if (err) 668c2ecf20Sopenharmony_ci goto ila_xlat_init_fail; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return 0; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciila_xlat_init_fail: 718c2ecf20Sopenharmony_ci return err; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic __net_exit void ila_exit_net(struct net *net) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci ila_xlat_exit_net(net); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic struct pernet_operations ila_net_ops = { 808c2ecf20Sopenharmony_ci .init = ila_init_net, 818c2ecf20Sopenharmony_ci .exit = ila_exit_net, 828c2ecf20Sopenharmony_ci .id = &ila_net_id, 838c2ecf20Sopenharmony_ci .size = sizeof(struct ila_net), 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic int __init ila_init(void) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci int ret; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci ret = register_pernet_device(&ila_net_ops); 918c2ecf20Sopenharmony_ci if (ret) 928c2ecf20Sopenharmony_ci goto register_device_fail; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci ret = genl_register_family(&ila_nl_family); 958c2ecf20Sopenharmony_ci if (ret) 968c2ecf20Sopenharmony_ci goto register_family_fail; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci ret = ila_lwt_init(); 998c2ecf20Sopenharmony_ci if (ret) 1008c2ecf20Sopenharmony_ci goto fail_lwt; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci return 0; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cifail_lwt: 1058c2ecf20Sopenharmony_ci genl_unregister_family(&ila_nl_family); 1068c2ecf20Sopenharmony_ciregister_family_fail: 1078c2ecf20Sopenharmony_ci unregister_pernet_device(&ila_net_ops); 1088c2ecf20Sopenharmony_ciregister_device_fail: 1098c2ecf20Sopenharmony_ci return ret; 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistatic void __exit ila_fini(void) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci ila_lwt_fini(); 1158c2ecf20Sopenharmony_ci genl_unregister_family(&ila_nl_family); 1168c2ecf20Sopenharmony_ci unregister_pernet_device(&ila_net_ops); 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cimodule_init(ila_init); 1208c2ecf20Sopenharmony_cimodule_exit(ila_fini); 1218c2ecf20Sopenharmony_ciMODULE_AUTHOR("Tom Herbert <tom@herbertland.com>"); 1228c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 1238c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("IPv6: Identifier Locator Addressing (ILA)"); 124