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