Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Encode/decode NLM basic data types
0004  *
0005  * Basic NLMv3 XDR data types are not defined in an IETF standards
0006  * document.  X/Open has a description of these data types that
0007  * is useful.  See Chapter 10 of "Protocols for Interworking:
0008  * XNFS, Version 3W".
0009  *
0010  * Basic NLMv4 XDR data types are defined in Appendix II.1.4 of
0011  * RFC 1813: "NFS Version 3 Protocol Specification".
0012  *
0013  * Author: Chuck Lever <chuck.lever@oracle.com>
0014  *
0015  * Copyright (c) 2020, Oracle and/or its affiliates.
0016  */
0017 
0018 #ifndef _LOCKD_SVCXDR_H_
0019 #define _LOCKD_SVCXDR_H_
0020 
0021 static inline bool
0022 svcxdr_decode_stats(struct xdr_stream *xdr, __be32 *status)
0023 {
0024     __be32 *p;
0025 
0026     p = xdr_inline_decode(xdr, XDR_UNIT);
0027     if (!p)
0028         return false;
0029     *status = *p;
0030 
0031     return true;
0032 }
0033 
0034 static inline bool
0035 svcxdr_encode_stats(struct xdr_stream *xdr, __be32 status)
0036 {
0037     __be32 *p;
0038 
0039     p = xdr_reserve_space(xdr, XDR_UNIT);
0040     if (!p)
0041         return false;
0042     *p = status;
0043 
0044     return true;
0045 }
0046 
0047 static inline bool
0048 svcxdr_decode_string(struct xdr_stream *xdr, char **data, unsigned int *data_len)
0049 {
0050     __be32 *p;
0051     u32 len;
0052 
0053     if (xdr_stream_decode_u32(xdr, &len) < 0)
0054         return false;
0055     if (len > NLM_MAXSTRLEN)
0056         return false;
0057     p = xdr_inline_decode(xdr, len);
0058     if (!p)
0059         return false;
0060     *data_len = len;
0061     *data = (char *)p;
0062 
0063     return true;
0064 }
0065 
0066 /*
0067  * NLM cookies are defined by specification to be a variable-length
0068  * XDR opaque no longer than 1024 bytes. However, this implementation
0069  * limits their length to 32 bytes, and treats zero-length cookies
0070  * specially.
0071  */
0072 static inline bool
0073 svcxdr_decode_cookie(struct xdr_stream *xdr, struct nlm_cookie *cookie)
0074 {
0075     __be32 *p;
0076     u32 len;
0077 
0078     if (xdr_stream_decode_u32(xdr, &len) < 0)
0079         return false;
0080     if (len > NLM_MAXCOOKIELEN)
0081         return false;
0082     if (!len)
0083         goto out_hpux;
0084 
0085     p = xdr_inline_decode(xdr, len);
0086     if (!p)
0087         return false;
0088     cookie->len = len;
0089     memcpy(cookie->data, p, len);
0090 
0091     return true;
0092 
0093     /* apparently HPUX can return empty cookies */
0094 out_hpux:
0095     cookie->len = 4;
0096     memset(cookie->data, 0, 4);
0097     return true;
0098 }
0099 
0100 static inline bool
0101 svcxdr_encode_cookie(struct xdr_stream *xdr, const struct nlm_cookie *cookie)
0102 {
0103     __be32 *p;
0104 
0105     if (xdr_stream_encode_u32(xdr, cookie->len) < 0)
0106         return false;
0107     p = xdr_reserve_space(xdr, cookie->len);
0108     if (!p)
0109         return false;
0110     memcpy(p, cookie->data, cookie->len);
0111 
0112     return true;
0113 }
0114 
0115 static inline bool
0116 svcxdr_decode_owner(struct xdr_stream *xdr, struct xdr_netobj *obj)
0117 {
0118     __be32 *p;
0119     u32 len;
0120 
0121     if (xdr_stream_decode_u32(xdr, &len) < 0)
0122         return false;
0123     if (len > XDR_MAX_NETOBJ)
0124         return false;
0125     p = xdr_inline_decode(xdr, len);
0126     if (!p)
0127         return false;
0128     obj->len = len;
0129     obj->data = (u8 *)p;
0130 
0131     return true;
0132 }
0133 
0134 static inline bool
0135 svcxdr_encode_owner(struct xdr_stream *xdr, const struct xdr_netobj *obj)
0136 {
0137     if (obj->len > XDR_MAX_NETOBJ)
0138         return false;
0139     return xdr_stream_encode_opaque(xdr, obj->data, obj->len) > 0;
0140 }
0141 
0142 #endif /* _LOCKD_SVCXDR_H_ */