aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2016-06-29 13:55:06 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-07-11 15:50:43 -0400
commit65b80179f9b8171b74625febf3457f41e792fa23 (patch)
tree91ed3dcb91c5bab4967ddfdf85132bb7b579a700
parent64695bde6c289a62250eb0a078916703c8cf639a (diff)
xprtrdma: No direct data placement with krb5i and krb5p
Direct data placement is not allowed when using flavors that guarantee integrity or privacy. When such security flavors are in effect, don't allow the use of Read and Write chunks for moving individual data items. All messages larger than the inline threshold are sent via Long Call or Long Reply. On my systems (CX-3 Pro on FDR), for small I/O operations, the use of Long messages adds only around 5 usecs of latency in each direction. Note that when integrity or encryption is used, the host CPU touches every byte in these messages. Even if it could be used, data movement offload doesn't buy much in this case. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Tested-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--include/linux/sunrpc/auth.h3
-rw-r--r--include/linux/sunrpc/gss_api.h2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c2
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c12
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c12
6 files changed, 31 insertions, 2 deletions
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 899791573a40..3a40287b4d27 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -107,6 +107,9 @@ struct rpc_auth {
107 /* per-flavor data */ 107 /* per-flavor data */
108}; 108};
109 109
110/* rpc_auth au_flags */
111#define RPCAUTH_AUTH_DATATOUCH 0x00000002
112
110struct rpc_auth_create_args { 113struct rpc_auth_create_args {
111 rpc_authflavor_t pseudoflavor; 114 rpc_authflavor_t pseudoflavor;
112 const char *target_name; 115 const char *target_name;
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
index 1f911ccb2a75..68ec78c1aa48 100644
--- a/include/linux/sunrpc/gss_api.h
+++ b/include/linux/sunrpc/gss_api.h
@@ -73,6 +73,7 @@ u32 gss_delete_sec_context(
73rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 qop, 73rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 qop,
74 u32 service); 74 u32 service);
75u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor); 75u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor);
76bool gss_pseudoflavor_to_datatouch(struct gss_api_mech *, u32 pseudoflavor);
76char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service); 77char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
77 78
78struct pf_desc { 79struct pf_desc {
@@ -81,6 +82,7 @@ struct pf_desc {
81 u32 service; 82 u32 service;
82 char *name; 83 char *name;
83 char *auth_domain_name; 84 char *auth_domain_name;
85 bool datatouch;
84}; 86};
85 87
86/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and 88/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index e64ae93d5b4f..bca3537efffd 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1017,6 +1017,8 @@ gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1017 auth->au_rslack = GSS_VERF_SLACK >> 2; 1017 auth->au_rslack = GSS_VERF_SLACK >> 2;
1018 auth->au_ops = &authgss_ops; 1018 auth->au_ops = &authgss_ops;
1019 auth->au_flavor = flavor; 1019 auth->au_flavor = flavor;
1020 if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor))
1021 auth->au_flags |= RPCAUTH_AUTH_DATATOUCH;
1020 atomic_set(&auth->au_count, 1); 1022 atomic_set(&auth->au_count, 1);
1021 kref_init(&gss_auth->kref); 1023 kref_init(&gss_auth->kref);
1022 1024
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 65427492b1c9..60595835317a 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -745,12 +745,14 @@ static struct pf_desc gss_kerberos_pfs[] = {
745 .qop = GSS_C_QOP_DEFAULT, 745 .qop = GSS_C_QOP_DEFAULT,
746 .service = RPC_GSS_SVC_INTEGRITY, 746 .service = RPC_GSS_SVC_INTEGRITY,
747 .name = "krb5i", 747 .name = "krb5i",
748 .datatouch = true,
748 }, 749 },
749 [2] = { 750 [2] = {
750 .pseudoflavor = RPC_AUTH_GSS_KRB5P, 751 .pseudoflavor = RPC_AUTH_GSS_KRB5P,
751 .qop = GSS_C_QOP_DEFAULT, 752 .qop = GSS_C_QOP_DEFAULT,
752 .service = RPC_GSS_SVC_PRIVACY, 753 .service = RPC_GSS_SVC_PRIVACY,
753 .name = "krb5p", 754 .name = "krb5p",
755 .datatouch = true,
754 }, 756 },
755}; 757};
756 758
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 7063d856a598..5fec3abbe19b 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -361,6 +361,18 @@ gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
361} 361}
362EXPORT_SYMBOL(gss_pseudoflavor_to_service); 362EXPORT_SYMBOL(gss_pseudoflavor_to_service);
363 363
364bool
365gss_pseudoflavor_to_datatouch(struct gss_api_mech *gm, u32 pseudoflavor)
366{
367 int i;
368
369 for (i = 0; i < gm->gm_pf_num; i++) {
370 if (gm->gm_pfs[i].pseudoflavor == pseudoflavor)
371 return gm->gm_pfs[i].datatouch;
372 }
373 return false;
374}
375
364char * 376char *
365gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) 377gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
366{ 378{
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index dac2990ae2f7..a47f170b20ef 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -570,6 +570,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
570 struct rpcrdma_req *req = rpcr_to_rdmar(rqst); 570 struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
571 enum rpcrdma_chunktype rtype, wtype; 571 enum rpcrdma_chunktype rtype, wtype;
572 struct rpcrdma_msg *headerp; 572 struct rpcrdma_msg *headerp;
573 bool ddp_allowed;
573 ssize_t hdrlen; 574 ssize_t hdrlen;
574 size_t rpclen; 575 size_t rpclen;
575 __be32 *iptr; 576 __be32 *iptr;
@@ -586,6 +587,13 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
586 headerp->rm_credit = cpu_to_be32(r_xprt->rx_buf.rb_max_requests); 587 headerp->rm_credit = cpu_to_be32(r_xprt->rx_buf.rb_max_requests);
587 headerp->rm_type = rdma_msg; 588 headerp->rm_type = rdma_msg;
588 589
590 /* When the ULP employs a GSS flavor that guarantees integrity
591 * or privacy, direct data placement of individual data items
592 * is not allowed.
593 */
594 ddp_allowed = !(rqst->rq_cred->cr_auth->au_flags &
595 RPCAUTH_AUTH_DATATOUCH);
596
589 /* 597 /*
590 * Chunks needed for results? 598 * Chunks needed for results?
591 * 599 *
@@ -597,7 +605,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
597 */ 605 */
598 if (rpcrdma_results_inline(r_xprt, rqst)) 606 if (rpcrdma_results_inline(r_xprt, rqst))
599 wtype = rpcrdma_noch; 607 wtype = rpcrdma_noch;
600 else if (rqst->rq_rcv_buf.flags & XDRBUF_READ) 608 else if (ddp_allowed && rqst->rq_rcv_buf.flags & XDRBUF_READ)
601 wtype = rpcrdma_writech; 609 wtype = rpcrdma_writech;
602 else 610 else
603 wtype = rpcrdma_replych; 611 wtype = rpcrdma_replych;
@@ -620,7 +628,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
620 rtype = rpcrdma_noch; 628 rtype = rpcrdma_noch;
621 rpcrdma_inline_pullup(rqst); 629 rpcrdma_inline_pullup(rqst);
622 rpclen = rqst->rq_svec[0].iov_len; 630 rpclen = rqst->rq_svec[0].iov_len;
623 } else if (rqst->rq_snd_buf.flags & XDRBUF_WRITE) { 631 } else if (ddp_allowed && rqst->rq_snd_buf.flags & XDRBUF_WRITE) {
624 rtype = rpcrdma_readch; 632 rtype = rpcrdma_readch;
625 rpclen = rqst->rq_svec[0].iov_len; 633 rpclen = rqst->rq_svec[0].iov_len;
626 rpclen += rpcrdma_tail_pullup(&rqst->rq_snd_buf); 634 rpclen += rpcrdma_tail_pullup(&rqst->rq_snd_buf);