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