1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <rpc/types.h> 30*7c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 32*7c478bd9Sstevel@tonic-gate #include <rpc/auth.h> 33*7c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h> 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate static struct xdr_ops *xdrrdma_xops(void); 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate struct private { 38*7c478bd9Sstevel@tonic-gate int min_chunk; 39*7c478bd9Sstevel@tonic-gate uint_t flags; /* controls setting for rdma xdr */ 40*7c478bd9Sstevel@tonic-gate int num_chunk; 41*7c478bd9Sstevel@tonic-gate caddr_t inline_buf; /* temporary buffer for xdr inlining */ 42*7c478bd9Sstevel@tonic-gate int inline_len; /* inline buffer length */ 43*7c478bd9Sstevel@tonic-gate }; 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 46*7c478bd9Sstevel@tonic-gate static bool_t 47*7c478bd9Sstevel@tonic-gate x_putint32_t(XDR *xdrs, int32_t *ip) 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate xdrs->x_handy += BYTES_PER_XDR_UNIT; 50*7c478bd9Sstevel@tonic-gate return (TRUE); 51*7c478bd9Sstevel@tonic-gate } 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 54*7c478bd9Sstevel@tonic-gate static bool_t 55*7c478bd9Sstevel@tonic-gate x_putbytes(XDR *xdrs, char *bp, int len) 56*7c478bd9Sstevel@tonic-gate { 57*7c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * min_chunk = 0, means that the stream of bytes, to estimate size of, 61*7c478bd9Sstevel@tonic-gate * contains no chunks to seperate out. See xdrrdma_putbytes() 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate if (len < xdrp->min_chunk || (xdrp->flags & RDMA_NOCHUNK)) { 64*7c478bd9Sstevel@tonic-gate xdrs->x_handy += len; 65*7c478bd9Sstevel@tonic-gate return (TRUE); 66*7c478bd9Sstevel@tonic-gate } 67*7c478bd9Sstevel@tonic-gate /* 68*7c478bd9Sstevel@tonic-gate * Chunk item. No impact on xdr size. 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate xdrp->num_chunk++; 71*7c478bd9Sstevel@tonic-gate return (TRUE); 72*7c478bd9Sstevel@tonic-gate } 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate static uint_t 75*7c478bd9Sstevel@tonic-gate x_getpostn(XDR *xdrs) 76*7c478bd9Sstevel@tonic-gate { 77*7c478bd9Sstevel@tonic-gate return (xdrs->x_handy); 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 81*7c478bd9Sstevel@tonic-gate static bool_t 82*7c478bd9Sstevel@tonic-gate x_setpostn(XDR *xdrs, uint_t pos) 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate /* This is not allowed */ 85*7c478bd9Sstevel@tonic-gate return (FALSE); 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 89*7c478bd9Sstevel@tonic-gate static bool_t 90*7c478bd9Sstevel@tonic-gate x_control(XDR *xdrs, int request, void *info) 91*7c478bd9Sstevel@tonic-gate { 92*7c478bd9Sstevel@tonic-gate int32_t *int32p; 93*7c478bd9Sstevel@tonic-gate uint_t in_flags; 94*7c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private; 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate switch (request) { 97*7c478bd9Sstevel@tonic-gate case XDR_RDMASET: 98*7c478bd9Sstevel@tonic-gate /* 99*7c478bd9Sstevel@tonic-gate * Set the flags provided in the *info in xp_flags for rdma xdr 100*7c478bd9Sstevel@tonic-gate * stream control. 101*7c478bd9Sstevel@tonic-gate */ 102*7c478bd9Sstevel@tonic-gate int32p = (int32_t *)info; 103*7c478bd9Sstevel@tonic-gate in_flags = (uint_t)(*int32p); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate xdrp->flags = in_flags; 106*7c478bd9Sstevel@tonic-gate return (TRUE); 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate case XDR_RDMAGET: 109*7c478bd9Sstevel@tonic-gate /* 110*7c478bd9Sstevel@tonic-gate * Get the flags provided in xp_flags return through *info 111*7c478bd9Sstevel@tonic-gate */ 112*7c478bd9Sstevel@tonic-gate int32p = (int32_t *)info; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate *int32p = (int32_t)xdrp->flags; 115*7c478bd9Sstevel@tonic-gate return (TRUE); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate default: 118*7c478bd9Sstevel@tonic-gate return (FALSE); 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 123*7c478bd9Sstevel@tonic-gate static rpc_inline_t * 124*7c478bd9Sstevel@tonic-gate x_inline(XDR *xdrs, int len) 125*7c478bd9Sstevel@tonic-gate { 126*7c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private; 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate if (len == 0) { 129*7c478bd9Sstevel@tonic-gate return (NULL); 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_ENCODE) { 132*7c478bd9Sstevel@tonic-gate return (NULL); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate if (len >= xdrp->min_chunk) { 135*7c478bd9Sstevel@tonic-gate return (NULL); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate if (len <= xdrp->inline_len) { 138*7c478bd9Sstevel@tonic-gate /* inline_buf was already allocated, just reuse it */ 139*7c478bd9Sstevel@tonic-gate xdrs->x_handy += len; 140*7c478bd9Sstevel@tonic-gate return ((rpc_inline_t *)xdrp->inline_buf); 141*7c478bd9Sstevel@tonic-gate } else { 142*7c478bd9Sstevel@tonic-gate /* Free the earlier space and allocate new area */ 143*7c478bd9Sstevel@tonic-gate if (xdrp->inline_buf) 144*7c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len); 145*7c478bd9Sstevel@tonic-gate if ((xdrp->inline_buf = (caddr_t)mem_alloc(len)) == NULL) { 146*7c478bd9Sstevel@tonic-gate xdrp->inline_len = 0; 147*7c478bd9Sstevel@tonic-gate return (NULL); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate xdrp->inline_len = len; 150*7c478bd9Sstevel@tonic-gate xdrs->x_handy += len; 151*7c478bd9Sstevel@tonic-gate return ((rpc_inline_t *)xdrp->inline_buf); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate static int 156*7c478bd9Sstevel@tonic-gate harmless() 157*7c478bd9Sstevel@tonic-gate { 158*7c478bd9Sstevel@tonic-gate /* Always return FALSE/NULL, as the case may be */ 159*7c478bd9Sstevel@tonic-gate return (0); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate static void 163*7c478bd9Sstevel@tonic-gate x_destroy(XDR *xdrs) 164*7c478bd9Sstevel@tonic-gate { 165*7c478bd9Sstevel@tonic-gate struct private *xdrp = (struct private *)xdrs->x_private; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 168*7c478bd9Sstevel@tonic-gate if (xdrp) { 169*7c478bd9Sstevel@tonic-gate if (xdrp->inline_buf) 170*7c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len); 171*7c478bd9Sstevel@tonic-gate mem_free(xdrp, sizeof (struct private)); 172*7c478bd9Sstevel@tonic-gate xdrs->x_private = NULL; 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate xdrs->x_base = 0; 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate static bool_t 178*7c478bd9Sstevel@tonic-gate xdrrdma_common(XDR *xdrs, int min_chunk) 179*7c478bd9Sstevel@tonic-gate { 180*7c478bd9Sstevel@tonic-gate struct private *xdrp; 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate xdrs->x_ops = xdrrdma_xops(); 183*7c478bd9Sstevel@tonic-gate xdrs->x_op = XDR_ENCODE; 184*7c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 185*7c478bd9Sstevel@tonic-gate xdrs->x_base = NULL; 186*7c478bd9Sstevel@tonic-gate xdrs->x_private = kmem_zalloc(sizeof (struct private), KM_SLEEP); 187*7c478bd9Sstevel@tonic-gate xdrp = (struct private *)xdrs->x_private; 188*7c478bd9Sstevel@tonic-gate xdrp->min_chunk = min_chunk; 189*7c478bd9Sstevel@tonic-gate xdrp->flags = 0; 190*7c478bd9Sstevel@tonic-gate if (xdrp->min_chunk == 0) 191*7c478bd9Sstevel@tonic-gate xdrp->flags |= RDMA_NOCHUNK; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate return (TRUE); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate unsigned int 197*7c478bd9Sstevel@tonic-gate xdrrdma_sizeof(xdrproc_t func, void *data, int min_chunk) 198*7c478bd9Sstevel@tonic-gate { 199*7c478bd9Sstevel@tonic-gate XDR x; 200*7c478bd9Sstevel@tonic-gate struct xdr_ops ops; 201*7c478bd9Sstevel@tonic-gate bool_t stat; 202*7c478bd9Sstevel@tonic-gate struct private *xdrp; 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate x.x_ops = &ops; 205*7c478bd9Sstevel@tonic-gate (void) xdrrdma_common(&x, min_chunk); 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate stat = func(&x, data); 208*7c478bd9Sstevel@tonic-gate xdrp = (struct private *)x.x_private; 209*7c478bd9Sstevel@tonic-gate if (xdrp) { 210*7c478bd9Sstevel@tonic-gate if (xdrp->inline_buf) 211*7c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len); 212*7c478bd9Sstevel@tonic-gate mem_free(xdrp, sizeof (struct private)); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate return (stat == TRUE ? (unsigned int)x.x_handy: 0); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate unsigned int 218*7c478bd9Sstevel@tonic-gate xdrrdma_authsize(AUTH *auth, struct cred *cred, int min_chunk) 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate XDR x; 221*7c478bd9Sstevel@tonic-gate struct xdr_ops ops; 222*7c478bd9Sstevel@tonic-gate bool_t stat; 223*7c478bd9Sstevel@tonic-gate struct private *xdrp; 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate x.x_ops = &ops; 226*7c478bd9Sstevel@tonic-gate (void) xdrrdma_common(&x, min_chunk); 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate stat = AUTH_MARSHALL(auth, &x, cred); 229*7c478bd9Sstevel@tonic-gate xdrp = (struct private *)x.x_private; 230*7c478bd9Sstevel@tonic-gate if (xdrp) { 231*7c478bd9Sstevel@tonic-gate if (xdrp->inline_buf) 232*7c478bd9Sstevel@tonic-gate mem_free(xdrp->inline_buf, xdrp->inline_len); 233*7c478bd9Sstevel@tonic-gate mem_free(xdrp, sizeof (struct private)); 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate return (stat == TRUE ? (unsigned int)x.x_handy: 0); 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate static struct xdr_ops * 239*7c478bd9Sstevel@tonic-gate xdrrdma_xops(void) 240*7c478bd9Sstevel@tonic-gate { 241*7c478bd9Sstevel@tonic-gate static struct xdr_ops ops; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* to stop ANSI-C compiler from complaining */ 244*7c478bd9Sstevel@tonic-gate typedef bool_t (* dummyfunc1)(XDR *, long *); 245*7c478bd9Sstevel@tonic-gate typedef bool_t (* dummyfunc2)(XDR *, caddr_t, int); 246*7c478bd9Sstevel@tonic-gate typedef bool_t (* dummyfunc3)(XDR *, int32_t *); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate ops.x_putbytes = x_putbytes; 249*7c478bd9Sstevel@tonic-gate ops.x_inline = x_inline; 250*7c478bd9Sstevel@tonic-gate ops.x_getpostn = x_getpostn; 251*7c478bd9Sstevel@tonic-gate ops.x_setpostn = x_setpostn; 252*7c478bd9Sstevel@tonic-gate ops.x_destroy = x_destroy; 253*7c478bd9Sstevel@tonic-gate ops.x_control = x_control; 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate #if defined(_LP64) || defined(_KERNEL) 256*7c478bd9Sstevel@tonic-gate ops.x_getint32 = (dummyfunc3)harmless; 257*7c478bd9Sstevel@tonic-gate ops.x_putint32 = x_putint32_t; 258*7c478bd9Sstevel@tonic-gate #endif 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate /* the other harmless ones */ 261*7c478bd9Sstevel@tonic-gate ops.x_getbytes = (dummyfunc2)harmless; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate return (&ops); 264*7c478bd9Sstevel@tonic-gate } 265