1e8372d9dSGuvenc Gulce // SPDX-License-Identifier: GPL-2.0
2e8372d9dSGuvenc Gulce /*
3e8372d9dSGuvenc Gulce * Shared Memory Communications over RDMA (SMC-R) and RoCE
4e8372d9dSGuvenc Gulce *
5e8372d9dSGuvenc Gulce * Generic netlink support functions to interact with SMC module
6e8372d9dSGuvenc Gulce *
7e8372d9dSGuvenc Gulce * Copyright IBM Corp. 2020
8e8372d9dSGuvenc Gulce *
9e8372d9dSGuvenc Gulce * Author(s): Guvenc Gulce <guvenc@linux.ibm.com>
10e8372d9dSGuvenc Gulce */
11e8372d9dSGuvenc Gulce
12e8372d9dSGuvenc Gulce #include <linux/module.h>
13e8372d9dSGuvenc Gulce #include <linux/list.h>
14e8372d9dSGuvenc Gulce #include <linux/ctype.h>
15e8372d9dSGuvenc Gulce #include <linux/mutex.h>
16e8372d9dSGuvenc Gulce #include <linux/if.h>
17e8372d9dSGuvenc Gulce #include <linux/smc.h>
18e8372d9dSGuvenc Gulce
19e8372d9dSGuvenc Gulce #include "smc_core.h"
20aaf95523SGuvenc Gulce #include "smc_ism.h"
21a3db10efSGuvenc Gulce #include "smc_ib.h"
22fa086662SKarsten Graul #include "smc_clc.h"
238c40602bSGuvenc Gulce #include "smc_stats.h"
24e8372d9dSGuvenc Gulce #include "smc_netlink.h"
25e8372d9dSGuvenc Gulce
26fa086662SKarsten Graul const struct nla_policy
27fa086662SKarsten Graul smc_gen_ueid_policy[SMC_NLA_EID_TABLE_MAX + 1] = {
28fa086662SKarsten Graul [SMC_NLA_EID_TABLE_UNSPEC] = { .type = NLA_UNSPEC },
29fa086662SKarsten Graul [SMC_NLA_EID_TABLE_ENTRY] = { .type = NLA_STRING,
30fa086662SKarsten Graul .len = SMC_MAX_EID_LEN,
31fa086662SKarsten Graul },
32fa086662SKarsten Graul };
33e8372d9dSGuvenc Gulce
34fa086662SKarsten Graul #define SMC_CMD_MAX_ATTR 1
35e8372d9dSGuvenc Gulce /* SMC_GENL generic netlink operation definition */
36e8372d9dSGuvenc Gulce static const struct genl_ops smc_gen_nl_ops[] = {
37099b990bSGuvenc Gulce {
38099b990bSGuvenc Gulce .cmd = SMC_NETLINK_GET_SYS_INFO,
39099b990bSGuvenc Gulce /* can be retrieved by unprivileged users */
40099b990bSGuvenc Gulce .dumpit = smc_nl_get_sys_info,
41099b990bSGuvenc Gulce },
42e9b8c845SGuvenc Gulce {
43e9b8c845SGuvenc Gulce .cmd = SMC_NETLINK_GET_LGR_SMCR,
44e9b8c845SGuvenc Gulce /* can be retrieved by unprivileged users */
45e9b8c845SGuvenc Gulce .dumpit = smcr_nl_get_lgr,
46e9b8c845SGuvenc Gulce },
475a7e09d5SGuvenc Gulce {
485a7e09d5SGuvenc Gulce .cmd = SMC_NETLINK_GET_LINK_SMCR,
495a7e09d5SGuvenc Gulce /* can be retrieved by unprivileged users */
505a7e09d5SGuvenc Gulce .dumpit = smcr_nl_get_link,
515a7e09d5SGuvenc Gulce },
528f9dde4bSGuvenc Gulce {
538f9dde4bSGuvenc Gulce .cmd = SMC_NETLINK_GET_LGR_SMCD,
548f9dde4bSGuvenc Gulce /* can be retrieved by unprivileged users */
558f9dde4bSGuvenc Gulce .dumpit = smcd_nl_get_lgr,
568f9dde4bSGuvenc Gulce },
57aaf95523SGuvenc Gulce {
58aaf95523SGuvenc Gulce .cmd = SMC_NETLINK_GET_DEV_SMCD,
59aaf95523SGuvenc Gulce /* can be retrieved by unprivileged users */
60aaf95523SGuvenc Gulce .dumpit = smcd_nl_get_device,
61aaf95523SGuvenc Gulce },
62a3db10efSGuvenc Gulce {
63a3db10efSGuvenc Gulce .cmd = SMC_NETLINK_GET_DEV_SMCR,
64a3db10efSGuvenc Gulce /* can be retrieved by unprivileged users */
65a3db10efSGuvenc Gulce .dumpit = smcr_nl_get_device,
66a3db10efSGuvenc Gulce },
678c40602bSGuvenc Gulce {
688c40602bSGuvenc Gulce .cmd = SMC_NETLINK_GET_STATS,
698c40602bSGuvenc Gulce /* can be retrieved by unprivileged users */
708c40602bSGuvenc Gulce .dumpit = smc_nl_get_stats,
718c40602bSGuvenc Gulce },
72f0dd7bf5SGuvenc Gulce {
73f0dd7bf5SGuvenc Gulce .cmd = SMC_NETLINK_GET_FBACK_STATS,
74f0dd7bf5SGuvenc Gulce /* can be retrieved by unprivileged users */
75f0dd7bf5SGuvenc Gulce .dumpit = smc_nl_get_fback_stats,
76f0dd7bf5SGuvenc Gulce },
77fa086662SKarsten Graul {
78fa086662SKarsten Graul .cmd = SMC_NETLINK_DUMP_UEID,
79fa086662SKarsten Graul /* can be retrieved by unprivileged users */
80fa086662SKarsten Graul .dumpit = smc_nl_dump_ueid,
81fa086662SKarsten Graul },
82fa086662SKarsten Graul {
83fa086662SKarsten Graul .cmd = SMC_NETLINK_ADD_UEID,
84fa086662SKarsten Graul .flags = GENL_ADMIN_PERM,
85fa086662SKarsten Graul .doit = smc_nl_add_ueid,
86fa086662SKarsten Graul .policy = smc_gen_ueid_policy,
87fa086662SKarsten Graul },
88fa086662SKarsten Graul {
89fa086662SKarsten Graul .cmd = SMC_NETLINK_REMOVE_UEID,
90fa086662SKarsten Graul .flags = GENL_ADMIN_PERM,
91fa086662SKarsten Graul .doit = smc_nl_remove_ueid,
92fa086662SKarsten Graul .policy = smc_gen_ueid_policy,
93fa086662SKarsten Graul },
94fa086662SKarsten Graul {
95fa086662SKarsten Graul .cmd = SMC_NETLINK_FLUSH_UEID,
96fa086662SKarsten Graul .flags = GENL_ADMIN_PERM,
97fa086662SKarsten Graul .doit = smc_nl_flush_ueid,
98fa086662SKarsten Graul },
993c572145SKarsten Graul {
1003c572145SKarsten Graul .cmd = SMC_NETLINK_DUMP_SEID,
1013c572145SKarsten Graul /* can be retrieved by unprivileged users */
1023c572145SKarsten Graul .dumpit = smc_nl_dump_seid,
1033c572145SKarsten Graul },
1043c572145SKarsten Graul {
1053c572145SKarsten Graul .cmd = SMC_NETLINK_ENABLE_SEID,
1063c572145SKarsten Graul .flags = GENL_ADMIN_PERM,
1073c572145SKarsten Graul .doit = smc_nl_enable_seid,
1083c572145SKarsten Graul },
1093c572145SKarsten Graul {
1103c572145SKarsten Graul .cmd = SMC_NETLINK_DISABLE_SEID,
1113c572145SKarsten Graul .flags = GENL_ADMIN_PERM,
1123c572145SKarsten Graul .doit = smc_nl_disable_seid,
1133c572145SKarsten Graul },
114f9496b7cSD. Wythe {
115f9496b7cSD. Wythe .cmd = SMC_NETLINK_DUMP_HS_LIMITATION,
116f9496b7cSD. Wythe /* can be retrieved by unprivileged users */
117f9496b7cSD. Wythe .dumpit = smc_nl_dump_hs_limitation,
118f9496b7cSD. Wythe },
119f9496b7cSD. Wythe {
120f9496b7cSD. Wythe .cmd = SMC_NETLINK_ENABLE_HS_LIMITATION,
121f9496b7cSD. Wythe .flags = GENL_ADMIN_PERM,
122f9496b7cSD. Wythe .doit = smc_nl_enable_hs_limitation,
123f9496b7cSD. Wythe },
124f9496b7cSD. Wythe {
125f9496b7cSD. Wythe .cmd = SMC_NETLINK_DISABLE_HS_LIMITATION,
126f9496b7cSD. Wythe .flags = GENL_ADMIN_PERM,
127f9496b7cSD. Wythe .doit = smc_nl_disable_hs_limitation,
128f9496b7cSD. Wythe },
129e8372d9dSGuvenc Gulce };
130e8372d9dSGuvenc Gulce
131e8372d9dSGuvenc Gulce static const struct nla_policy smc_gen_nl_policy[2] = {
132e8372d9dSGuvenc Gulce [SMC_CMD_MAX_ATTR] = { .type = NLA_REJECT, },
133e8372d9dSGuvenc Gulce };
134e8372d9dSGuvenc Gulce
135e8372d9dSGuvenc Gulce /* SMC_GENL family definition */
136e8372d9dSGuvenc Gulce struct genl_family smc_gen_nl_family __ro_after_init = {
137e8372d9dSGuvenc Gulce .hdrsize = 0,
138e8372d9dSGuvenc Gulce .name = SMC_GENL_FAMILY_NAME,
139e8372d9dSGuvenc Gulce .version = SMC_GENL_FAMILY_VERSION,
140e8372d9dSGuvenc Gulce .maxattr = SMC_CMD_MAX_ATTR,
141e8372d9dSGuvenc Gulce .policy = smc_gen_nl_policy,
142e8372d9dSGuvenc Gulce .netnsok = true,
143e8372d9dSGuvenc Gulce .module = THIS_MODULE,
144e8372d9dSGuvenc Gulce .ops = smc_gen_nl_ops,
145*9c5d03d3SJakub Kicinski .n_ops = ARRAY_SIZE(smc_gen_nl_ops),
146*9c5d03d3SJakub Kicinski .resv_start_op = SMC_NETLINK_DISABLE_HS_LIMITATION + 1,
147e8372d9dSGuvenc Gulce };
148e8372d9dSGuvenc Gulce
smc_nl_init(void)149e8372d9dSGuvenc Gulce int __init smc_nl_init(void)
150e8372d9dSGuvenc Gulce {
151e8372d9dSGuvenc Gulce return genl_register_family(&smc_gen_nl_family);
152e8372d9dSGuvenc Gulce }
153e8372d9dSGuvenc Gulce
smc_nl_exit(void)154e8372d9dSGuvenc Gulce void smc_nl_exit(void)
155e8372d9dSGuvenc Gulce {
156e8372d9dSGuvenc Gulce genl_unregister_family(&smc_gen_nl_family);
157e8372d9dSGuvenc Gulce }
158