162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Netlink routines for CIFS 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2020 Samuel Cabrero <scabrero@suse.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <net/genetlink.h> 962306a36Sopenharmony_ci#include <uapi/linux/cifs/cifs_netlink.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "netlink.h" 1262306a36Sopenharmony_ci#include "cifsglob.h" 1362306a36Sopenharmony_ci#include "cifs_debug.h" 1462306a36Sopenharmony_ci#include "cifs_swn.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistatic const struct nla_policy cifs_genl_policy[CIFS_GENL_ATTR_MAX + 1] = { 1762306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_REGISTRATION_ID] = { .type = NLA_U32 }, 1862306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_NET_NAME] = { .type = NLA_STRING }, 1962306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_SHARE_NAME] = { .type = NLA_STRING }, 2062306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_IP] = { .len = sizeof(struct sockaddr_storage) }, 2162306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_NET_NAME_NOTIFY] = { .type = NLA_FLAG }, 2262306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_SHARE_NAME_NOTIFY] = { .type = NLA_FLAG }, 2362306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_IP_NOTIFY] = { .type = NLA_FLAG }, 2462306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_KRB_AUTH] = { .type = NLA_FLAG }, 2562306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_USER_NAME] = { .type = NLA_STRING }, 2662306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_PASSWORD] = { .type = NLA_STRING }, 2762306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_DOMAIN_NAME] = { .type = NLA_STRING }, 2862306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_NOTIFICATION_TYPE] = { .type = NLA_U32 }, 2962306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_RESOURCE_STATE] = { .type = NLA_U32 }, 3062306a36Sopenharmony_ci [CIFS_GENL_ATTR_SWN_RESOURCE_NAME] = { .type = NLA_STRING}, 3162306a36Sopenharmony_ci}; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic const struct genl_ops cifs_genl_ops[] = { 3462306a36Sopenharmony_ci { 3562306a36Sopenharmony_ci .cmd = CIFS_GENL_CMD_SWN_NOTIFY, 3662306a36Sopenharmony_ci .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 3762306a36Sopenharmony_ci .doit = cifs_swn_notify, 3862306a36Sopenharmony_ci }, 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic const struct genl_multicast_group cifs_genl_mcgrps[] = { 4262306a36Sopenharmony_ci [CIFS_GENL_MCGRP_SWN] = { .name = CIFS_GENL_MCGRP_SWN_NAME }, 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistruct genl_family cifs_genl_family = { 4662306a36Sopenharmony_ci .name = CIFS_GENL_NAME, 4762306a36Sopenharmony_ci .version = CIFS_GENL_VERSION, 4862306a36Sopenharmony_ci .hdrsize = 0, 4962306a36Sopenharmony_ci .maxattr = CIFS_GENL_ATTR_MAX, 5062306a36Sopenharmony_ci .module = THIS_MODULE, 5162306a36Sopenharmony_ci .policy = cifs_genl_policy, 5262306a36Sopenharmony_ci .ops = cifs_genl_ops, 5362306a36Sopenharmony_ci .n_ops = ARRAY_SIZE(cifs_genl_ops), 5462306a36Sopenharmony_ci .resv_start_op = CIFS_GENL_CMD_SWN_NOTIFY + 1, 5562306a36Sopenharmony_ci .mcgrps = cifs_genl_mcgrps, 5662306a36Sopenharmony_ci .n_mcgrps = ARRAY_SIZE(cifs_genl_mcgrps), 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/** 6062306a36Sopenharmony_ci * cifs_genl_init - Register generic netlink family 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * Return zero if initialized successfully, otherwise non-zero. 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ciint cifs_genl_init(void) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci int ret; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci ret = genl_register_family(&cifs_genl_family); 6962306a36Sopenharmony_ci if (ret < 0) { 7062306a36Sopenharmony_ci cifs_dbg(VFS, "%s: failed to register netlink family\n", 7162306a36Sopenharmony_ci __func__); 7262306a36Sopenharmony_ci return ret; 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci return 0; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/** 7962306a36Sopenharmony_ci * cifs_genl_exit - Unregister generic netlink family 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_civoid cifs_genl_exit(void) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci int ret; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci ret = genl_unregister_family(&cifs_genl_family); 8662306a36Sopenharmony_ci if (ret < 0) { 8762306a36Sopenharmony_ci cifs_dbg(VFS, "%s: failed to unregister netlink family\n", 8862306a36Sopenharmony_ci __func__); 8962306a36Sopenharmony_ci } 9062306a36Sopenharmony_ci} 91