xref: /spdk/lib/accel/accel_rpc.c (revision eb7506a1b4fb1589911dbb1ffb5ac60a048202be)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2020 Intel Corporation.
3  *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES.
4  *   All rights reserved.
5  */
6 
7 #include "accel_internal.h"
8 #include "spdk_internal/accel_module.h"
9 
10 #include "spdk/rpc.h"
11 #include "spdk/util.h"
12 #include "spdk/event.h"
13 #include "spdk/stdinc.h"
14 #include "spdk/env.h"
15 #include "spdk/util.h"
16 
17 static void
18 rpc_accel_get_opc_assignments(struct spdk_jsonrpc_request *request,
19 			      const struct spdk_json_val *params)
20 {
21 	struct spdk_json_write_ctx *w;
22 	enum accel_opcode opcode;
23 	const char *name, *module_name = NULL;
24 	int rc;
25 
26 	if (params != NULL) {
27 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
28 						 "accel_get_opc_assignments requires no parameters");
29 		return;
30 	}
31 
32 	w = spdk_jsonrpc_begin_result(request);
33 
34 	spdk_json_write_object_begin(w);
35 	for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) {
36 		rc = _accel_get_opc_name(opcode, &name);
37 		if (rc == 0) {
38 			rc = spdk_accel_get_opc_module_name(opcode, &module_name);
39 			if (rc == 0) {
40 				spdk_json_write_named_string(w, name, module_name);
41 			} else {
42 				/* This isn't fatal but throw an informational message if we
43 				 * cant get an module name right now */
44 				SPDK_NOTICELOG("FYI error (%d) getting module name.\n", rc);
45 			}
46 		} else {
47 			/* this should never happen */
48 			SPDK_ERRLOG("Invalid opcode (%d)).\n", opcode);
49 			assert(0);
50 		}
51 	}
52 	spdk_json_write_object_end(w);
53 
54 	spdk_jsonrpc_end_result(request, w);
55 }
56 SPDK_RPC_REGISTER("accel_get_opc_assignments", rpc_accel_get_opc_assignments, SPDK_RPC_RUNTIME)
57 
58 static void
59 rpc_dump_module_info(struct module_info *info)
60 {
61 	struct spdk_json_write_ctx *w = info->w;
62 	const char *name;
63 	uint32_t i;
64 	int rc;
65 
66 	spdk_json_write_object_begin(w);
67 
68 	spdk_json_write_named_string(w, "module", info->name);
69 	spdk_json_write_named_array_begin(w, "supported ops");
70 
71 	for (i = 0; i < info->num_ops; i++) {
72 		rc = _accel_get_opc_name(i, &name);
73 		if (rc == 0) {
74 			spdk_json_write_string(w, name);
75 		} else {
76 			/* this should never happen */
77 			SPDK_ERRLOG("Invalid opcode (%d)).\n", i);
78 			assert(0);
79 		}
80 	}
81 
82 	spdk_json_write_array_end(w);
83 	spdk_json_write_object_end(w);
84 }
85 
86 static void
87 rpc_accel_get_module_info(struct spdk_jsonrpc_request *request,
88 			  const struct spdk_json_val *params)
89 {
90 	struct module_info info;
91 
92 	if (params != NULL) {
93 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
94 						 "accel_get_module_info requires no parameters");
95 		return;
96 	}
97 
98 	info.w = spdk_jsonrpc_begin_result(request);
99 	spdk_json_write_array_begin(info.w);
100 
101 	_accel_for_each_module(&info, rpc_dump_module_info);
102 
103 	spdk_json_write_array_end(info.w);
104 	spdk_jsonrpc_end_result(request, info.w);
105 }
106 SPDK_RPC_REGISTER("accel_get_module_info", rpc_accel_get_module_info, SPDK_RPC_RUNTIME)
107 SPDK_RPC_REGISTER_ALIAS_DEPRECATED(accel_get_module_info, accel_get_engine_info)
108 
109 struct rpc_accel_assign_opc {
110 	char *opname;
111 	char *module;
112 };
113 
114 static const struct spdk_json_object_decoder rpc_accel_assign_opc_decoders[] = {
115 	{"opname", offsetof(struct rpc_accel_assign_opc, opname), spdk_json_decode_string},
116 	{"module", offsetof(struct rpc_accel_assign_opc, module), spdk_json_decode_string},
117 };
118 
119 static void
120 free_accel_assign_opc(struct rpc_accel_assign_opc *r)
121 {
122 	free(r->opname);
123 	free(r->module);
124 }
125 
126 static void
127 rpc_accel_assign_opc(struct spdk_jsonrpc_request *request,
128 		     const struct spdk_json_val *params)
129 {
130 	struct rpc_accel_assign_opc req = {};
131 	const char *opcode_str;
132 	enum accel_opcode opcode;
133 	bool found = false;
134 	int rc;
135 
136 	if (spdk_json_decode_object(params, rpc_accel_assign_opc_decoders,
137 				    SPDK_COUNTOF(rpc_accel_assign_opc_decoders),
138 				    &req)) {
139 		SPDK_DEBUGLOG(accel, "spdk_json_decode_object failed\n");
140 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
141 						 "spdk_json_decode_object failed");
142 		goto cleanup;
143 	}
144 
145 	for (opcode = 0; opcode < ACCEL_OPC_LAST; opcode++) {
146 		rc = _accel_get_opc_name(opcode, &opcode_str);
147 		assert(!rc);
148 		if (strcmp(opcode_str, req.opname) == 0) {
149 			found = true;
150 			break;
151 		}
152 	}
153 
154 	if (found == false) {
155 		SPDK_DEBUGLOG(accel, "Invalid operation name\n");
156 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
157 						 "spdk_json_decode_object failed");
158 		goto cleanup;
159 	}
160 
161 	rc = spdk_accel_assign_opc(opcode, req.module);
162 	if (rc) {
163 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
164 						 "error assigning opcode");
165 		goto cleanup;
166 	}
167 
168 	SPDK_NOTICELOG("Operation %s will be assigned to module %s\n", req.opname, req.module);
169 	spdk_jsonrpc_send_bool_response(request, true);
170 
171 cleanup:
172 	free_accel_assign_opc(&req);
173 
174 }
175 SPDK_RPC_REGISTER("accel_assign_opc", rpc_accel_assign_opc, SPDK_RPC_STARTUP)
176 
177 struct rpc_accel_crypto_key_create {
178 	struct spdk_accel_crypto_key_create_param param;
179 };
180 
181 static const struct spdk_json_object_decoder rpc_accel_dek_create_decoders[] = {
182 	{"cipher", offsetof(struct rpc_accel_crypto_key_create, param.cipher), spdk_json_decode_string},
183 	{"key", offsetof(struct rpc_accel_crypto_key_create, param.hex_key),   spdk_json_decode_string},
184 	{"key2", offsetof(struct rpc_accel_crypto_key_create, param.hex_key2), spdk_json_decode_string, true},
185 	{"name", offsetof(struct rpc_accel_crypto_key_create, param.key_name), spdk_json_decode_string},
186 };
187 
188 static void
189 rpc_accel_crypto_key_create(struct spdk_jsonrpc_request *request,
190 			    const struct spdk_json_val *params)
191 {
192 	struct rpc_accel_crypto_key_create req = {};
193 	size_t key_size;
194 	int rc;
195 
196 	if (spdk_json_decode_object(params, rpc_accel_dek_create_decoders,
197 				    SPDK_COUNTOF(rpc_accel_dek_create_decoders),
198 				    &req)) {
199 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
200 						 "spdk_json_decode_object failed");
201 		goto cleanup;
202 	}
203 
204 	rc = spdk_accel_crypto_key_create(&req.param);
205 	if (rc) {
206 		spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
207 						     "failed to create DEK, rc %d", rc);
208 	} else {
209 		spdk_jsonrpc_send_bool_response(request, true);
210 	}
211 
212 cleanup:
213 	free(req.param.cipher);
214 	if (req.param.hex_key) {
215 		key_size = strnlen(req.param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH);
216 		spdk_memset_s(req.param.hex_key, key_size, 0, key_size);
217 		free(req.param.hex_key);
218 	}
219 	if (req.param.hex_key2) {
220 		key_size = strnlen(req.param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH);
221 		spdk_memset_s(req.param.hex_key2, key_size, 0, key_size);
222 		free(req.param.hex_key2);
223 	}
224 	free(req.param.key_name);
225 }
226 SPDK_RPC_REGISTER("accel_crypto_key_create", rpc_accel_crypto_key_create, SPDK_RPC_RUNTIME)
227 
228 struct rpc_accel_crypto_keys_get_ctx {
229 	char *key_name;
230 };
231 
232 static const struct spdk_json_object_decoder rpc_accel_crypto_keys_get_decoders[] = {
233 	{"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string, true},
234 };
235 
236 static void
237 rpc_accel_crypto_keys_get(struct spdk_jsonrpc_request *request,
238 			  const struct spdk_json_val *params)
239 {
240 	struct rpc_accel_crypto_keys_get_ctx req = {};
241 	struct spdk_accel_crypto_key *key = NULL;
242 	struct spdk_json_write_ctx *w;
243 
244 	if (params && spdk_json_decode_object(params, rpc_accel_crypto_keys_get_decoders,
245 					      SPDK_COUNTOF(rpc_accel_crypto_keys_get_decoders),
246 					      &req)) {
247 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
248 						 "spdk_json_decode_object failed");
249 		free(req.key_name);
250 		return;
251 	}
252 
253 	if (req.key_name) {
254 		key = spdk_accel_crypto_key_get(req.key_name);
255 		free(req.key_name);
256 		if (!key) {
257 			spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "key was not found\n");
258 			return;
259 		}
260 	}
261 
262 	w = spdk_jsonrpc_begin_result(request);
263 	spdk_json_write_array_begin(w);
264 
265 	if (key) {
266 		_accel_crypto_key_dump_param(w, key);
267 	} else {
268 		_accel_crypto_keys_dump_param(w);
269 	}
270 
271 	spdk_json_write_array_end(w);
272 	spdk_jsonrpc_end_result(request, w);
273 }
274 SPDK_RPC_REGISTER("accel_crypto_keys_get", rpc_accel_crypto_keys_get, SPDK_RPC_RUNTIME)
275