17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50a701b1eSRobert Gordon * Common Development and Distribution License (the "License").
60a701b1eSRobert Gordon * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
220a701b1eSRobert Gordon * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
24919f1431SAndrew Stormont *
25919f1431SAndrew Stormont * Copyright 2017 RackTop Systems.
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate #include <rpc/types.h>
297c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
310a701b1eSRobert Gordon #include <sys/sdt.h>
327c478bd9Sstevel@tonic-gate #include <rpc/auth.h>
337c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h>
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate struct private {
367c478bd9Sstevel@tonic-gate int min_chunk;
377c478bd9Sstevel@tonic-gate uint_t flags; /* controls setting for rdma xdr */
387c478bd9Sstevel@tonic-gate int num_chunk;
397c478bd9Sstevel@tonic-gate caddr_t inline_buf; /* temporary buffer for xdr inlining */
407c478bd9Sstevel@tonic-gate int inline_len; /* inline buffer length */
410a701b1eSRobert Gordon uint_t xp_reply_chunk_len;
420a701b1eSRobert Gordon uint_t xp_reply_chunk_len_alt;
437c478bd9Sstevel@tonic-gate };
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate /* ARGSUSED */
467c478bd9Sstevel@tonic-gate static bool_t
x_putint32_t(XDR * xdrs,int32_t * ip)477c478bd9Sstevel@tonic-gate x_putint32_t(XDR *xdrs, int32_t *ip)
487c478bd9Sstevel@tonic-gate {
497c478bd9Sstevel@tonic-gate xdrs->x_handy += BYTES_PER_XDR_UNIT;
507c478bd9Sstevel@tonic-gate return (TRUE);
517c478bd9Sstevel@tonic-gate }
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /* ARGSUSED */
547c478bd9Sstevel@tonic-gate static bool_t
x_putbytes(XDR * xdrs,char * bp,int len)557c478bd9Sstevel@tonic-gate x_putbytes(XDR *xdrs, char *bp, int len)
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private;
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate * min_chunk = 0, means that the stream of bytes, to estimate size of,
617c478bd9Sstevel@tonic-gate * contains no chunks to seperate out. See xdrrdma_putbytes()
627c478bd9Sstevel@tonic-gate */
630a701b1eSRobert Gordon if (len < xdrp->min_chunk || !(xdrp->flags & XDR_RDMA_CHUNK)) {
647c478bd9Sstevel@tonic-gate xdrs->x_handy += len;
657c478bd9Sstevel@tonic-gate return (TRUE);
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate * Chunk item. No impact on xdr size.
697c478bd9Sstevel@tonic-gate */
707c478bd9Sstevel@tonic-gate xdrp->num_chunk++;
710a701b1eSRobert Gordon
727c478bd9Sstevel@tonic-gate return (TRUE);
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate static uint_t
x_getpostn(XDR * xdrs)767c478bd9Sstevel@tonic-gate x_getpostn(XDR *xdrs)
777c478bd9Sstevel@tonic-gate {
787c478bd9Sstevel@tonic-gate return (xdrs->x_handy);
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate /* ARGSUSED */
827c478bd9Sstevel@tonic-gate static bool_t
x_setpostn(XDR * xdrs,uint_t pos)837c478bd9Sstevel@tonic-gate x_setpostn(XDR *xdrs, uint_t pos)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate /* This is not allowed */
867c478bd9Sstevel@tonic-gate return (FALSE);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate /* ARGSUSED */
907c478bd9Sstevel@tonic-gate static bool_t
x_control(XDR * xdrs,int request,void * info)917c478bd9Sstevel@tonic-gate x_control(XDR *xdrs, int request, void *info)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate int32_t *int32p;
947c478bd9Sstevel@tonic-gate uint_t in_flags;
950a701b1eSRobert Gordon rdma_chunkinfo_t *rcip = NULL;
960a701b1eSRobert Gordon rdma_chunkinfo_lengths_t *rcilp = NULL;
977c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private;
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate switch (request) {
1000a701b1eSRobert Gordon case XDR_RDMA_SET_FLAGS:
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate * Set the flags provided in the *info in xp_flags for rdma xdr
1037c478bd9Sstevel@tonic-gate * stream control.
1047c478bd9Sstevel@tonic-gate */
1057c478bd9Sstevel@tonic-gate int32p = (int32_t *)info;
1067c478bd9Sstevel@tonic-gate in_flags = (uint_t)(*int32p);
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate xdrp->flags = in_flags;
1097c478bd9Sstevel@tonic-gate return (TRUE);
1107c478bd9Sstevel@tonic-gate
1110a701b1eSRobert Gordon case XDR_RDMA_GET_FLAGS:
1127c478bd9Sstevel@tonic-gate /*
1137c478bd9Sstevel@tonic-gate * Get the flags provided in xp_flags return through *info
1147c478bd9Sstevel@tonic-gate */
1157c478bd9Sstevel@tonic-gate int32p = (int32_t *)info;
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate *int32p = (int32_t)xdrp->flags;
1187c478bd9Sstevel@tonic-gate return (TRUE);
1197c478bd9Sstevel@tonic-gate
1200a701b1eSRobert Gordon case XDR_RDMA_GET_CHUNK_LEN:
1210a701b1eSRobert Gordon rcilp = (rdma_chunkinfo_lengths_t *)info;
1220a701b1eSRobert Gordon rcilp->rcil_len = xdrp->xp_reply_chunk_len;
1230a701b1eSRobert Gordon rcilp->rcil_len_alt = xdrp->xp_reply_chunk_len_alt;
1240a701b1eSRobert Gordon
1250a701b1eSRobert Gordon return (TRUE);
1260a701b1eSRobert Gordon
1270a701b1eSRobert Gordon case XDR_RDMA_ADD_CHUNK:
1280a701b1eSRobert Gordon rcip = (rdma_chunkinfo_t *)info;
1290a701b1eSRobert Gordon
1300a701b1eSRobert Gordon switch (rcip->rci_type) {
1310a701b1eSRobert Gordon case RCI_WRITE_UIO_CHUNK:
1320a701b1eSRobert Gordon xdrp->xp_reply_chunk_len_alt += rcip->rci_len;
1330a701b1eSRobert Gordon break;
1340a701b1eSRobert Gordon
1350a701b1eSRobert Gordon case RCI_WRITE_ADDR_CHUNK:
1360a701b1eSRobert Gordon xdrp->xp_reply_chunk_len_alt += rcip->rci_len;
1370a701b1eSRobert Gordon break;
1380a701b1eSRobert Gordon
1390a701b1eSRobert Gordon case RCI_REPLY_CHUNK:
1400a701b1eSRobert Gordon xdrp->xp_reply_chunk_len += rcip->rci_len;
1410a701b1eSRobert Gordon break;
1420a701b1eSRobert Gordon }
1430a701b1eSRobert Gordon return (TRUE);
1440a701b1eSRobert Gordon
1457c478bd9Sstevel@tonic-gate default:
1467c478bd9Sstevel@tonic-gate return (FALSE);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate /* ARGSUSED */
1517c478bd9Sstevel@tonic-gate static rpc_inline_t *
x_inline(XDR * xdrs,int len)1527c478bd9Sstevel@tonic-gate x_inline(XDR *xdrs, int len)
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private;
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate if (len == 0) {
1577c478bd9Sstevel@tonic-gate return (NULL);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_ENCODE) {
1607c478bd9Sstevel@tonic-gate return (NULL);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate if (len >= xdrp->min_chunk) {
1637c478bd9Sstevel@tonic-gate return (NULL);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate if (len <= xdrp->inline_len) {
1667c478bd9Sstevel@tonic-gate /* inline_buf was already allocated, just reuse it */
1677c478bd9Sstevel@tonic-gate xdrs->x_handy += len;
1687c478bd9Sstevel@tonic-gate return ((rpc_inline_t *)xdrp->inline_buf);
1697c478bd9Sstevel@tonic-gate } else {
1707c478bd9Sstevel@tonic-gate /* Free the earlier space and allocate new area */
1717c478bd9Sstevel@tonic-gate if (xdrp->inline_buf)
1727c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len);
1737c478bd9Sstevel@tonic-gate if ((xdrp->inline_buf = (caddr_t)mem_alloc(len)) == NULL) {
1747c478bd9Sstevel@tonic-gate xdrp->inline_len = 0;
1757c478bd9Sstevel@tonic-gate return (NULL);
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate xdrp->inline_len = len;
1787c478bd9Sstevel@tonic-gate xdrs->x_handy += len;
1797c478bd9Sstevel@tonic-gate return ((rpc_inline_t *)xdrp->inline_buf);
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate static int
harmless()1847c478bd9Sstevel@tonic-gate harmless()
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate /* Always return FALSE/NULL, as the case may be */
1877c478bd9Sstevel@tonic-gate return (0);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate static void
x_destroy(XDR * xdrs)1917c478bd9Sstevel@tonic-gate x_destroy(XDR *xdrs)
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private;
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate xdrs->x_handy = 0;
1967c478bd9Sstevel@tonic-gate if (xdrp) {
1977c478bd9Sstevel@tonic-gate if (xdrp->inline_buf)
1987c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len);
1997c478bd9Sstevel@tonic-gate mem_free(xdrp, sizeof (struct private));
2007c478bd9Sstevel@tonic-gate xdrs->x_private = NULL;
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate xdrs->x_base = 0;
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate static bool_t
xdrrdma_common(XDR * xdrs,int min_chunk)2067c478bd9Sstevel@tonic-gate xdrrdma_common(XDR *xdrs, int min_chunk)
2077c478bd9Sstevel@tonic-gate {
2087c478bd9Sstevel@tonic-gate struct private *xdrp;
2097c478bd9Sstevel@tonic-gate
2107c478bd9Sstevel@tonic-gate xdrs->x_ops = xdrrdma_xops();
2117c478bd9Sstevel@tonic-gate xdrs->x_op = XDR_ENCODE;
2127c478bd9Sstevel@tonic-gate xdrs->x_handy = 0;
2137c478bd9Sstevel@tonic-gate xdrs->x_base = NULL;
2147c478bd9Sstevel@tonic-gate xdrs->x_private = kmem_zalloc(sizeof (struct private), KM_SLEEP);
2157c478bd9Sstevel@tonic-gate xdrp = (struct private *)xdrs->x_private;
2167c478bd9Sstevel@tonic-gate xdrp->min_chunk = min_chunk;
2177c478bd9Sstevel@tonic-gate xdrp->flags = 0;
2180a701b1eSRobert Gordon if (xdrp->min_chunk != 0)
2190a701b1eSRobert Gordon xdrp->flags |= XDR_RDMA_CHUNK;
2200a701b1eSRobert Gordon
2210a701b1eSRobert Gordon xdrp->xp_reply_chunk_len = 0;
2220a701b1eSRobert Gordon xdrp->xp_reply_chunk_len_alt = 0;
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate return (TRUE);
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate unsigned int
xdrrdma_sizeof(xdrproc_t func,void * data,int min_chunk,uint_t * reply_size,uint_t * reply_size_alt)2280a701b1eSRobert Gordon xdrrdma_sizeof(xdrproc_t func, void *data, int min_chunk,
2290a701b1eSRobert Gordon uint_t *reply_size, uint_t *reply_size_alt)
2307c478bd9Sstevel@tonic-gate {
2317c478bd9Sstevel@tonic-gate XDR x;
2327c478bd9Sstevel@tonic-gate struct xdr_ops ops;
2337c478bd9Sstevel@tonic-gate bool_t stat;
2347c478bd9Sstevel@tonic-gate struct private *xdrp;
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate x.x_ops = &ops;
2377c478bd9Sstevel@tonic-gate (void) xdrrdma_common(&x, min_chunk);
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate stat = func(&x, data);
2407c478bd9Sstevel@tonic-gate xdrp = (struct private *)x.x_private;
2417c478bd9Sstevel@tonic-gate if (xdrp) {
2420a701b1eSRobert Gordon if (reply_size != NULL)
2430a701b1eSRobert Gordon *reply_size = xdrp->xp_reply_chunk_len;
2440a701b1eSRobert Gordon if (reply_size_alt != NULL)
2450a701b1eSRobert Gordon *reply_size_alt = xdrp->xp_reply_chunk_len_alt;
2467c478bd9Sstevel@tonic-gate if (xdrp->inline_buf)
2477c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len);
2487c478bd9Sstevel@tonic-gate mem_free(xdrp, sizeof (struct private));
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate return (stat == TRUE ? (unsigned int)x.x_handy: 0);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate unsigned int
xdrrdma_authsize(AUTH * auth,struct cred * cred,int min_chunk)2547c478bd9Sstevel@tonic-gate xdrrdma_authsize(AUTH *auth, struct cred *cred, int min_chunk)
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate XDR x;
2577c478bd9Sstevel@tonic-gate struct xdr_ops ops;
2587c478bd9Sstevel@tonic-gate bool_t stat;
2597c478bd9Sstevel@tonic-gate struct private *xdrp;
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate x.x_ops = &ops;
2627c478bd9Sstevel@tonic-gate (void) xdrrdma_common(&x, min_chunk);
2637c478bd9Sstevel@tonic-gate
2647c478bd9Sstevel@tonic-gate stat = AUTH_MARSHALL(auth, &x, cred);
2657c478bd9Sstevel@tonic-gate xdrp = (struct private *)x.x_private;
2667c478bd9Sstevel@tonic-gate if (xdrp) {
2677c478bd9Sstevel@tonic-gate if (xdrp->inline_buf)
2687c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len);
2697c478bd9Sstevel@tonic-gate mem_free(xdrp, sizeof (struct private));
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate return (stat == TRUE ? (unsigned int)x.x_handy: 0);
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate
2740a701b1eSRobert Gordon struct xdr_ops *
xdrrdma_xops(void)2757c478bd9Sstevel@tonic-gate xdrrdma_xops(void)
2767c478bd9Sstevel@tonic-gate {
2777c478bd9Sstevel@tonic-gate static struct xdr_ops ops;
2787c478bd9Sstevel@tonic-gate
279*0827cc77SDan McDonald /* to stop ANSI-C compiler from complaining */
280*0827cc77SDan McDonald typedef bool_t (* dummyfunc1)(XDR *, caddr_t, int);
281*0827cc77SDan McDonald #if defined(_LP64) || defined(_KERNEL)
282*0827cc77SDan McDonald typedef bool_t (* dummyfunc2)(XDR *, int32_t *);
283*0827cc77SDan McDonald #endif
284*0827cc77SDan McDonald
2857c478bd9Sstevel@tonic-gate ops.x_putbytes = x_putbytes;
2867c478bd9Sstevel@tonic-gate ops.x_inline = x_inline;
2877c478bd9Sstevel@tonic-gate ops.x_getpostn = x_getpostn;
2887c478bd9Sstevel@tonic-gate ops.x_setpostn = x_setpostn;
2897c478bd9Sstevel@tonic-gate ops.x_destroy = x_destroy;
2907c478bd9Sstevel@tonic-gate ops.x_control = x_control;
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate #if defined(_LP64) || defined(_KERNEL)
293*0827cc77SDan McDonald ops.x_getint32 = (dummyfunc2)harmless;
2947c478bd9Sstevel@tonic-gate ops.x_putint32 = x_putint32_t;
2957c478bd9Sstevel@tonic-gate #endif
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate /* the other harmless ones */
298*0827cc77SDan McDonald ops.x_getbytes = (dummyfunc1)harmless;
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate return (&ops);
3017c478bd9Sstevel@tonic-gate }
302