@@ -32,6 +32,12 @@
struct rpc_inode;
struct rpc_sysfs_client;
+enum rpc_xprtsec {
+ RPC_XPRTSEC_NONE, /* No transport security is used */
+ RPC_XPRTSEC_TLS, /* RPC-with-TLS, encryption only */
+ RPC_XPRTSEC_MTLS, /* RPC-with-TLS, peer auth plus encryption */
+};
+
/*
* The high-level client handle
*/
@@ -58,6 +64,7 @@ struct rpc_clnt {
cl_noretranstimeo: 1,/* No retransmit timeouts */
cl_autobind : 1,/* use getport() */
cl_chatty : 1;/* be verbose */
+ enum rpc_xprtsec cl_xprtsec_policy; /* transport security policy */
struct rpc_rtt * cl_rtt; /* RTO estimator data */
const struct rpc_timeout *cl_timeout; /* Timeout strategy */
@@ -139,6 +139,16 @@ DEFINE_RPC_CLNT_EVENT(release);
DEFINE_RPC_CLNT_EVENT(replace_xprt);
DEFINE_RPC_CLNT_EVENT(replace_xprt_err);
+TRACE_DEFINE_ENUM(RPC_XPRTSEC_NONE);
+TRACE_DEFINE_ENUM(RPC_XPRTSEC_TLS);
+TRACE_DEFINE_ENUM(RPC_XPRTSEC_MTLS);
+
+#define rpc_show_xprtsec_policy(policy) \
+ __print_symbolic(policy, \
+ { RPC_XPRTSEC_NONE, "none" }, \
+ { RPC_XPRTSEC_TLS, "tls" }, \
+ { RPC_XPRTSEC_MTLS, "mtls" })
+
TRACE_EVENT(rpc_clnt_new,
TP_PROTO(
const struct rpc_clnt *clnt,
@@ -1535,6 +1545,50 @@ TRACE_EVENT(rpcb_unregister,
)
);
+/**
+ ** RPC-over-TLS tracepoints
+ **/
+
+DECLARE_EVENT_CLASS(rpc_tls_class,
+ TP_PROTO(
+ const struct rpc_clnt *clnt,
+ const struct rpc_xprt *xprt
+ ),
+
+ TP_ARGS(clnt, xprt),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, requested_policy)
+ __field(u32, version)
+ __string(servername, xprt->servername)
+ __string(progname, clnt->cl_program->name)
+ ),
+
+ TP_fast_assign(
+ __entry->requested_policy = clnt->cl_xprtsec_policy;
+ __entry->version = clnt->cl_vers;
+ __assign_str(servername, xprt->servername);
+ __assign_str(progname, clnt->cl_program->name)
+ ),
+
+ TP_printk("server=%s %sv%u requested_policy=%s",
+ __get_str(servername), __get_str(progname), __entry->version,
+ rpc_show_xprtsec_policy(__entry->requested_policy)
+ )
+);
+
+#define DEFINE_RPC_TLS_EVENT(name) \
+ DEFINE_EVENT(rpc_tls_class, rpc_tls_##name, \
+ TP_PROTO( \
+ const struct rpc_clnt *clnt, \
+ const struct rpc_xprt *xprt \
+ ), \
+ TP_ARGS(clnt, xprt))
+
+DEFINE_RPC_TLS_EVENT(unavailable);
+DEFINE_RPC_TLS_EVENT(not_started);
+
+
/* Record an xdr_buf containing a fully-formed RPC message */
DECLARE_EVENT_CLASS(svc_xdr_msg_class,
TP_PROTO(
@@ -477,6 +477,7 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
if (IS_ERR(clnt))
return clnt;
+ clnt->cl_xprtsec_policy = RPC_XPRTSEC_NONE;
if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
int err = rpc_ping(clnt);
if (err != 0) {
@@ -643,6 +644,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
new->cl_noretranstimeo = clnt->cl_noretranstimeo;
new->cl_discrtry = clnt->cl_discrtry;
new->cl_chatty = clnt->cl_chatty;
+ new->cl_xprtsec_policy = clnt->cl_xprtsec_policy;
new->cl_principal = clnt->cl_principal;
return new;
The Linux RPC client will support one transport security policy for each struct rpc_clnt: Three basic ones are added initially: = None: No transport security for this rpc_clnt. = TLS: The RPC client will establish a TLS session with encryption for this rpc_clnt. = mTLS: The RPC client will perform mutual peer authentication and establish a TLS session with encryption for this rpc_clnt. Add tracepoints that are used to create an audit trail of TLS usage, as REQUIRED by Section 7.1 of draft-ietf-nfsv4-rpc-tls-11 . Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- include/linux/sunrpc/clnt.h | 7 +++++ include/trace/events/sunrpc.h | 54 +++++++++++++++++++++++++++++++++++++++++ net/sunrpc/clnt.c | 2 ++ 3 files changed, 63 insertions(+)