xref: /spdk/lib/sock/sock_rpc.c (revision 4e6e7eafefea30d301a64549d65c40aa4d975dc6)
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 	spdk_json_write_object_end(w);
58 	spdk_jsonrpc_end_result(request, w);
59 	free(impl_name);
60 }
61 SPDK_RPC_REGISTER("sock_impl_get_options", rpc_sock_impl_get_options,
62 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
63 
64 struct spdk_rpc_sock_impl_set_opts {
65 	char *impl_name;
66 	struct spdk_sock_impl_opts sock_opts;
67 };
68 
69 static const struct spdk_json_object_decoder rpc_sock_impl_set_opts_decoders[] = {
70 	{
71 		"impl_name", offsetof(struct spdk_rpc_sock_impl_set_opts, impl_name),
72 		spdk_json_decode_string, false
73 	},
74 	{
75 		"recv_buf_size", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.recv_buf_size),
76 		spdk_json_decode_uint32, true
77 	},
78 	{
79 		"send_buf_size", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.send_buf_size),
80 		spdk_json_decode_uint32, true
81 	},
82 	{
83 		"enable_recv_pipe", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_recv_pipe),
84 		spdk_json_decode_bool, true
85 	},
86 	{
87 		"enable_quickack", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_quickack),
88 		spdk_json_decode_bool, true
89 	},
90 	{
91 		"enable_placement_id", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_placement_id),
92 		spdk_json_decode_uint32, true
93 	},
94 	{
95 		"enable_zerocopy_send_server", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_zerocopy_send_server),
96 		spdk_json_decode_bool, true
97 	},
98 	{
99 		"enable_zerocopy_send_client", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_zerocopy_send_client),
100 		spdk_json_decode_bool, true
101 	},
102 	{
103 		"zerocopy_threshold", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.zerocopy_threshold),
104 		spdk_json_decode_uint32, true
105 	},
106 	{
107 		"tls_version", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.tls_version),
108 		spdk_json_decode_uint32, true
109 	},
110 	{
111 		"enable_ktls", offsetof(struct spdk_rpc_sock_impl_set_opts, sock_opts.enable_ktls),
112 		spdk_json_decode_bool, true
113 	}
114 };
115 
116 static void
117 rpc_sock_impl_set_options(struct spdk_jsonrpc_request *request,
118 			  const struct spdk_json_val *params)
119 {
120 	struct spdk_rpc_sock_impl_set_opts opts = {};
121 	size_t len;
122 	int rc;
123 
124 	/* Get type */
125 	if (spdk_json_decode_object(params, rpc_sock_impl_set_opts_decoders,
126 				    SPDK_COUNTOF(rpc_sock_impl_set_opts_decoders), &opts)) {
127 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
128 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
129 						 "Invalid parameters");
130 		return;
131 	}
132 
133 	/* Retrieve default opts for requested socket implementation */
134 	len = sizeof(opts.sock_opts);
135 	rc = spdk_sock_impl_get_opts(opts.impl_name, &opts.sock_opts, &len);
136 	if (rc) {
137 		free(opts.impl_name);
138 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
139 						 "Invalid parameters");
140 		return;
141 	}
142 
143 	/* Decode opts */
144 	if (spdk_json_decode_object(params, rpc_sock_impl_set_opts_decoders,
145 				    SPDK_COUNTOF(rpc_sock_impl_set_opts_decoders), &opts)) {
146 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
147 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
148 						 "Invalid parameters");
149 		return;
150 	}
151 
152 	rc = spdk_sock_impl_set_opts(opts.impl_name, &opts.sock_opts, sizeof(opts.sock_opts));
153 	if (rc != 0) {
154 		free(opts.impl_name);
155 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
156 						 "Invalid parameters");
157 		return;
158 	}
159 
160 	spdk_jsonrpc_send_bool_response(request, true);
161 	free(opts.impl_name);
162 }
163 SPDK_RPC_REGISTER("sock_impl_set_options", rpc_sock_impl_set_options, SPDK_RPC_STARTUP)
164 
165 static void
166 rpc_sock_set_default_impl(struct spdk_jsonrpc_request *request,
167 			  const struct spdk_json_val *params)
168 {
169 	char *impl_name = NULL;
170 	int rc;
171 
172 	/* Reuse get_opts decoder */
173 	if (spdk_json_decode_object(params, rpc_sock_impl_get_opts_decoders,
174 				    SPDK_COUNTOF(rpc_sock_impl_get_opts_decoders), &impl_name)) {
175 		SPDK_ERRLOG("spdk_json_decode_object() failed\n");
176 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
177 						 "Invalid parameters");
178 		return;
179 	}
180 
181 	rc = spdk_sock_set_default_impl(impl_name);
182 	if (rc) {
183 		free(impl_name);
184 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
185 						 "Invalid parameters");
186 		return;
187 	}
188 
189 	spdk_jsonrpc_send_bool_response(request, true);
190 	free(impl_name);
191 }
192 SPDK_RPC_REGISTER("sock_set_default_impl", rpc_sock_set_default_impl, SPDK_RPC_STARTUP)
193