xref: /spdk/lib/sock/sock_rpc.c (revision 307b8c112ffd90a26d53dd15fad67bd9038ef526)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) 2020, 2021 Mellanox Technologies LTD. All rights reserved.
3  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4  */
5 
6 #include "spdk/sock.h"
7 
8 #include "spdk/rpc.h"
9 #include "spdk/util.h"
10 #include "spdk/string.h"
11 
12 #include "spdk/log.h"
13 
14 
15 static const struct spdk_json_object_decoder rpc_sock_impl_get_opts_decoders[] = {
16 	{ "impl_name", 0, spdk_json_decode_string, false },
17 };
18 
19 static void
20 rpc_sock_impl_get_options(struct spdk_jsonrpc_request *request,
21 			  const struct spdk_json_val *params)
22 {
23 	char *impl_name = NULL;
24 	struct spdk_sock_impl_opts sock_opts = {};
25 	struct spdk_json_write_ctx *w;
26 	size_t len;
27 	int rc;
28 
29 	if (spdk_json_decode_object(params, rpc_sock_impl_get_opts_decoders,
30 				    SPDK_COUNTOF(rpc_sock_impl_get_opts_decoders), &impl_name)) {
31 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
32 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
33 						 "Invalid parameters");
34 		return;
35 	}
36 
37 	len = sizeof(sock_opts);
38 	rc = spdk_sock_impl_get_opts(impl_name, &sock_opts, &len);
39 	if (rc) {
40 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
41 						 "Invalid parameters");
42 		return;
43 	}
44 
45 	w = spdk_jsonrpc_begin_result(request);
46 	spdk_json_write_object_begin(w);
47 	spdk_json_write_named_uint32(w, "recv_buf_size", sock_opts.recv_buf_size);
48 	spdk_json_write_named_uint32(w, "send_buf_size", sock_opts.send_buf_size);
49 	spdk_json_write_named_bool(w, "enable_recv_pipe", sock_opts.enable_recv_pipe);
50 	spdk_json_write_named_bool(w, "enable_quickack", sock_opts.enable_quickack);
51 	spdk_json_write_named_uint32(w, "enable_placement_id", sock_opts.enable_placement_id);
52 	spdk_json_write_named_bool(w, "enable_zerocopy_send_server", sock_opts.enable_zerocopy_send_server);
53 	spdk_json_write_named_bool(w, "enable_zerocopy_send_client", sock_opts.enable_zerocopy_send_client);
54 	spdk_json_write_named_uint32(w, "zerocopy_threshold", sock_opts.zerocopy_threshold);
55 	spdk_json_write_named_uint32(w, "tls_version", sock_opts.tls_version);
56 	spdk_json_write_named_bool(w, "enable_ktls", sock_opts.enable_ktls);
57 	if (sock_opts.psk_key) {
58 		spdk_json_write_named_string(w, "psk_key", sock_opts.psk_key);
59 	}
60 	if (sock_opts.psk_identity) {
61 		spdk_json_write_named_string(w, "psk_identity", sock_opts.psk_identity);
62 	}
63 	spdk_json_write_object_end(w);
64 	spdk_jsonrpc_end_result(request, w);
65 	free(impl_name);
66 }
67 SPDK_RPC_REGISTER("sock_impl_get_options", rpc_sock_impl_get_options,
68 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
69 
70 struct spdk_rpc_sock_impl_set_opts {
71 	char *impl_name;
72 	struct spdk_sock_impl_opts sock_opts;
73 };
74 
75 static const struct spdk_json_object_decoder rpc_sock_impl_set_opts_decoders[] = {
76 	{
77 		"impl_name", offsetof(struct spdk_rpc_sock_impl_set_opts, impl_name),
78 		spdk_json_decode_string, false
79 	},
80 	{
81 		"recv_buf_size", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.recv_buf_size),
82 		spdk_json_decode_uint32, true
83 	},
84 	{
85 		"send_buf_size", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.send_buf_size),
86 		spdk_json_decode_uint32, true
87 	},
88 	{
89 		"enable_recv_pipe", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_recv_pipe),
90 		spdk_json_decode_bool, true
91 	},
92 	{
93 		"enable_quickack", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_quickack),
94 		spdk_json_decode_bool, true
95 	},
96 	{
97 		"enable_placement_id", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_placement_id),
98 		spdk_json_decode_uint32, true
99 	},
100 	{
101 		"enable_zerocopy_send_server", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_zerocopy_send_server),
102 		spdk_json_decode_bool, true
103 	},
104 	{
105 		"enable_zerocopy_send_client", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_zerocopy_send_client),
106 		spdk_json_decode_bool, true
107 	},
108 	{
109 		"zerocopy_threshold", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.zerocopy_threshold),
110 		spdk_json_decode_uint32, true
111 	},
112 	{
113 		"tls_version", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.tls_version),
114 		spdk_json_decode_uint32, true
115 	},
116 	{
117 		"enable_ktls", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_ktls),
118 		spdk_json_decode_bool, true
119 	},
120 	{
121 		"psk_key", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.psk_key),
122 		spdk_json_decode_string, true
123 	},
124 	{
125 		"psk_identity", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.psk_identity),
126 		spdk_json_decode_string, true
127 	}
128 };
129 
130 static void
131 rpc_sock_impl_set_options(struct spdk_jsonrpc_request *request,
132 			  const struct spdk_json_val *params)
133 {
134 	struct spdk_rpc_sock_impl_set_opts opts = {};
135 	size_t len;
136 	int rc;
137 
138 	/* Get type */
139 	if (spdk_json_decode_object(params, rpc_sock_impl_set_opts_decoders,
140 				    SPDK_COUNTOF(rpc_sock_impl_set_opts_decoders), &opts)) {
141 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
142 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
143 						 "Invalid parameters");
144 		return;
145 	}
146 
147 	/* Retrieve default opts for requested socket implementation */
148 	len = sizeof(opts.sock_opts);
149 	rc = spdk_sock_impl_get_opts(opts.impl_name, &opts.sock_opts, &len);
150 	if (rc) {
151 		free(opts.impl_name);
152 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
153 						 "Invalid parameters");
154 		return;
155 	}
156 
157 	/* Decode opts */
158 	if (spdk_json_decode_object(params, rpc_sock_impl_set_opts_decoders,
159 				    SPDK_COUNTOF(rpc_sock_impl_set_opts_decoders), &opts)) {
160 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
161 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
162 						 "Invalid parameters");
163 		return;
164 	}
165 
166 	rc = spdk_sock_impl_set_opts(opts.impl_name, &opts.sock_opts, sizeof(opts.sock_opts));
167 	if (rc != 0) {
168 		free(opts.impl_name);
169 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
170 						 "Invalid parameters");
171 		return;
172 	}
173 
174 	spdk_jsonrpc_send_bool_response(request, true);
175 	free(opts.impl_name);
176 }
177 SPDK_RPC_REGISTER("sock_impl_set_options", rpc_sock_impl_set_options, SPDK_RPC_STARTUP)
178 
179 static void
180 rpc_sock_set_default_impl(struct spdk_jsonrpc_request *request,
181 			  const struct spdk_json_val *params)
182 {
183 	char *impl_name = NULL;
184 	int rc;
185 
186 	/* Reuse get_opts decoder */
187 	if (spdk_json_decode_object(params, rpc_sock_impl_get_opts_decoders,
188 				    SPDK_COUNTOF(rpc_sock_impl_get_opts_decoders), &impl_name)) {
189 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
190 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
191 						 "Invalid parameters");
192 		return;
193 	}
194 
195 	rc = spdk_sock_set_default_impl(impl_name);
196 	if (rc) {
197 		free(impl_name);
198 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
199 						 "Invalid parameters");
200 		return;
201 	}
202 
203 	spdk_jsonrpc_send_bool_response(request, true);
204 	free(impl_name);
205 }
206 SPDK_RPC_REGISTER("sock_set_default_impl", rpc_sock_set_default_impl, SPDK_RPC_STARTUP)
207