1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2024 Oracle and/or its affiliates.
4  *
5  * This header defines XDR data type primitives specified in
6  * Section 4 of RFC 4506, used by RPC programs implemented
7  * in the Linux kernel.
8  */
9 
10 #ifndef _SUNRPC_XDRGEN__BUILTINS_H_
11 #define _SUNRPC_XDRGEN__BUILTINS_H_
12 
13 #include <linux/sunrpc/xdr.h>
14 
15 static inline bool
xdrgen_decode_void(struct xdr_stream * xdr)16 xdrgen_decode_void(struct xdr_stream *xdr)
17 {
18 	return true;
19 }
20 
21 static inline bool
xdrgen_encode_void(struct xdr_stream * xdr)22 xdrgen_encode_void(struct xdr_stream *xdr)
23 {
24 	return true;
25 }
26 
27 static inline bool
xdrgen_decode_bool(struct xdr_stream * xdr,bool * ptr)28 xdrgen_decode_bool(struct xdr_stream *xdr, bool *ptr)
29 {
30 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
31 
32 	if (unlikely(!p))
33 		return false;
34 	*ptr = (*p != xdr_zero);
35 	return true;
36 }
37 
38 static inline bool
xdrgen_encode_bool(struct xdr_stream * xdr,bool val)39 xdrgen_encode_bool(struct xdr_stream *xdr, bool val)
40 {
41 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
42 
43 	if (unlikely(!p))
44 		return false;
45 	*p = val ? xdr_one : xdr_zero;
46 	return true;
47 }
48 
49 static inline bool
xdrgen_decode_int(struct xdr_stream * xdr,s32 * ptr)50 xdrgen_decode_int(struct xdr_stream *xdr, s32 *ptr)
51 {
52 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
53 
54 	if (unlikely(!p))
55 		return false;
56 	*ptr = be32_to_cpup(p);
57 	return true;
58 }
59 
60 static inline bool
xdrgen_encode_int(struct xdr_stream * xdr,s32 val)61 xdrgen_encode_int(struct xdr_stream *xdr, s32 val)
62 {
63 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
64 
65 	if (unlikely(!p))
66 		return false;
67 	*p = cpu_to_be32(val);
68 	return true;
69 }
70 
71 static inline bool
xdrgen_decode_unsigned_int(struct xdr_stream * xdr,u32 * ptr)72 xdrgen_decode_unsigned_int(struct xdr_stream *xdr, u32 *ptr)
73 {
74 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
75 
76 	if (unlikely(!p))
77 		return false;
78 	*ptr = be32_to_cpup(p);
79 	return true;
80 }
81 
82 static inline bool
xdrgen_encode_unsigned_int(struct xdr_stream * xdr,u32 val)83 xdrgen_encode_unsigned_int(struct xdr_stream *xdr, u32 val)
84 {
85 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
86 
87 	if (unlikely(!p))
88 		return false;
89 	*p = cpu_to_be32(val);
90 	return true;
91 }
92 
93 static inline bool
xdrgen_decode_long(struct xdr_stream * xdr,s32 * ptr)94 xdrgen_decode_long(struct xdr_stream *xdr, s32 *ptr)
95 {
96 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
97 
98 	if (unlikely(!p))
99 		return false;
100 	*ptr = be32_to_cpup(p);
101 	return true;
102 }
103 
104 static inline bool
xdrgen_encode_long(struct xdr_stream * xdr,s32 val)105 xdrgen_encode_long(struct xdr_stream *xdr, s32 val)
106 {
107 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
108 
109 	if (unlikely(!p))
110 		return false;
111 	*p = cpu_to_be32(val);
112 	return true;
113 }
114 
115 static inline bool
xdrgen_decode_unsigned_long(struct xdr_stream * xdr,u32 * ptr)116 xdrgen_decode_unsigned_long(struct xdr_stream *xdr, u32 *ptr)
117 {
118 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);
119 
120 	if (unlikely(!p))
121 		return false;
122 	*ptr = be32_to_cpup(p);
123 	return true;
124 }
125 
126 static inline bool
xdrgen_encode_unsigned_long(struct xdr_stream * xdr,u32 val)127 xdrgen_encode_unsigned_long(struct xdr_stream *xdr, u32 val)
128 {
129 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);
130 
131 	if (unlikely(!p))
132 		return false;
133 	*p = cpu_to_be32(val);
134 	return true;
135 }
136 
137 static inline bool
xdrgen_decode_hyper(struct xdr_stream * xdr,s64 * ptr)138 xdrgen_decode_hyper(struct xdr_stream *xdr, s64 *ptr)
139 {
140 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT * 2);
141 
142 	if (unlikely(!p))
143 		return false;
144 	*ptr = get_unaligned_be64(p);
145 	return true;
146 }
147 
148 static inline bool
xdrgen_encode_hyper(struct xdr_stream * xdr,s64 val)149 xdrgen_encode_hyper(struct xdr_stream *xdr, s64 val)
150 {
151 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT * 2);
152 
153 	if (unlikely(!p))
154 		return false;
155 	put_unaligned_be64(val, p);
156 	return true;
157 }
158 
159 static inline bool
xdrgen_decode_unsigned_hyper(struct xdr_stream * xdr,u64 * ptr)160 xdrgen_decode_unsigned_hyper(struct xdr_stream *xdr, u64 *ptr)
161 {
162 	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT * 2);
163 
164 	if (unlikely(!p))
165 		return false;
166 	*ptr = get_unaligned_be64(p);
167 	return true;
168 }
169 
170 static inline bool
xdrgen_encode_unsigned_hyper(struct xdr_stream * xdr,u64 val)171 xdrgen_encode_unsigned_hyper(struct xdr_stream *xdr, u64 val)
172 {
173 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT * 2);
174 
175 	if (unlikely(!p))
176 		return false;
177 	put_unaligned_be64(val, p);
178 	return true;
179 }
180 
181 static inline bool
xdrgen_decode_string(struct xdr_stream * xdr,string * ptr,u32 maxlen)182 xdrgen_decode_string(struct xdr_stream *xdr, string *ptr, u32 maxlen)
183 {
184 	__be32 *p;
185 	u32 len;
186 
187 	if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
188 		return false;
189 	if (unlikely(maxlen && len > maxlen))
190 		return false;
191 	if (len != 0) {
192 		p = xdr_inline_decode(xdr, len);
193 		if (unlikely(!p))
194 			return false;
195 		ptr->data = (unsigned char *)p;
196 	}
197 	ptr->len = len;
198 	return true;
199 }
200 
201 static inline bool
xdrgen_encode_string(struct xdr_stream * xdr,string val,u32 maxlen)202 xdrgen_encode_string(struct xdr_stream *xdr, string val, u32 maxlen)
203 {
204 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT + xdr_align_size(val.len));
205 
206 	if (unlikely(!p))
207 		return false;
208 	xdr_encode_opaque(p, val.data, val.len);
209 	return true;
210 }
211 
212 static inline bool
xdrgen_decode_opaque(struct xdr_stream * xdr,opaque * ptr,u32 maxlen)213 xdrgen_decode_opaque(struct xdr_stream *xdr, opaque *ptr, u32 maxlen)
214 {
215 	__be32 *p;
216 	u32 len;
217 
218 	if (unlikely(xdr_stream_decode_u32(xdr, &len) < 0))
219 		return false;
220 	if (unlikely(maxlen && len > maxlen))
221 		return false;
222 	if (len != 0) {
223 		p = xdr_inline_decode(xdr, len);
224 		if (unlikely(!p))
225 			return false;
226 		ptr->data = (u8 *)p;
227 	}
228 	ptr->len = len;
229 	return true;
230 }
231 
232 static inline bool
xdrgen_encode_opaque(struct xdr_stream * xdr,opaque val)233 xdrgen_encode_opaque(struct xdr_stream *xdr, opaque val)
234 {
235 	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT + xdr_align_size(val.len));
236 
237 	if (unlikely(!p))
238 		return false;
239 	xdr_encode_opaque(p, val.data, val.len);
240 	return true;
241 }
242 
243 #endif /* _SUNRPC_XDRGEN__BUILTINS_H_ */
244