SUNRPC: Plumb an API for setting transport layer security
authorChuck Lever <chuck.lever@oracle.com>
Wed, 7 Jun 2023 13:57:10 +0000 (09:57 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 19 Jun 2023 16:16:59 +0000 (12:16 -0400)
Add an initial set of policies along with fields for upper layers to
pass the requested policy down to the transport layer.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
include/linux/sunrpc/clnt.h
include/linux/sunrpc/xprt.h
net/sunrpc/clnt.c

index 770ef2c..063692c 100644 (file)
@@ -58,6 +58,7 @@ struct rpc_clnt {
                                cl_noretranstimeo: 1,/* No retransmit timeouts */
                                cl_autobind : 1,/* use getport() */
                                cl_chatty   : 1;/* be verbose */
+       struct xprtsec_parms    cl_xprtsec;     /* transport security policy */
 
        struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
        const struct rpc_timeout *cl_timeout;   /* Timeout strategy */
@@ -139,6 +140,7 @@ struct rpc_create_args {
        struct svc_xprt         *bc_xprt;       /* NFSv4.1 backchannel */
        const struct cred       *cred;
        unsigned int            max_connect;
+       struct xprtsec_parms    xprtsec;
 };
 
 struct rpc_add_xprt_test {
index b9f59aa..9e7f12c 100644 (file)
@@ -129,6 +129,21 @@ struct rpc_rqst {
 #define rq_svec                        rq_snd_buf.head
 #define rq_slen                        rq_snd_buf.len
 
+/* RPC transport layer security policies */
+enum xprtsec_policies {
+       RPC_XPRTSEC_NONE = 0,
+       RPC_XPRTSEC_TLS_ANON,
+       RPC_XPRTSEC_TLS_X509,
+};
+
+struct xprtsec_parms {
+       enum xprtsec_policies   policy;
+
+       /* authentication material */
+       key_serial_t            cert_serial;
+       key_serial_t            privkey_serial;
+};
+
 struct rpc_xprt_ops {
        void            (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
        int             (*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
@@ -229,6 +244,7 @@ struct rpc_xprt {
         */
        unsigned long           bind_timeout,
                                reestablish_timeout;
+       struct xprtsec_parms    xprtsec;
        unsigned int            connect_cookie; /* A cookie that gets bumped
                                                   every time the transport
                                                   is reconnected */
@@ -333,6 +349,7 @@ struct xprt_create {
        struct svc_xprt         *bc_xprt;       /* NFSv4.1 backchannel */
        struct rpc_xprt_switch  *bc_xps;
        unsigned int            flags;
+       struct xprtsec_parms    xprtsec;
 };
 
 struct xprt_class {
index 18f7085..8364b74 100644 (file)
@@ -385,6 +385,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
        if (!clnt)
                goto out_err;
        clnt->cl_parent = parent ? : clnt;
+       clnt->cl_xprtsec = args->xprtsec;
 
        err = rpc_alloc_clid(clnt);
        if (err)
@@ -532,6 +533,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
                .addrlen = args->addrsize,
                .servername = args->servername,
                .bc_xprt = args->bc_xprt,
+               .xprtsec = args->xprtsec,
        };
        char servername[48];
        struct rpc_clnt *clnt;
@@ -731,6 +733,7 @@ int rpc_switch_client_transport(struct rpc_clnt *clnt,
        struct rpc_clnt *parent;
        int err;
 
+       args->xprtsec = clnt->cl_xprtsec;
        xprt = xprt_create_transport(args);
        if (IS_ERR(xprt))
                return PTR_ERR(xprt);
@@ -3050,6 +3053,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
 
        if (!xprtargs->ident)
                xprtargs->ident = ident;
+       xprtargs->xprtsec = clnt->cl_xprtsec;
        xprt = xprt_create_transport(xprtargs);
        if (IS_ERR(xprt)) {
                ret = PTR_ERR(xprt);