xref: /linux/fs/smb/client/netlink.c (revision 8e07e0e3964ca4e23ce7b68e2096fe660a888942)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Netlink routines for CIFS
4  *
5  * Copyright (c) 2020 Samuel Cabrero <scabrero@suse.de>
6  */
7 
8 #include <net/genetlink.h>
9 #include <uapi/linux/cifs/cifs_netlink.h>
10 
11 #include "netlink.h"
12 #include "cifsglob.h"
13 #include "cifs_debug.h"
14 #include "cifs_swn.h"
15 
16 static const struct nla_policy cifs_genl_policy[CIFS_GENL_ATTR_MAX + 1] = {
17 	[CIFS_GENL_ATTR_SWN_REGISTRATION_ID]	= { .type = NLA_U32 },
18 	[CIFS_GENL_ATTR_SWN_NET_NAME]		= { .type = NLA_STRING },
19 	[CIFS_GENL_ATTR_SWN_SHARE_NAME]		= { .type = NLA_STRING },
20 	[CIFS_GENL_ATTR_SWN_IP]			= { .len = sizeof(struct sockaddr_storage) },
21 	[CIFS_GENL_ATTR_SWN_NET_NAME_NOTIFY]	= { .type = NLA_FLAG },
22 	[CIFS_GENL_ATTR_SWN_SHARE_NAME_NOTIFY]	= { .type = NLA_FLAG },
23 	[CIFS_GENL_ATTR_SWN_IP_NOTIFY]		= { .type = NLA_FLAG },
24 	[CIFS_GENL_ATTR_SWN_KRB_AUTH]		= { .type = NLA_FLAG },
25 	[CIFS_GENL_ATTR_SWN_USER_NAME]		= { .type = NLA_STRING },
26 	[CIFS_GENL_ATTR_SWN_PASSWORD]		= { .type = NLA_STRING },
27 	[CIFS_GENL_ATTR_SWN_DOMAIN_NAME]	= { .type = NLA_STRING },
28 	[CIFS_GENL_ATTR_SWN_NOTIFICATION_TYPE]	= { .type = NLA_U32 },
29 	[CIFS_GENL_ATTR_SWN_RESOURCE_STATE]	= { .type = NLA_U32 },
30 	[CIFS_GENL_ATTR_SWN_RESOURCE_NAME]	= { .type = NLA_STRING},
31 };
32 
33 static const struct genl_ops cifs_genl_ops[] = {
34 	{
35 		.cmd = CIFS_GENL_CMD_SWN_NOTIFY,
36 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
37 		.doit = cifs_swn_notify,
38 	},
39 };
40 
41 static const struct genl_multicast_group cifs_genl_mcgrps[] = {
42 	[CIFS_GENL_MCGRP_SWN] = { .name = CIFS_GENL_MCGRP_SWN_NAME },
43 };
44 
45 struct genl_family cifs_genl_family = {
46 	.name		= CIFS_GENL_NAME,
47 	.version	= CIFS_GENL_VERSION,
48 	.hdrsize	= 0,
49 	.maxattr	= CIFS_GENL_ATTR_MAX,
50 	.module		= THIS_MODULE,
51 	.policy		= cifs_genl_policy,
52 	.ops		= cifs_genl_ops,
53 	.n_ops		= ARRAY_SIZE(cifs_genl_ops),
54 	.resv_start_op	= CIFS_GENL_CMD_SWN_NOTIFY + 1,
55 	.mcgrps		= cifs_genl_mcgrps,
56 	.n_mcgrps	= ARRAY_SIZE(cifs_genl_mcgrps),
57 };
58 
59 /**
60  * cifs_genl_init - Register generic netlink family
61  *
62  * Return zero if initialized successfully, otherwise non-zero.
63  */
64 int cifs_genl_init(void)
65 {
66 	int ret;
67 
68 	ret = genl_register_family(&cifs_genl_family);
69 	if (ret < 0) {
70 		cifs_dbg(VFS, "%s: failed to register netlink family\n",
71 				__func__);
72 		return ret;
73 	}
74 
75 	return 0;
76 }
77 
78 /**
79  * cifs_genl_exit - Unregister generic netlink family
80  */
81 void cifs_genl_exit(void)
82 {
83 	int ret;
84 
85 	ret = genl_unregister_family(&cifs_genl_family);
86 	if (ret < 0) {
87 		cifs_dbg(VFS, "%s: failed to unregister netlink family\n",
88 				__func__);
89 	}
90 }
91