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