]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / cddl / contrib / opensolaris / common / nvpair / nvpair.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25
26 #include <sys/debug.h>
27 #include <sys/nvpair.h>
28 #include <sys/nvpair_impl.h>
29 #include <rpc/types.h>
30 #include <rpc/xdr.h>
31
32 #if defined(_KERNEL) && !defined(_BOOT)
33 #include <sys/varargs.h>
34 #include <sys/sunddi.h>
35 #else
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <strings.h>
40 #endif
41
42 #ifndef offsetof
43 #define offsetof(s, m)          ((size_t)(&(((s *)0)->m)))
44 #endif
45 #define skip_whitespace(p)      while ((*(p) == ' ') || (*(p) == '\t')) p++
46
47 /*
48  * nvpair.c - Provides kernel & userland interfaces for manipulating
49  *      name-value pairs.
50  *
51  * Overview Diagram
52  *
53  *  +--------------+
54  *  |  nvlist_t    |
55  *  |--------------|
56  *  | nvl_version  |
57  *  | nvl_nvflag   |
58  *  | nvl_priv    -+-+
59  *  | nvl_flag     | |
60  *  | nvl_pad      | |
61  *  +--------------+ |
62  *                   V
63  *      +--------------+      last i_nvp in list
64  *      | nvpriv_t     |  +--------------------->
65  *      |--------------|  |
66  *   +--+- nvp_list    |  |   +------------+
67  *   |  |  nvp_last   -+--+   + nv_alloc_t |
68  *   |  |  nvp_curr    |      |------------|
69  *   |  |  nvp_nva    -+----> | nva_ops    |
70  *   |  |  nvp_stat    |      | nva_arg    |
71  *   |  +--------------+      +------------+
72  *   |
73  *   +-------+
74  *           V
75  *   +---------------------+      +-------------------+
76  *   |  i_nvp_t            |  +-->|  i_nvp_t          |  +-->
77  *   |---------------------|  |   |-------------------|  |
78  *   | nvi_next           -+--+   | nvi_next         -+--+
79  *   | nvi_prev (NULL)     | <----+ nvi_prev          |
80  *   | . . . . . . . . . . |      | . . . . . . . . . |
81  *   | nvp (nvpair_t)      |      | nvp (nvpair_t)    |
82  *   |  - nvp_size         |      |  - nvp_size       |
83  *   |  - nvp_name_sz      |      |  - nvp_name_sz    |
84  *   |  - nvp_value_elem   |      |  - nvp_value_elem |
85  *   |  - nvp_type         |      |  - nvp_type       |
86  *   |  - data ...         |      |  - data ...       |
87  *   +---------------------+      +-------------------+
88  *
89  *
90  *
91  *   +---------------------+              +---------------------+
92  *   |  i_nvp_t            |  +-->    +-->|  i_nvp_t (last)     |
93  *   |---------------------|  |       |   |---------------------|
94  *   |  nvi_next          -+--+ ... --+   | nvi_next (NULL)     |
95  * <-+- nvi_prev           |<-- ...  <----+ nvi_prev            |
96  *   | . . . . . . . . .   |              | . . . . . . . . .   |
97  *   | nvp (nvpair_t)      |              | nvp (nvpair_t)      |
98  *   |  - nvp_size         |              |  - nvp_size         |
99  *   |  - nvp_name_sz      |              |  - nvp_name_sz      |
100  *   |  - nvp_value_elem   |              |  - nvp_value_elem   |
101  *   |  - DATA_TYPE_NVLIST |              |  - nvp_type         |
102  *   |  - data (embedded)  |              |  - data ...         |
103  *   |    nvlist name      |              +---------------------+
104  *   |  +--------------+   |
105  *   |  |  nvlist_t    |   |
106  *   |  |--------------|   |
107  *   |  | nvl_version  |   |
108  *   |  | nvl_nvflag   |   |
109  *   |  | nvl_priv   --+---+---->
110  *   |  | nvl_flag     |   |
111  *   |  | nvl_pad      |   |
112  *   |  +--------------+   |
113  *   +---------------------+
114  *
115  *
116  * N.B. nvpair_t may be aligned on 4 byte boundary, so +4 will
117  * allow value to be aligned on 8 byte boundary
118  *
119  * name_len is the length of the name string including the null terminator
120  * so it must be >= 1
121  */
122 #define NVP_SIZE_CALC(name_len, data_len) \
123         (NV_ALIGN((sizeof (nvpair_t)) + name_len) + NV_ALIGN(data_len))
124
125 static int i_get_value_size(data_type_t type, const void *data, uint_t nelem);
126 static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type,
127     uint_t nelem, const void *data);
128
129 #define NV_STAT_EMBEDDED        0x1
130 #define EMBEDDED_NVL(nvp)       ((nvlist_t *)(void *)NVP_VALUE(nvp))
131 #define EMBEDDED_NVL_ARRAY(nvp) ((nvlist_t **)(void *)NVP_VALUE(nvp))
132
133 #define NVP_VALOFF(nvp) (NV_ALIGN(sizeof (nvpair_t) + (nvp)->nvp_name_sz))
134 #define NVPAIR2I_NVP(nvp) \
135         ((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_nvp)))
136
137
138 int
139 nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
140 {
141         va_list valist;
142         int err = 0;
143
144         nva->nva_ops = nvo;
145         nva->nva_arg = NULL;
146
147         va_start(valist, nvo);
148         if (nva->nva_ops->nv_ao_init != NULL)
149                 err = nva->nva_ops->nv_ao_init(nva, valist);
150         va_end(valist);
151
152         return (err);
153 }
154
155 void
156 nv_alloc_reset(nv_alloc_t *nva)
157 {
158         if (nva->nva_ops->nv_ao_reset != NULL)
159                 nva->nva_ops->nv_ao_reset(nva);
160 }
161
162 void
163 nv_alloc_fini(nv_alloc_t *nva)
164 {
165         if (nva->nva_ops->nv_ao_fini != NULL)
166                 nva->nva_ops->nv_ao_fini(nva);
167 }
168
169 nv_alloc_t *
170 nvlist_lookup_nv_alloc(nvlist_t *nvl)
171 {
172         nvpriv_t *priv;
173
174         if (nvl == NULL ||
175             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
176                 return (NULL);
177
178         return (priv->nvp_nva);
179 }
180
181 static void *
182 nv_mem_zalloc(nvpriv_t *nvp, size_t size)
183 {
184         nv_alloc_t *nva = nvp->nvp_nva;
185         void *buf;
186
187         if ((buf = nva->nva_ops->nv_ao_alloc(nva, size)) != NULL)
188                 bzero(buf, size);
189
190         return (buf);
191 }
192
193 static void
194 nv_mem_free(nvpriv_t *nvp, void *buf, size_t size)
195 {
196         nv_alloc_t *nva = nvp->nvp_nva;
197
198         nva->nva_ops->nv_ao_free(nva, buf, size);
199 }
200
201 static void
202 nv_priv_init(nvpriv_t *priv, nv_alloc_t *nva, uint32_t stat)
203 {
204         bzero(priv, sizeof (nvpriv_t));
205
206         priv->nvp_nva = nva;
207         priv->nvp_stat = stat;
208 }
209
210 static nvpriv_t *
211 nv_priv_alloc(nv_alloc_t *nva)
212 {
213         nvpriv_t *priv;
214
215         /*
216          * nv_mem_alloc() cannot called here because it needs the priv
217          * argument.
218          */
219         if ((priv = nva->nva_ops->nv_ao_alloc(nva, sizeof (nvpriv_t))) == NULL)
220                 return (NULL);
221
222         nv_priv_init(priv, nva, 0);
223
224         return (priv);
225 }
226
227 /*
228  * Embedded lists need their own nvpriv_t's.  We create a new
229  * nvpriv_t using the parameters and allocator from the parent
230  * list's nvpriv_t.
231  */
232 static nvpriv_t *
233 nv_priv_alloc_embedded(nvpriv_t *priv)
234 {
235         nvpriv_t *emb_priv;
236
237         if ((emb_priv = nv_mem_zalloc(priv, sizeof (nvpriv_t))) == NULL)
238                 return (NULL);
239
240         nv_priv_init(emb_priv, priv->nvp_nva, NV_STAT_EMBEDDED);
241
242         return (emb_priv);
243 }
244
245 static void
246 nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv)
247 {
248         nvl->nvl_version = NV_VERSION;
249         nvl->nvl_nvflag = nvflag & (NV_UNIQUE_NAME|NV_UNIQUE_NAME_TYPE);
250         nvl->nvl_priv = (uint64_t)(uintptr_t)priv;
251         nvl->nvl_flag = 0;
252         nvl->nvl_pad = 0;
253 }
254
255 uint_t
256 nvlist_nvflag(nvlist_t *nvl)
257 {
258         return (nvl->nvl_nvflag);
259 }
260
261 /*
262  * nvlist_alloc - Allocate nvlist.
263  */
264 /*ARGSUSED1*/
265 int
266 nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag)
267 {
268 #if defined(_KERNEL) && !defined(_BOOT)
269         return (nvlist_xalloc(nvlp, nvflag,
270             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
271 #else
272         return (nvlist_xalloc(nvlp, nvflag, nv_alloc_nosleep));
273 #endif
274 }
275
276 int
277 nvlist_xalloc(nvlist_t **nvlp, uint_t nvflag, nv_alloc_t *nva)
278 {
279         nvpriv_t *priv;
280
281         if (nvlp == NULL || nva == NULL)
282                 return (EINVAL);
283
284         if ((priv = nv_priv_alloc(nva)) == NULL)
285                 return (ENOMEM);
286
287         if ((*nvlp = nv_mem_zalloc(priv,
288             NV_ALIGN(sizeof (nvlist_t)))) == NULL) {
289                 nv_mem_free(priv, priv, sizeof (nvpriv_t));
290                 return (ENOMEM);
291         }
292
293         nvlist_init(*nvlp, nvflag, priv);
294
295         return (0);
296 }
297
298 /*
299  * nvp_buf_alloc - Allocate i_nvp_t for storing a new nv pair.
300  */
301 static nvpair_t *
302 nvp_buf_alloc(nvlist_t *nvl, size_t len)
303 {
304         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
305         i_nvp_t *buf;
306         nvpair_t *nvp;
307         size_t nvsize;
308
309         /*
310          * Allocate the buffer
311          */
312         nvsize = len + offsetof(i_nvp_t, nvi_nvp);
313
314         if ((buf = nv_mem_zalloc(priv, nvsize)) == NULL)
315                 return (NULL);
316
317         nvp = &buf->nvi_nvp;
318         nvp->nvp_size = len;
319
320         return (nvp);
321 }
322
323 /*
324  * nvp_buf_free - de-Allocate an i_nvp_t.
325  */
326 static void
327 nvp_buf_free(nvlist_t *nvl, nvpair_t *nvp)
328 {
329         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
330         size_t nvsize = nvp->nvp_size + offsetof(i_nvp_t, nvi_nvp);
331
332         nv_mem_free(priv, NVPAIR2I_NVP(nvp), nvsize);
333 }
334
335 /*
336  * nvp_buf_link - link a new nv pair into the nvlist.
337  */
338 static void
339 nvp_buf_link(nvlist_t *nvl, nvpair_t *nvp)
340 {
341         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
342         i_nvp_t *curr = NVPAIR2I_NVP(nvp);
343
344         /* Put element at end of nvlist */
345         if (priv->nvp_list == NULL) {
346                 priv->nvp_list = priv->nvp_last = curr;
347         } else {
348                 curr->nvi_prev = priv->nvp_last;
349                 priv->nvp_last->nvi_next = curr;
350                 priv->nvp_last = curr;
351         }
352 }
353
354 /*
355  * nvp_buf_unlink - unlink an removed nvpair out of the nvlist.
356  */
357 static void
358 nvp_buf_unlink(nvlist_t *nvl, nvpair_t *nvp)
359 {
360         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
361         i_nvp_t *curr = NVPAIR2I_NVP(nvp);
362
363         /*
364          * protect nvlist_next_nvpair() against walking on freed memory.
365          */
366         if (priv->nvp_curr == curr)
367                 priv->nvp_curr = curr->nvi_next;
368
369         if (curr == priv->nvp_list)
370                 priv->nvp_list = curr->nvi_next;
371         else
372                 curr->nvi_prev->nvi_next = curr->nvi_next;
373
374         if (curr == priv->nvp_last)
375                 priv->nvp_last = curr->nvi_prev;
376         else
377                 curr->nvi_next->nvi_prev = curr->nvi_prev;
378 }
379
380 /*
381  * take a nvpair type and number of elements and make sure the are valid
382  */
383 static int
384 i_validate_type_nelem(data_type_t type, uint_t nelem)
385 {
386         switch (type) {
387         case DATA_TYPE_BOOLEAN:
388                 if (nelem != 0)
389                         return (EINVAL);
390                 break;
391         case DATA_TYPE_BOOLEAN_VALUE:
392         case DATA_TYPE_BYTE:
393         case DATA_TYPE_INT8:
394         case DATA_TYPE_UINT8:
395         case DATA_TYPE_INT16:
396         case DATA_TYPE_UINT16:
397         case DATA_TYPE_INT32:
398         case DATA_TYPE_UINT32:
399         case DATA_TYPE_INT64:
400         case DATA_TYPE_UINT64:
401         case DATA_TYPE_STRING:
402         case DATA_TYPE_HRTIME:
403         case DATA_TYPE_NVLIST:
404 #if !defined(_KERNEL)
405         case DATA_TYPE_DOUBLE:
406 #endif
407                 if (nelem != 1)
408                         return (EINVAL);
409                 break;
410         case DATA_TYPE_BOOLEAN_ARRAY:
411         case DATA_TYPE_BYTE_ARRAY:
412         case DATA_TYPE_INT8_ARRAY:
413         case DATA_TYPE_UINT8_ARRAY:
414         case DATA_TYPE_INT16_ARRAY:
415         case DATA_TYPE_UINT16_ARRAY:
416         case DATA_TYPE_INT32_ARRAY:
417         case DATA_TYPE_UINT32_ARRAY:
418         case DATA_TYPE_INT64_ARRAY:
419         case DATA_TYPE_UINT64_ARRAY:
420         case DATA_TYPE_STRING_ARRAY:
421         case DATA_TYPE_NVLIST_ARRAY:
422                 /* we allow arrays with 0 elements */
423                 break;
424         default:
425                 return (EINVAL);
426         }
427         return (0);
428 }
429
430 /*
431  * Verify nvp_name_sz and check the name string length.
432  */
433 static int
434 i_validate_nvpair_name(nvpair_t *nvp)
435 {
436         if ((nvp->nvp_name_sz <= 0) ||
437             (nvp->nvp_size < NVP_SIZE_CALC(nvp->nvp_name_sz, 0)))
438                 return (EFAULT);
439
440         /* verify the name string, make sure its terminated */
441         if (NVP_NAME(nvp)[nvp->nvp_name_sz - 1] != '\0')
442                 return (EFAULT);
443
444         return (strlen(NVP_NAME(nvp)) == nvp->nvp_name_sz - 1 ? 0 : EFAULT);
445 }
446
447 static int
448 i_validate_nvpair_value(data_type_t type, uint_t nelem, const void *data)
449 {
450         switch (type) {
451         case DATA_TYPE_BOOLEAN_VALUE:
452                 if (*(boolean_t *)data != B_TRUE &&
453                     *(boolean_t *)data != B_FALSE)
454                         return (EINVAL);
455                 break;
456         case DATA_TYPE_BOOLEAN_ARRAY: {
457                 int i;
458
459                 for (i = 0; i < nelem; i++)
460                         if (((boolean_t *)data)[i] != B_TRUE &&
461                             ((boolean_t *)data)[i] != B_FALSE)
462                                 return (EINVAL);
463                 break;
464         }
465         default:
466                 break;
467         }
468
469         return (0);
470 }
471
472 /*
473  * This function takes a pointer to what should be a nvpair and it's size
474  * and then verifies that all the nvpair fields make sense and can be
475  * trusted.  This function is used when decoding packed nvpairs.
476  */
477 static int
478 i_validate_nvpair(nvpair_t *nvp)
479 {
480         data_type_t type = NVP_TYPE(nvp);
481         int size1, size2;
482
483         /* verify nvp_name_sz, check the name string length */
484         if (i_validate_nvpair_name(nvp) != 0)
485                 return (EFAULT);
486
487         if (i_validate_nvpair_value(type, NVP_NELEM(nvp), NVP_VALUE(nvp)) != 0)
488                 return (EFAULT);
489
490         /*
491          * verify nvp_type, nvp_value_elem, and also possibly
492          * verify string values and get the value size.
493          */
494         size2 = i_get_value_size(type, NVP_VALUE(nvp), NVP_NELEM(nvp));
495         size1 = nvp->nvp_size - NVP_VALOFF(nvp);
496         if (size2 < 0 || size1 != NV_ALIGN(size2))
497                 return (EFAULT);
498
499         return (0);
500 }
501
502 static int
503 nvlist_copy_pairs(nvlist_t *snvl, nvlist_t *dnvl)
504 {
505         nvpriv_t *priv;
506         i_nvp_t *curr;
507
508         if ((priv = (nvpriv_t *)(uintptr_t)snvl->nvl_priv) == NULL)
509                 return (EINVAL);
510
511         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
512                 nvpair_t *nvp = &curr->nvi_nvp;
513                 int err;
514
515                 if ((err = nvlist_add_common(dnvl, NVP_NAME(nvp), NVP_TYPE(nvp),
516                     NVP_NELEM(nvp), NVP_VALUE(nvp))) != 0)
517                         return (err);
518         }
519
520         return (0);
521 }
522
523 /*
524  * Frees all memory allocated for an nvpair (like embedded lists) with
525  * the exception of the nvpair buffer itself.
526  */
527 static void
528 nvpair_free(nvpair_t *nvp)
529 {
530         switch (NVP_TYPE(nvp)) {
531         case DATA_TYPE_NVLIST:
532                 nvlist_free(EMBEDDED_NVL(nvp));
533                 break;
534         case DATA_TYPE_NVLIST_ARRAY: {
535                 nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
536                 int i;
537
538                 for (i = 0; i < NVP_NELEM(nvp); i++)
539                         if (nvlp[i] != NULL)
540                                 nvlist_free(nvlp[i]);
541                 break;
542         }
543         default:
544                 break;
545         }
546 }
547
548 /*
549  * nvlist_free - free an unpacked nvlist
550  */
551 void
552 nvlist_free(nvlist_t *nvl)
553 {
554         nvpriv_t *priv;
555         i_nvp_t *curr;
556
557         if (nvl == NULL ||
558             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
559                 return;
560
561         /*
562          * Unpacked nvlist are linked through i_nvp_t
563          */
564         curr = priv->nvp_list;
565         while (curr != NULL) {
566                 nvpair_t *nvp = &curr->nvi_nvp;
567                 curr = curr->nvi_next;
568
569                 nvpair_free(nvp);
570                 nvp_buf_free(nvl, nvp);
571         }
572
573         if (!(priv->nvp_stat & NV_STAT_EMBEDDED))
574                 nv_mem_free(priv, nvl, NV_ALIGN(sizeof (nvlist_t)));
575         else
576                 nvl->nvl_priv = 0;
577
578         nv_mem_free(priv, priv, sizeof (nvpriv_t));
579 }
580
581 static int
582 nvlist_contains_nvp(nvlist_t *nvl, nvpair_t *nvp)
583 {
584         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
585         i_nvp_t *curr;
586
587         if (nvp == NULL)
588                 return (0);
589
590         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
591                 if (&curr->nvi_nvp == nvp)
592                         return (1);
593
594         return (0);
595 }
596
597 /*
598  * Make a copy of nvlist
599  */
600 /*ARGSUSED1*/
601 int
602 nvlist_dup(nvlist_t *nvl, nvlist_t **nvlp, int kmflag)
603 {
604 #if defined(_KERNEL) && !defined(_BOOT)
605         return (nvlist_xdup(nvl, nvlp,
606             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
607 #else
608         return (nvlist_xdup(nvl, nvlp, nv_alloc_nosleep));
609 #endif
610 }
611
612 int
613 nvlist_xdup(nvlist_t *nvl, nvlist_t **nvlp, nv_alloc_t *nva)
614 {
615         int err;
616         nvlist_t *ret;
617
618         if (nvl == NULL || nvlp == NULL)
619                 return (EINVAL);
620
621         if ((err = nvlist_xalloc(&ret, nvl->nvl_nvflag, nva)) != 0)
622                 return (err);
623
624         if ((err = nvlist_copy_pairs(nvl, ret)) != 0)
625                 nvlist_free(ret);
626         else
627                 *nvlp = ret;
628
629         return (err);
630 }
631
632 /*
633  * Remove all with matching name
634  */
635 int
636 nvlist_remove_all(nvlist_t *nvl, const char *name)
637 {
638         nvpriv_t *priv;
639         i_nvp_t *curr;
640         int error = ENOENT;
641
642         if (nvl == NULL || name == NULL ||
643             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
644                 return (EINVAL);
645
646         curr = priv->nvp_list;
647         while (curr != NULL) {
648                 nvpair_t *nvp = &curr->nvi_nvp;
649
650                 curr = curr->nvi_next;
651                 if (strcmp(name, NVP_NAME(nvp)) != 0)
652                         continue;
653
654                 nvp_buf_unlink(nvl, nvp);
655                 nvpair_free(nvp);
656                 nvp_buf_free(nvl, nvp);
657
658                 error = 0;
659         }
660
661         return (error);
662 }
663
664 /*
665  * Remove first one with matching name and type
666  */
667 int
668 nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type)
669 {
670         nvpriv_t *priv;
671         i_nvp_t *curr;
672
673         if (nvl == NULL || name == NULL ||
674             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
675                 return (EINVAL);
676
677         curr = priv->nvp_list;
678         while (curr != NULL) {
679                 nvpair_t *nvp = &curr->nvi_nvp;
680
681                 if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type) {
682                         nvp_buf_unlink(nvl, nvp);
683                         nvpair_free(nvp);
684                         nvp_buf_free(nvl, nvp);
685
686                         return (0);
687                 }
688                 curr = curr->nvi_next;
689         }
690
691         return (ENOENT);
692 }
693
694 int
695 nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
696 {
697         if (nvl == NULL || nvp == NULL)
698                 return (EINVAL);
699
700         nvp_buf_unlink(nvl, nvp);
701         nvpair_free(nvp);
702         nvp_buf_free(nvl, nvp);
703         return (0);
704 }
705
706 /*
707  * This function calculates the size of an nvpair value.
708  *
709  * The data argument controls the behavior in case of the data types
710  *      DATA_TYPE_STRING        and
711  *      DATA_TYPE_STRING_ARRAY
712  * Is data == NULL then the size of the string(s) is excluded.
713  */
714 static int
715 i_get_value_size(data_type_t type, const void *data, uint_t nelem)
716 {
717         uint64_t value_sz;
718
719         if (i_validate_type_nelem(type, nelem) != 0)
720                 return (-1);
721
722         /* Calculate required size for holding value */
723         switch (type) {
724         case DATA_TYPE_BOOLEAN:
725                 value_sz = 0;
726                 break;
727         case DATA_TYPE_BOOLEAN_VALUE:
728                 value_sz = sizeof (boolean_t);
729                 break;
730         case DATA_TYPE_BYTE:
731                 value_sz = sizeof (uchar_t);
732                 break;
733         case DATA_TYPE_INT8:
734                 value_sz = sizeof (int8_t);
735                 break;
736         case DATA_TYPE_UINT8:
737                 value_sz = sizeof (uint8_t);
738                 break;
739         case DATA_TYPE_INT16:
740                 value_sz = sizeof (int16_t);
741                 break;
742         case DATA_TYPE_UINT16:
743                 value_sz = sizeof (uint16_t);
744                 break;
745         case DATA_TYPE_INT32:
746                 value_sz = sizeof (int32_t);
747                 break;
748         case DATA_TYPE_UINT32:
749                 value_sz = sizeof (uint32_t);
750                 break;
751         case DATA_TYPE_INT64:
752                 value_sz = sizeof (int64_t);
753                 break;
754         case DATA_TYPE_UINT64:
755                 value_sz = sizeof (uint64_t);
756                 break;
757 #if !defined(_KERNEL)
758         case DATA_TYPE_DOUBLE:
759                 value_sz = sizeof (double);
760                 break;
761 #endif
762         case DATA_TYPE_STRING:
763                 if (data == NULL)
764                         value_sz = 0;
765                 else
766                         value_sz = strlen(data) + 1;
767                 break;
768         case DATA_TYPE_BOOLEAN_ARRAY:
769                 value_sz = (uint64_t)nelem * sizeof (boolean_t);
770                 break;
771         case DATA_TYPE_BYTE_ARRAY:
772                 value_sz = (uint64_t)nelem * sizeof (uchar_t);
773                 break;
774         case DATA_TYPE_INT8_ARRAY:
775                 value_sz = (uint64_t)nelem * sizeof (int8_t);
776                 break;
777         case DATA_TYPE_UINT8_ARRAY:
778                 value_sz = (uint64_t)nelem * sizeof (uint8_t);
779                 break;
780         case DATA_TYPE_INT16_ARRAY:
781                 value_sz = (uint64_t)nelem * sizeof (int16_t);
782                 break;
783         case DATA_TYPE_UINT16_ARRAY:
784                 value_sz = (uint64_t)nelem * sizeof (uint16_t);
785                 break;
786         case DATA_TYPE_INT32_ARRAY:
787                 value_sz = (uint64_t)nelem * sizeof (int32_t);
788                 break;
789         case DATA_TYPE_UINT32_ARRAY:
790                 value_sz = (uint64_t)nelem * sizeof (uint32_t);
791                 break;
792         case DATA_TYPE_INT64_ARRAY:
793                 value_sz = (uint64_t)nelem * sizeof (int64_t);
794                 break;
795         case DATA_TYPE_UINT64_ARRAY:
796                 value_sz = (uint64_t)nelem * sizeof (uint64_t);
797                 break;
798         case DATA_TYPE_STRING_ARRAY:
799                 value_sz = (uint64_t)nelem * sizeof (uint64_t);
800
801                 if (data != NULL) {
802                         char *const *strs = data;
803                         uint_t i;
804
805                         /* no alignment requirement for strings */
806                         for (i = 0; i < nelem; i++) {
807                                 if (strs[i] == NULL)
808                                         return (-1);
809                                 value_sz += strlen(strs[i]) + 1;
810                         }
811                 }
812                 break;
813         case DATA_TYPE_HRTIME:
814                 value_sz = sizeof (hrtime_t);
815                 break;
816         case DATA_TYPE_NVLIST:
817                 value_sz = NV_ALIGN(sizeof (nvlist_t));
818                 break;
819         case DATA_TYPE_NVLIST_ARRAY:
820                 value_sz = (uint64_t)nelem * sizeof (uint64_t) +
821                     (uint64_t)nelem * NV_ALIGN(sizeof (nvlist_t));
822                 break;
823         default:
824                 return (-1);
825         }
826
827         return (value_sz > INT32_MAX ? -1 : (int)value_sz);
828 }
829
830 static int
831 nvlist_copy_embedded(nvlist_t *nvl, nvlist_t *onvl, nvlist_t *emb_nvl)
832 {
833         nvpriv_t *priv;
834         int err;
835
836         if ((priv = nv_priv_alloc_embedded((nvpriv_t *)(uintptr_t)
837             nvl->nvl_priv)) == NULL)
838                 return (ENOMEM);
839
840         nvlist_init(emb_nvl, onvl->nvl_nvflag, priv);
841
842         if ((err = nvlist_copy_pairs(onvl, emb_nvl)) != 0) {
843                 nvlist_free(emb_nvl);
844                 emb_nvl->nvl_priv = 0;
845         }
846
847         return (err);
848 }
849
850 /*
851  * nvlist_add_common - Add new <name,value> pair to nvlist
852  */
853 static int
854 nvlist_add_common(nvlist_t *nvl, const char *name,
855     data_type_t type, uint_t nelem, const void *data)
856 {
857         nvpair_t *nvp;
858         uint_t i;
859
860         int nvp_sz, name_sz, value_sz;
861         int err = 0;
862
863         if (name == NULL || nvl == NULL || nvl->nvl_priv == 0)
864                 return (EINVAL);
865
866         if (nelem != 0 && data == NULL)
867                 return (EINVAL);
868
869         /*
870          * Verify type and nelem and get the value size.
871          * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
872          * is the size of the string(s) included.
873          */
874         if ((value_sz = i_get_value_size(type, data, nelem)) < 0)
875                 return (EINVAL);
876
877         if (i_validate_nvpair_value(type, nelem, data) != 0)
878                 return (EINVAL);
879
880         /*
881          * If we're adding an nvlist or nvlist array, ensure that we are not
882          * adding the input nvlist to itself, which would cause recursion,
883          * and ensure that no NULL nvlist pointers are present.
884          */
885         switch (type) {
886         case DATA_TYPE_NVLIST:
887                 if (data == nvl || data == NULL)
888                         return (EINVAL);
889                 break;
890         case DATA_TYPE_NVLIST_ARRAY: {
891                 nvlist_t **onvlp = (nvlist_t **)data;
892                 for (i = 0; i < nelem; i++) {
893                         if (onvlp[i] == nvl || onvlp[i] == NULL)
894                                 return (EINVAL);
895                 }
896                 break;
897         }
898         default:
899                 break;
900         }
901
902         /* calculate sizes of the nvpair elements and the nvpair itself */
903         name_sz = strlen(name) + 1;
904
905         nvp_sz = NVP_SIZE_CALC(name_sz, value_sz);
906
907         if ((nvp = nvp_buf_alloc(nvl, nvp_sz)) == NULL)
908                 return (ENOMEM);
909
910         ASSERT(nvp->nvp_size == nvp_sz);
911         nvp->nvp_name_sz = name_sz;
912         nvp->nvp_value_elem = nelem;
913         nvp->nvp_type = type;
914         bcopy(name, NVP_NAME(nvp), name_sz);
915
916         switch (type) {
917         case DATA_TYPE_BOOLEAN:
918                 break;
919         case DATA_TYPE_STRING_ARRAY: {
920                 char *const *strs = data;
921                 char *buf = NVP_VALUE(nvp);
922                 char **cstrs = (void *)buf;
923
924                 /* skip pre-allocated space for pointer array */
925                 buf += nelem * sizeof (uint64_t);
926                 for (i = 0; i < nelem; i++) {
927                         int slen = strlen(strs[i]) + 1;
928                         bcopy(strs[i], buf, slen);
929                         cstrs[i] = buf;
930                         buf += slen;
931                 }
932                 break;
933         }
934         case DATA_TYPE_NVLIST: {
935                 nvlist_t *nnvl = EMBEDDED_NVL(nvp);
936                 nvlist_t *onvl = (nvlist_t *)data;
937
938                 if ((err = nvlist_copy_embedded(nvl, onvl, nnvl)) != 0) {
939                         nvp_buf_free(nvl, nvp);
940                         return (err);
941                 }
942                 break;
943         }
944         case DATA_TYPE_NVLIST_ARRAY: {
945                 nvlist_t **onvlp = (nvlist_t **)data;
946                 nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
947                 nvlist_t *embedded = (nvlist_t *)
948                     ((uintptr_t)nvlp + nelem * sizeof (uint64_t));
949
950                 for (i = 0; i < nelem; i++) {
951                         if ((err = nvlist_copy_embedded(nvl,
952                             onvlp[i], embedded)) != 0) {
953                                 /*
954                                  * Free any successfully created lists
955                                  */
956                                 nvpair_free(nvp);
957                                 nvp_buf_free(nvl, nvp);
958                                 return (err);
959                         }
960
961                         nvlp[i] = embedded++;
962                 }
963                 break;
964         }
965         default:
966                 bcopy(data, NVP_VALUE(nvp), value_sz);
967         }
968
969         /* if unique name, remove before add */
970         if (nvl->nvl_nvflag & NV_UNIQUE_NAME)
971                 (void) nvlist_remove_all(nvl, name);
972         else if (nvl->nvl_nvflag & NV_UNIQUE_NAME_TYPE)
973                 (void) nvlist_remove(nvl, name, type);
974
975         nvp_buf_link(nvl, nvp);
976
977         return (0);
978 }
979
980 int
981 nvlist_add_boolean(nvlist_t *nvl, const char *name)
982 {
983         return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN, 0, NULL));
984 }
985
986 int
987 nvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t val)
988 {
989         return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_VALUE, 1, &val));
990 }
991
992 int
993 nvlist_add_byte(nvlist_t *nvl, const char *name, uchar_t val)
994 {
995         return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE, 1, &val));
996 }
997
998 int
999 nvlist_add_int8(nvlist_t *nvl, const char *name, int8_t val)
1000 {
1001         return (nvlist_add_common(nvl, name, DATA_TYPE_INT8, 1, &val));
1002 }
1003
1004 int
1005 nvlist_add_uint8(nvlist_t *nvl, const char *name, uint8_t val)
1006 {
1007         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8, 1, &val));
1008 }
1009
1010 int
1011 nvlist_add_int16(nvlist_t *nvl, const char *name, int16_t val)
1012 {
1013         return (nvlist_add_common(nvl, name, DATA_TYPE_INT16, 1, &val));
1014 }
1015
1016 int
1017 nvlist_add_uint16(nvlist_t *nvl, const char *name, uint16_t val)
1018 {
1019         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16, 1, &val));
1020 }
1021
1022 int
1023 nvlist_add_int32(nvlist_t *nvl, const char *name, int32_t val)
1024 {
1025         return (nvlist_add_common(nvl, name, DATA_TYPE_INT32, 1, &val));
1026 }
1027
1028 int
1029 nvlist_add_uint32(nvlist_t *nvl, const char *name, uint32_t val)
1030 {
1031         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32, 1, &val));
1032 }
1033
1034 int
1035 nvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val)
1036 {
1037         return (nvlist_add_common(nvl, name, DATA_TYPE_INT64, 1, &val));
1038 }
1039
1040 int
1041 nvlist_add_uint64(nvlist_t *nvl, const char *name, uint64_t val)
1042 {
1043         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val));
1044 }
1045
1046 #if !defined(_KERNEL)
1047 int
1048 nvlist_add_double(nvlist_t *nvl, const char *name, double val)
1049 {
1050         return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val));
1051 }
1052 #endif
1053
1054 int
1055 nvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
1056 {
1057         return (nvlist_add_common(nvl, name, DATA_TYPE_STRING, 1, (void *)val));
1058 }
1059
1060 int
1061 nvlist_add_boolean_array(nvlist_t *nvl, const char *name,
1062     boolean_t *a, uint_t n)
1063 {
1064         return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_ARRAY, n, a));
1065 }
1066
1067 int
1068 nvlist_add_byte_array(nvlist_t *nvl, const char *name, uchar_t *a, uint_t n)
1069 {
1070         return (nvlist_add_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
1071 }
1072
1073 int
1074 nvlist_add_int8_array(nvlist_t *nvl, const char *name, int8_t *a, uint_t n)
1075 {
1076         return (nvlist_add_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
1077 }
1078
1079 int
1080 nvlist_add_uint8_array(nvlist_t *nvl, const char *name, uint8_t *a, uint_t n)
1081 {
1082         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
1083 }
1084
1085 int
1086 nvlist_add_int16_array(nvlist_t *nvl, const char *name, int16_t *a, uint_t n)
1087 {
1088         return (nvlist_add_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
1089 }
1090
1091 int
1092 nvlist_add_uint16_array(nvlist_t *nvl, const char *name, uint16_t *a, uint_t n)
1093 {
1094         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
1095 }
1096
1097 int
1098 nvlist_add_int32_array(nvlist_t *nvl, const char *name, int32_t *a, uint_t n)
1099 {
1100         return (nvlist_add_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
1101 }
1102
1103 int
1104 nvlist_add_uint32_array(nvlist_t *nvl, const char *name, uint32_t *a, uint_t n)
1105 {
1106         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
1107 }
1108
1109 int
1110 nvlist_add_int64_array(nvlist_t *nvl, const char *name, int64_t *a, uint_t n)
1111 {
1112         return (nvlist_add_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
1113 }
1114
1115 int
1116 nvlist_add_uint64_array(nvlist_t *nvl, const char *name, uint64_t *a, uint_t n)
1117 {
1118         return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
1119 }
1120
1121 int
1122 nvlist_add_string_array(nvlist_t *nvl, const char *name,
1123     char *const *a, uint_t n)
1124 {
1125         return (nvlist_add_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
1126 }
1127
1128 int
1129 nvlist_add_hrtime(nvlist_t *nvl, const char *name, hrtime_t val)
1130 {
1131         return (nvlist_add_common(nvl, name, DATA_TYPE_HRTIME, 1, &val));
1132 }
1133
1134 int
1135 nvlist_add_nvlist(nvlist_t *nvl, const char *name, nvlist_t *val)
1136 {
1137         return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST, 1, val));
1138 }
1139
1140 int
1141 nvlist_add_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **a, uint_t n)
1142 {
1143         return (nvlist_add_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
1144 }
1145
1146 /* reading name-value pairs */
1147 nvpair_t *
1148 nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1149 {
1150         nvpriv_t *priv;
1151         i_nvp_t *curr;
1152
1153         if (nvl == NULL ||
1154             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1155                 return (NULL);
1156
1157         curr = NVPAIR2I_NVP(nvp);
1158
1159         /*
1160          * Ensure that nvp is a valid nvpair on this nvlist.
1161          * NB: nvp_curr is used only as a hint so that we don't always
1162          * have to walk the list to determine if nvp is still on the list.
1163          */
1164         if (nvp == NULL)
1165                 curr = priv->nvp_list;
1166         else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
1167                 curr = curr->nvi_next;
1168         else
1169                 curr = NULL;
1170
1171         priv->nvp_curr = curr;
1172
1173         return (curr != NULL ? &curr->nvi_nvp : NULL);
1174 }
1175
1176 nvpair_t *
1177 nvlist_prev_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1178 {
1179         nvpriv_t *priv;
1180         i_nvp_t *curr;
1181
1182         if (nvl == NULL ||
1183             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1184                 return (NULL);
1185
1186         curr = NVPAIR2I_NVP(nvp);
1187
1188         if (nvp == NULL)
1189                 curr = priv->nvp_last;
1190         else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
1191                 curr = curr->nvi_prev;
1192         else
1193                 curr = NULL;
1194
1195         priv->nvp_curr = curr;
1196
1197         return (curr != NULL ? &curr->nvi_nvp : NULL);
1198 }
1199
1200 boolean_t
1201 nvlist_empty(nvlist_t *nvl)
1202 {
1203         nvpriv_t *priv;
1204
1205         if (nvl == NULL ||
1206             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1207                 return (B_TRUE);
1208
1209         return (priv->nvp_list == NULL);
1210 }
1211
1212 char *
1213 nvpair_name(nvpair_t *nvp)
1214 {
1215         return (NVP_NAME(nvp));
1216 }
1217
1218 data_type_t
1219 nvpair_type(nvpair_t *nvp)
1220 {
1221         return (NVP_TYPE(nvp));
1222 }
1223
1224 int
1225 nvpair_type_is_array(nvpair_t *nvp)
1226 {
1227         data_type_t type = NVP_TYPE(nvp);
1228
1229         if ((type == DATA_TYPE_BYTE_ARRAY) ||
1230             (type == DATA_TYPE_UINT8_ARRAY) ||
1231             (type == DATA_TYPE_INT16_ARRAY) ||
1232             (type == DATA_TYPE_UINT16_ARRAY) ||
1233             (type == DATA_TYPE_INT32_ARRAY) ||
1234             (type == DATA_TYPE_UINT32_ARRAY) ||
1235             (type == DATA_TYPE_INT64_ARRAY) ||
1236             (type == DATA_TYPE_UINT64_ARRAY) ||
1237             (type == DATA_TYPE_BOOLEAN_ARRAY) ||
1238             (type == DATA_TYPE_STRING_ARRAY) ||
1239             (type == DATA_TYPE_NVLIST_ARRAY))
1240                 return (1);
1241         return (0);
1242
1243 }
1244
1245 static int
1246 nvpair_value_common(nvpair_t *nvp, data_type_t type, uint_t *nelem, void *data)
1247 {
1248         if (nvp == NULL || nvpair_type(nvp) != type)
1249                 return (EINVAL);
1250
1251         /*
1252          * For non-array types, we copy the data.
1253          * For array types (including string), we set a pointer.
1254          */
1255         switch (type) {
1256         case DATA_TYPE_BOOLEAN:
1257                 if (nelem != NULL)
1258                         *nelem = 0;
1259                 break;
1260
1261         case DATA_TYPE_BOOLEAN_VALUE:
1262         case DATA_TYPE_BYTE:
1263         case DATA_TYPE_INT8:
1264         case DATA_TYPE_UINT8:
1265         case DATA_TYPE_INT16:
1266         case DATA_TYPE_UINT16:
1267         case DATA_TYPE_INT32:
1268         case DATA_TYPE_UINT32:
1269         case DATA_TYPE_INT64:
1270         case DATA_TYPE_UINT64:
1271         case DATA_TYPE_HRTIME:
1272 #if !defined(_KERNEL)
1273         case DATA_TYPE_DOUBLE:
1274 #endif
1275                 if (data == NULL)
1276                         return (EINVAL);
1277                 bcopy(NVP_VALUE(nvp), data,
1278                     (size_t)i_get_value_size(type, NULL, 1));
1279                 if (nelem != NULL)
1280                         *nelem = 1;
1281                 break;
1282
1283         case DATA_TYPE_NVLIST:
1284         case DATA_TYPE_STRING:
1285                 if (data == NULL)
1286                         return (EINVAL);
1287                 *(void **)data = (void *)NVP_VALUE(nvp);
1288                 if (nelem != NULL)
1289                         *nelem = 1;
1290                 break;
1291
1292         case DATA_TYPE_BOOLEAN_ARRAY:
1293         case DATA_TYPE_BYTE_ARRAY:
1294         case DATA_TYPE_INT8_ARRAY:
1295         case DATA_TYPE_UINT8_ARRAY:
1296         case DATA_TYPE_INT16_ARRAY:
1297         case DATA_TYPE_UINT16_ARRAY:
1298         case DATA_TYPE_INT32_ARRAY:
1299         case DATA_TYPE_UINT32_ARRAY:
1300         case DATA_TYPE_INT64_ARRAY:
1301         case DATA_TYPE_UINT64_ARRAY:
1302         case DATA_TYPE_STRING_ARRAY:
1303         case DATA_TYPE_NVLIST_ARRAY:
1304                 if (nelem == NULL || data == NULL)
1305                         return (EINVAL);
1306                 if ((*nelem = NVP_NELEM(nvp)) != 0)
1307                         *(void **)data = (void *)NVP_VALUE(nvp);
1308                 else
1309                         *(void **)data = NULL;
1310                 break;
1311
1312         default:
1313                 return (ENOTSUP);
1314         }
1315
1316         return (0);
1317 }
1318
1319 static int
1320 nvlist_lookup_common(nvlist_t *nvl, const char *name, data_type_t type,
1321     uint_t *nelem, void *data)
1322 {
1323         nvpriv_t *priv;
1324         nvpair_t *nvp;
1325         i_nvp_t *curr;
1326
1327         if (name == NULL || nvl == NULL ||
1328             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1329                 return (EINVAL);
1330
1331         if (!(nvl->nvl_nvflag & (NV_UNIQUE_NAME | NV_UNIQUE_NAME_TYPE)))
1332                 return (ENOTSUP);
1333
1334         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
1335                 nvp = &curr->nvi_nvp;
1336
1337                 if (strcmp(name, NVP_NAME(nvp)) == 0 && NVP_TYPE(nvp) == type)
1338                         return (nvpair_value_common(nvp, type, nelem, data));
1339         }
1340
1341         return (ENOENT);
1342 }
1343
1344 int
1345 nvlist_lookup_boolean(nvlist_t *nvl, const char *name)
1346 {
1347         return (nvlist_lookup_common(nvl, name, DATA_TYPE_BOOLEAN, NULL, NULL));
1348 }
1349
1350 int
1351 nvlist_lookup_boolean_value(nvlist_t *nvl, const char *name, boolean_t *val)
1352 {
1353         return (nvlist_lookup_common(nvl, name,
1354             DATA_TYPE_BOOLEAN_VALUE, NULL, val));
1355 }
1356
1357 int
1358 nvlist_lookup_byte(nvlist_t *nvl, const char *name, uchar_t *val)
1359 {
1360         return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE, NULL, val));
1361 }
1362
1363 int
1364 nvlist_lookup_int8(nvlist_t *nvl, const char *name, int8_t *val)
1365 {
1366         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8, NULL, val));
1367 }
1368
1369 int
1370 nvlist_lookup_uint8(nvlist_t *nvl, const char *name, uint8_t *val)
1371 {
1372         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8, NULL, val));
1373 }
1374
1375 int
1376 nvlist_lookup_int16(nvlist_t *nvl, const char *name, int16_t *val)
1377 {
1378         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16, NULL, val));
1379 }
1380
1381 int
1382 nvlist_lookup_uint16(nvlist_t *nvl, const char *name, uint16_t *val)
1383 {
1384         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16, NULL, val));
1385 }
1386
1387 int
1388 nvlist_lookup_int32(nvlist_t *nvl, const char *name, int32_t *val)
1389 {
1390         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32, NULL, val));
1391 }
1392
1393 int
1394 nvlist_lookup_uint32(nvlist_t *nvl, const char *name, uint32_t *val)
1395 {
1396         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32, NULL, val));
1397 }
1398
1399 int
1400 nvlist_lookup_int64(nvlist_t *nvl, const char *name, int64_t *val)
1401 {
1402         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64, NULL, val));
1403 }
1404
1405 int
1406 nvlist_lookup_uint64(nvlist_t *nvl, const char *name, uint64_t *val)
1407 {
1408         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val));
1409 }
1410
1411 #if !defined(_KERNEL)
1412 int
1413 nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val)
1414 {
1415         return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val));
1416 }
1417 #endif
1418
1419 int
1420 nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
1421 {
1422         return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING, NULL, val));
1423 }
1424
1425 int
1426 nvlist_lookup_nvlist(nvlist_t *nvl, const char *name, nvlist_t **val)
1427 {
1428         return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST, NULL, val));
1429 }
1430
1431 int
1432 nvlist_lookup_boolean_array(nvlist_t *nvl, const char *name,
1433     boolean_t **a, uint_t *n)
1434 {
1435         return (nvlist_lookup_common(nvl, name,
1436             DATA_TYPE_BOOLEAN_ARRAY, n, a));
1437 }
1438
1439 int
1440 nvlist_lookup_byte_array(nvlist_t *nvl, const char *name,
1441     uchar_t **a, uint_t *n)
1442 {
1443         return (nvlist_lookup_common(nvl, name, DATA_TYPE_BYTE_ARRAY, n, a));
1444 }
1445
1446 int
1447 nvlist_lookup_int8_array(nvlist_t *nvl, const char *name, int8_t **a, uint_t *n)
1448 {
1449         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT8_ARRAY, n, a));
1450 }
1451
1452 int
1453 nvlist_lookup_uint8_array(nvlist_t *nvl, const char *name,
1454     uint8_t **a, uint_t *n)
1455 {
1456         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT8_ARRAY, n, a));
1457 }
1458
1459 int
1460 nvlist_lookup_int16_array(nvlist_t *nvl, const char *name,
1461     int16_t **a, uint_t *n)
1462 {
1463         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT16_ARRAY, n, a));
1464 }
1465
1466 int
1467 nvlist_lookup_uint16_array(nvlist_t *nvl, const char *name,
1468     uint16_t **a, uint_t *n)
1469 {
1470         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT16_ARRAY, n, a));
1471 }
1472
1473 int
1474 nvlist_lookup_int32_array(nvlist_t *nvl, const char *name,
1475     int32_t **a, uint_t *n)
1476 {
1477         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT32_ARRAY, n, a));
1478 }
1479
1480 int
1481 nvlist_lookup_uint32_array(nvlist_t *nvl, const char *name,
1482     uint32_t **a, uint_t *n)
1483 {
1484         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT32_ARRAY, n, a));
1485 }
1486
1487 int
1488 nvlist_lookup_int64_array(nvlist_t *nvl, const char *name,
1489     int64_t **a, uint_t *n)
1490 {
1491         return (nvlist_lookup_common(nvl, name, DATA_TYPE_INT64_ARRAY, n, a));
1492 }
1493
1494 int
1495 nvlist_lookup_uint64_array(nvlist_t *nvl, const char *name,
1496     uint64_t **a, uint_t *n)
1497 {
1498         return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64_ARRAY, n, a));
1499 }
1500
1501 int
1502 nvlist_lookup_string_array(nvlist_t *nvl, const char *name,
1503     char ***a, uint_t *n)
1504 {
1505         return (nvlist_lookup_common(nvl, name, DATA_TYPE_STRING_ARRAY, n, a));
1506 }
1507
1508 int
1509 nvlist_lookup_nvlist_array(nvlist_t *nvl, const char *name,
1510     nvlist_t ***a, uint_t *n)
1511 {
1512         return (nvlist_lookup_common(nvl, name, DATA_TYPE_NVLIST_ARRAY, n, a));
1513 }
1514
1515 int
1516 nvlist_lookup_hrtime(nvlist_t *nvl, const char *name, hrtime_t *val)
1517 {
1518         return (nvlist_lookup_common(nvl, name, DATA_TYPE_HRTIME, NULL, val));
1519 }
1520
1521 int
1522 nvlist_lookup_pairs(nvlist_t *nvl, int flag, ...)
1523 {
1524         va_list ap;
1525         char *name;
1526         int noentok = (flag & NV_FLAG_NOENTOK ? 1 : 0);
1527         int ret = 0;
1528
1529         va_start(ap, flag);
1530         while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
1531                 data_type_t type;
1532                 void *val;
1533                 uint_t *nelem;
1534
1535                 switch (type = va_arg(ap, data_type_t)) {
1536                 case DATA_TYPE_BOOLEAN:
1537                         ret = nvlist_lookup_common(nvl, name, type, NULL, NULL);
1538                         break;
1539
1540                 case DATA_TYPE_BOOLEAN_VALUE:
1541                 case DATA_TYPE_BYTE:
1542                 case DATA_TYPE_INT8:
1543                 case DATA_TYPE_UINT8:
1544                 case DATA_TYPE_INT16:
1545                 case DATA_TYPE_UINT16:
1546                 case DATA_TYPE_INT32:
1547                 case DATA_TYPE_UINT32:
1548                 case DATA_TYPE_INT64:
1549                 case DATA_TYPE_UINT64:
1550                 case DATA_TYPE_HRTIME:
1551                 case DATA_TYPE_STRING:
1552                 case DATA_TYPE_NVLIST:
1553 #if !defined(_KERNEL)
1554                 case DATA_TYPE_DOUBLE:
1555 #endif
1556                         val = va_arg(ap, void *);
1557                         ret = nvlist_lookup_common(nvl, name, type, NULL, val);
1558                         break;
1559
1560                 case DATA_TYPE_BYTE_ARRAY:
1561                 case DATA_TYPE_BOOLEAN_ARRAY:
1562                 case DATA_TYPE_INT8_ARRAY:
1563                 case DATA_TYPE_UINT8_ARRAY:
1564                 case DATA_TYPE_INT16_ARRAY:
1565                 case DATA_TYPE_UINT16_ARRAY:
1566                 case DATA_TYPE_INT32_ARRAY:
1567                 case DATA_TYPE_UINT32_ARRAY:
1568                 case DATA_TYPE_INT64_ARRAY:
1569                 case DATA_TYPE_UINT64_ARRAY:
1570                 case DATA_TYPE_STRING_ARRAY:
1571                 case DATA_TYPE_NVLIST_ARRAY:
1572                         val = va_arg(ap, void *);
1573                         nelem = va_arg(ap, uint_t *);
1574                         ret = nvlist_lookup_common(nvl, name, type, nelem, val);
1575                         break;
1576
1577                 default:
1578                         ret = EINVAL;
1579                 }
1580
1581                 if (ret == ENOENT && noentok)
1582                         ret = 0;
1583         }
1584         va_end(ap);
1585
1586         return (ret);
1587 }
1588
1589 /*
1590  * Find the 'name'ed nvpair in the nvlist 'nvl'. If 'name' found, the function
1591  * returns zero and a pointer to the matching nvpair is returned in '*ret'
1592  * (given 'ret' is non-NULL). If 'sep' is specified then 'name' will penitrate
1593  * multiple levels of embedded nvlists, with 'sep' as the separator. As an
1594  * example, if sep is '.', name might look like: "a" or "a.b" or "a.c[3]" or
1595  * "a.d[3].e[1]".  This matches the C syntax for array embed (for convience,
1596  * code also supports "a.d[3]e[1]" syntax).
1597  *
1598  * If 'ip' is non-NULL and the last name component is an array, return the
1599  * value of the "...[index]" array index in *ip. For an array reference that
1600  * is not indexed, *ip will be returned as -1. If there is a syntax error in
1601  * 'name', and 'ep' is non-NULL then *ep will be set to point to the location
1602  * inside the 'name' string where the syntax error was detected.
1603  */
1604 static int
1605 nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
1606     nvpair_t **ret, int *ip, char **ep)
1607 {
1608         nvpair_t        *nvp;
1609         const char      *np;
1610         char            *sepp;
1611         char            *idxp, *idxep;
1612         nvlist_t        **nva;
1613         long            idx;
1614         int             n;
1615
1616         if (ip)
1617                 *ip = -1;                       /* not indexed */
1618         if (ep)
1619                 *ep = NULL;
1620
1621         if ((nvl == NULL) || (name == NULL))
1622                 return (EINVAL);
1623
1624         /* step through components of name */
1625         for (np = name; np && *np; np = sepp) {
1626                 /* ensure unique names */
1627                 if (!(nvl->nvl_nvflag & NV_UNIQUE_NAME))
1628                         return (ENOTSUP);
1629
1630                 /* skip white space */
1631                 skip_whitespace(np);
1632                 if (*np == 0)
1633                         break;
1634
1635                 /* set 'sepp' to end of current component 'np' */
1636                 if (sep)
1637                         sepp = strchr(np, sep);
1638                 else
1639                         sepp = NULL;
1640
1641                 /* find start of next "[ index ]..." */
1642                 idxp = strchr(np, '[');
1643
1644                 /* if sepp comes first, set idxp to NULL */
1645                 if (sepp && idxp && (sepp < idxp))
1646                         idxp = NULL;
1647
1648                 /*
1649                  * At this point 'idxp' is set if there is an index
1650                  * expected for the current component.
1651                  */
1652                 if (idxp) {
1653                         /* set 'n' to length of current 'np' name component */
1654                         n = idxp++ - np;
1655
1656                         /* keep sepp up to date for *ep use as we advance */
1657                         skip_whitespace(idxp);
1658                         sepp = idxp;
1659
1660                         /* determine the index value */
1661 #if defined(_KERNEL) && !defined(_BOOT)
1662                         if (ddi_strtol(idxp, &idxep, 0, &idx))
1663                                 goto fail;
1664 #else
1665                         idx = strtol(idxp, &idxep, 0);
1666 #endif
1667                         if (idxep == idxp)
1668                                 goto fail;
1669
1670                         /* keep sepp up to date for *ep use as we advance */
1671                         sepp = idxep;
1672
1673                         /* skip white space index value and check for ']' */
1674                         skip_whitespace(sepp);
1675                         if (*sepp++ != ']')
1676                                 goto fail;
1677
1678                         /* for embedded arrays, support C syntax: "a[1].b" */
1679                         skip_whitespace(sepp);
1680                         if (sep && (*sepp == sep))
1681                                 sepp++;
1682                 } else if (sepp) {
1683                         n = sepp++ - np;
1684                 } else {
1685                         n = strlen(np);
1686                 }
1687
1688                 /* trim trailing whitespace by reducing length of 'np' */
1689                 if (n == 0)
1690                         goto fail;
1691                 for (n--; (np[n] == ' ') || (np[n] == '\t'); n--)
1692                         ;
1693                 n++;
1694
1695                 /* skip whitespace, and set sepp to NULL if complete */
1696                 if (sepp) {
1697                         skip_whitespace(sepp);
1698                         if (*sepp == 0)
1699                                 sepp = NULL;
1700                 }
1701
1702                 /*
1703                  * At this point:
1704                  * o  'n' is the length of current 'np' component.
1705                  * o  'idxp' is set if there was an index, and value 'idx'.
1706                  * o  'sepp' is set to the beginning of the next component,
1707                  *    and set to NULL if we have no more components.
1708                  *
1709                  * Search for nvpair with matching component name.
1710                  */
1711                 for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
1712                     nvp = nvlist_next_nvpair(nvl, nvp)) {
1713
1714                         /* continue if no match on name */
1715                         if (strncmp(np, nvpair_name(nvp), n) ||
1716                             (strlen(nvpair_name(nvp)) != n))
1717                                 continue;
1718
1719                         /* if indexed, verify type is array oriented */
1720                         if (idxp && !nvpair_type_is_array(nvp))
1721                                 goto fail;
1722
1723                         /*
1724                          * Full match found, return nvp and idx if this
1725                          * was the last component.
1726                          */
1727                         if (sepp == NULL) {
1728                                 if (ret)
1729                                         *ret = nvp;
1730                                 if (ip && idxp)
1731                                         *ip = (int)idx; /* return index */
1732                                 return (0);             /* found */
1733                         }
1734
1735                         /*
1736                          * More components: current match must be
1737                          * of DATA_TYPE_NVLIST or DATA_TYPE_NVLIST_ARRAY
1738                          * to support going deeper.
1739                          */
1740                         if (nvpair_type(nvp) == DATA_TYPE_NVLIST) {
1741                                 nvl = EMBEDDED_NVL(nvp);
1742                                 break;
1743                         } else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY) {
1744                                 (void) nvpair_value_nvlist_array(nvp,
1745                                     &nva, (uint_t *)&n);
1746                                 if ((n < 0) || (idx >= n))
1747                                         goto fail;
1748                                 nvl = nva[idx];
1749                                 break;
1750                         }
1751
1752                         /* type does not support more levels */
1753                         goto fail;
1754                 }
1755                 if (nvp == NULL)
1756                         goto fail;              /* 'name' not found */
1757
1758                 /* search for match of next component in embedded 'nvl' list */
1759         }
1760
1761 fail:   if (ep && sepp)
1762                 *ep = sepp;
1763         return (EINVAL);
1764 }
1765
1766 /*
1767  * Return pointer to nvpair with specified 'name'.
1768  */
1769 int
1770 nvlist_lookup_nvpair(nvlist_t *nvl, const char *name, nvpair_t **ret)
1771 {
1772         return (nvlist_lookup_nvpair_ei_sep(nvl, name, 0, ret, NULL, NULL));
1773 }
1774
1775 /*
1776  * Determine if named nvpair exists in nvlist (use embedded separator of '.'
1777  * and return array index).  See nvlist_lookup_nvpair_ei_sep for more detailed
1778  * description.
1779  */
1780 int nvlist_lookup_nvpair_embedded_index(nvlist_t *nvl,
1781     const char *name, nvpair_t **ret, int *ip, char **ep)
1782 {
1783         return (nvlist_lookup_nvpair_ei_sep(nvl, name, '.', ret, ip, ep));
1784 }
1785
1786 boolean_t
1787 nvlist_exists(nvlist_t *nvl, const char *name)
1788 {
1789         nvpriv_t *priv;
1790         nvpair_t *nvp;
1791         i_nvp_t *curr;
1792
1793         if (name == NULL || nvl == NULL ||
1794             (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
1795                 return (B_FALSE);
1796
1797         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
1798                 nvp = &curr->nvi_nvp;
1799
1800                 if (strcmp(name, NVP_NAME(nvp)) == 0)
1801                         return (B_TRUE);
1802         }
1803
1804         return (B_FALSE);
1805 }
1806
1807 int
1808 nvpair_value_boolean_value(nvpair_t *nvp, boolean_t *val)
1809 {
1810         return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_VALUE, NULL, val));
1811 }
1812
1813 int
1814 nvpair_value_byte(nvpair_t *nvp, uchar_t *val)
1815 {
1816         return (nvpair_value_common(nvp, DATA_TYPE_BYTE, NULL, val));
1817 }
1818
1819 int
1820 nvpair_value_int8(nvpair_t *nvp, int8_t *val)
1821 {
1822         return (nvpair_value_common(nvp, DATA_TYPE_INT8, NULL, val));
1823 }
1824
1825 int
1826 nvpair_value_uint8(nvpair_t *nvp, uint8_t *val)
1827 {
1828         return (nvpair_value_common(nvp, DATA_TYPE_UINT8, NULL, val));
1829 }
1830
1831 int
1832 nvpair_value_int16(nvpair_t *nvp, int16_t *val)
1833 {
1834         return (nvpair_value_common(nvp, DATA_TYPE_INT16, NULL, val));
1835 }
1836
1837 int
1838 nvpair_value_uint16(nvpair_t *nvp, uint16_t *val)
1839 {
1840         return (nvpair_value_common(nvp, DATA_TYPE_UINT16, NULL, val));
1841 }
1842
1843 int
1844 nvpair_value_int32(nvpair_t *nvp, int32_t *val)
1845 {
1846         return (nvpair_value_common(nvp, DATA_TYPE_INT32, NULL, val));
1847 }
1848
1849 int
1850 nvpair_value_uint32(nvpair_t *nvp, uint32_t *val)
1851 {
1852         return (nvpair_value_common(nvp, DATA_TYPE_UINT32, NULL, val));
1853 }
1854
1855 int
1856 nvpair_value_int64(nvpair_t *nvp, int64_t *val)
1857 {
1858         return (nvpair_value_common(nvp, DATA_TYPE_INT64, NULL, val));
1859 }
1860
1861 int
1862 nvpair_value_uint64(nvpair_t *nvp, uint64_t *val)
1863 {
1864         return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val));
1865 }
1866
1867 #if !defined(_KERNEL)
1868 int
1869 nvpair_value_double(nvpair_t *nvp, double *val)
1870 {
1871         return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val));
1872 }
1873 #endif
1874
1875 int
1876 nvpair_value_string(nvpair_t *nvp, char **val)
1877 {
1878         return (nvpair_value_common(nvp, DATA_TYPE_STRING, NULL, val));
1879 }
1880
1881 int
1882 nvpair_value_nvlist(nvpair_t *nvp, nvlist_t **val)
1883 {
1884         return (nvpair_value_common(nvp, DATA_TYPE_NVLIST, NULL, val));
1885 }
1886
1887 int
1888 nvpair_value_boolean_array(nvpair_t *nvp, boolean_t **val, uint_t *nelem)
1889 {
1890         return (nvpair_value_common(nvp, DATA_TYPE_BOOLEAN_ARRAY, nelem, val));
1891 }
1892
1893 int
1894 nvpair_value_byte_array(nvpair_t *nvp, uchar_t **val, uint_t *nelem)
1895 {
1896         return (nvpair_value_common(nvp, DATA_TYPE_BYTE_ARRAY, nelem, val));
1897 }
1898
1899 int
1900 nvpair_value_int8_array(nvpair_t *nvp, int8_t **val, uint_t *nelem)
1901 {
1902         return (nvpair_value_common(nvp, DATA_TYPE_INT8_ARRAY, nelem, val));
1903 }
1904
1905 int
1906 nvpair_value_uint8_array(nvpair_t *nvp, uint8_t **val, uint_t *nelem)
1907 {
1908         return (nvpair_value_common(nvp, DATA_TYPE_UINT8_ARRAY, nelem, val));
1909 }
1910
1911 int
1912 nvpair_value_int16_array(nvpair_t *nvp, int16_t **val, uint_t *nelem)
1913 {
1914         return (nvpair_value_common(nvp, DATA_TYPE_INT16_ARRAY, nelem, val));
1915 }
1916
1917 int
1918 nvpair_value_uint16_array(nvpair_t *nvp, uint16_t **val, uint_t *nelem)
1919 {
1920         return (nvpair_value_common(nvp, DATA_TYPE_UINT16_ARRAY, nelem, val));
1921 }
1922
1923 int
1924 nvpair_value_int32_array(nvpair_t *nvp, int32_t **val, uint_t *nelem)
1925 {
1926         return (nvpair_value_common(nvp, DATA_TYPE_INT32_ARRAY, nelem, val));
1927 }
1928
1929 int
1930 nvpair_value_uint32_array(nvpair_t *nvp, uint32_t **val, uint_t *nelem)
1931 {
1932         return (nvpair_value_common(nvp, DATA_TYPE_UINT32_ARRAY, nelem, val));
1933 }
1934
1935 int
1936 nvpair_value_int64_array(nvpair_t *nvp, int64_t **val, uint_t *nelem)
1937 {
1938         return (nvpair_value_common(nvp, DATA_TYPE_INT64_ARRAY, nelem, val));
1939 }
1940
1941 int
1942 nvpair_value_uint64_array(nvpair_t *nvp, uint64_t **val, uint_t *nelem)
1943 {
1944         return (nvpair_value_common(nvp, DATA_TYPE_UINT64_ARRAY, nelem, val));
1945 }
1946
1947 int
1948 nvpair_value_string_array(nvpair_t *nvp, char ***val, uint_t *nelem)
1949 {
1950         return (nvpair_value_common(nvp, DATA_TYPE_STRING_ARRAY, nelem, val));
1951 }
1952
1953 int
1954 nvpair_value_nvlist_array(nvpair_t *nvp, nvlist_t ***val, uint_t *nelem)
1955 {
1956         return (nvpair_value_common(nvp, DATA_TYPE_NVLIST_ARRAY, nelem, val));
1957 }
1958
1959 int
1960 nvpair_value_hrtime(nvpair_t *nvp, hrtime_t *val)
1961 {
1962         return (nvpair_value_common(nvp, DATA_TYPE_HRTIME, NULL, val));
1963 }
1964
1965 /*
1966  * Add specified pair to the list.
1967  */
1968 int
1969 nvlist_add_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1970 {
1971         if (nvl == NULL || nvp == NULL)
1972                 return (EINVAL);
1973
1974         return (nvlist_add_common(nvl, NVP_NAME(nvp), NVP_TYPE(nvp),
1975             NVP_NELEM(nvp), NVP_VALUE(nvp)));
1976 }
1977
1978 /*
1979  * Merge the supplied nvlists and put the result in dst.
1980  * The merged list will contain all names specified in both lists,
1981  * the values are taken from nvl in the case of duplicates.
1982  * Return 0 on success.
1983  */
1984 /*ARGSUSED*/
1985 int
1986 nvlist_merge(nvlist_t *dst, nvlist_t *nvl, int flag)
1987 {
1988         if (nvl == NULL || dst == NULL)
1989                 return (EINVAL);
1990
1991         if (dst != nvl)
1992                 return (nvlist_copy_pairs(nvl, dst));
1993
1994         return (0);
1995 }
1996
1997 /*
1998  * Encoding related routines
1999  */
2000 #define NVS_OP_ENCODE   0
2001 #define NVS_OP_DECODE   1
2002 #define NVS_OP_GETSIZE  2
2003
2004 typedef struct nvs_ops nvs_ops_t;
2005
2006 typedef struct {
2007         int             nvs_op;
2008         const nvs_ops_t *nvs_ops;
2009         void            *nvs_private;
2010         nvpriv_t        *nvs_priv;
2011 } nvstream_t;
2012
2013 /*
2014  * nvs operations are:
2015  *   - nvs_nvlist
2016  *     encoding / decoding of a nvlist header (nvlist_t)
2017  *     calculates the size used for header and end detection
2018  *
2019  *   - nvs_nvpair
2020  *     responsible for the first part of encoding / decoding of an nvpair
2021  *     calculates the decoded size of an nvpair
2022  *
2023  *   - nvs_nvp_op
2024  *     second part of encoding / decoding of an nvpair
2025  *
2026  *   - nvs_nvp_size
2027  *     calculates the encoding size of an nvpair
2028  *
2029  *   - nvs_nvl_fini
2030  *     encodes the end detection mark (zeros).
2031  */
2032 struct nvs_ops {
2033         int (*nvs_nvlist)(nvstream_t *, nvlist_t *, size_t *);
2034         int (*nvs_nvpair)(nvstream_t *, nvpair_t *, size_t *);
2035         int (*nvs_nvp_op)(nvstream_t *, nvpair_t *);
2036         int (*nvs_nvp_size)(nvstream_t *, nvpair_t *, size_t *);
2037         int (*nvs_nvl_fini)(nvstream_t *);
2038 };
2039
2040 typedef struct {
2041         char    nvh_encoding;   /* nvs encoding method */
2042         char    nvh_endian;     /* nvs endian */
2043         char    nvh_reserved1;  /* reserved for future use */
2044         char    nvh_reserved2;  /* reserved for future use */
2045 } nvs_header_t;
2046
2047 static int
2048 nvs_encode_pairs(nvstream_t *nvs, nvlist_t *nvl)
2049 {
2050         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
2051         i_nvp_t *curr;
2052
2053         /*
2054          * Walk nvpair in list and encode each nvpair
2055          */
2056         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next)
2057                 if (nvs->nvs_ops->nvs_nvpair(nvs, &curr->nvi_nvp, NULL) != 0)
2058                         return (EFAULT);
2059
2060         return (nvs->nvs_ops->nvs_nvl_fini(nvs));
2061 }
2062
2063 static int
2064 nvs_decode_pairs(nvstream_t *nvs, nvlist_t *nvl)
2065 {
2066         nvpair_t *nvp;
2067         size_t nvsize;
2068         int err;
2069
2070         /*
2071          * Get decoded size of next pair in stream, alloc
2072          * memory for nvpair_t, then decode the nvpair
2073          */
2074         while ((err = nvs->nvs_ops->nvs_nvpair(nvs, NULL, &nvsize)) == 0) {
2075                 if (nvsize == 0) /* end of list */
2076                         break;
2077
2078                 /* make sure len makes sense */
2079                 if (nvsize < NVP_SIZE_CALC(1, 0))
2080                         return (EFAULT);
2081
2082                 if ((nvp = nvp_buf_alloc(nvl, nvsize)) == NULL)
2083                         return (ENOMEM);
2084
2085                 if ((err = nvs->nvs_ops->nvs_nvp_op(nvs, nvp)) != 0) {
2086                         nvp_buf_free(nvl, nvp);
2087                         return (err);
2088                 }
2089
2090                 if (i_validate_nvpair(nvp) != 0) {
2091                         nvpair_free(nvp);
2092                         nvp_buf_free(nvl, nvp);
2093                         return (EFAULT);
2094                 }
2095
2096                 nvp_buf_link(nvl, nvp);
2097         }
2098         return (err);
2099 }
2100
2101 static int
2102 nvs_getsize_pairs(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
2103 {
2104         nvpriv_t *priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv;
2105         i_nvp_t *curr;
2106         uint64_t nvsize = *buflen;
2107         size_t size;
2108
2109         /*
2110          * Get encoded size of nvpairs in nvlist
2111          */
2112         for (curr = priv->nvp_list; curr != NULL; curr = curr->nvi_next) {
2113                 if (nvs->nvs_ops->nvs_nvp_size(nvs, &curr->nvi_nvp, &size) != 0)
2114                         return (EINVAL);
2115
2116                 if ((nvsize += size) > INT32_MAX)
2117                         return (EINVAL);
2118         }
2119
2120         *buflen = nvsize;
2121         return (0);
2122 }
2123
2124 static int
2125 nvs_operation(nvstream_t *nvs, nvlist_t *nvl, size_t *buflen)
2126 {
2127         int err;
2128
2129         if (nvl->nvl_priv == 0)
2130                 return (EFAULT);
2131
2132         /*
2133          * Perform the operation, starting with header, then each nvpair
2134          */
2135         if ((err = nvs->nvs_ops->nvs_nvlist(nvs, nvl, buflen)) != 0)
2136                 return (err);
2137
2138         switch (nvs->nvs_op) {
2139         case NVS_OP_ENCODE:
2140                 err = nvs_encode_pairs(nvs, nvl);
2141                 break;
2142
2143         case NVS_OP_DECODE:
2144                 err = nvs_decode_pairs(nvs, nvl);
2145                 break;
2146
2147         case NVS_OP_GETSIZE:
2148                 err = nvs_getsize_pairs(nvs, nvl, buflen);
2149                 break;
2150
2151         default:
2152                 err = EINVAL;
2153         }
2154
2155         return (err);
2156 }
2157
2158 static int
2159 nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
2160 {
2161         switch (nvs->nvs_op) {
2162         case NVS_OP_ENCODE:
2163                 return (nvs_operation(nvs, embedded, NULL));
2164
2165         case NVS_OP_DECODE: {
2166                 nvpriv_t *priv;
2167                 int err;
2168
2169                 if (embedded->nvl_version != NV_VERSION)
2170                         return (ENOTSUP);
2171
2172                 if ((priv = nv_priv_alloc_embedded(nvs->nvs_priv)) == NULL)
2173                         return (ENOMEM);
2174
2175                 nvlist_init(embedded, embedded->nvl_nvflag, priv);
2176
2177                 if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
2178                         nvlist_free(embedded);
2179                 return (err);
2180         }
2181         default:
2182                 break;
2183         }
2184
2185         return (EINVAL);
2186 }
2187
2188 static int
2189 nvs_embedded_nvl_array(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2190 {
2191         size_t nelem = NVP_NELEM(nvp);
2192         nvlist_t **nvlp = EMBEDDED_NVL_ARRAY(nvp);
2193         int i;
2194
2195         switch (nvs->nvs_op) {
2196         case NVS_OP_ENCODE:
2197                 for (i = 0; i < nelem; i++)
2198                         if (nvs_embedded(nvs, nvlp[i]) != 0)
2199                                 return (EFAULT);
2200                 break;
2201
2202         case NVS_OP_DECODE: {
2203                 size_t len = nelem * sizeof (uint64_t);
2204                 nvlist_t *embedded = (nvlist_t *)((uintptr_t)nvlp + len);
2205
2206                 bzero(nvlp, len);       /* don't trust packed data */
2207                 for (i = 0; i < nelem; i++) {
2208                         if (nvs_embedded(nvs, embedded) != 0) {
2209                                 nvpair_free(nvp);
2210                                 return (EFAULT);
2211                         }
2212
2213                         nvlp[i] = embedded++;
2214                 }
2215                 break;
2216         }
2217         case NVS_OP_GETSIZE: {
2218                 uint64_t nvsize = 0;
2219
2220                 for (i = 0; i < nelem; i++) {
2221                         size_t nvp_sz = 0;
2222
2223                         if (nvs_operation(nvs, nvlp[i], &nvp_sz) != 0)
2224                                 return (EINVAL);
2225
2226                         if ((nvsize += nvp_sz) > INT32_MAX)
2227                                 return (EINVAL);
2228                 }
2229
2230                 *size = nvsize;
2231                 break;
2232         }
2233         default:
2234                 return (EINVAL);
2235         }
2236
2237         return (0);
2238 }
2239
2240 static int nvs_native(nvstream_t *, nvlist_t *, char *, size_t *);
2241 static int nvs_xdr(nvstream_t *, nvlist_t *, char *, size_t *);
2242
2243 /*
2244  * Common routine for nvlist operations:
2245  * encode, decode, getsize (encoded size).
2246  */
2247 static int
2248 nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding,
2249     int nvs_op)
2250 {
2251         int err = 0;
2252         nvstream_t nvs;
2253         int nvl_endian;
2254 #if BYTE_ORDER == _LITTLE_ENDIAN
2255         int host_endian = 1;
2256 #else
2257         int host_endian = 0;
2258 #endif  /* _LITTLE_ENDIAN */
2259         nvs_header_t *nvh = (void *)buf;
2260
2261         if (buflen == NULL || nvl == NULL ||
2262             (nvs.nvs_priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
2263                 return (EINVAL);
2264
2265         nvs.nvs_op = nvs_op;
2266
2267         /*
2268          * For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
2269          * a buffer is allocated.  The first 4 bytes in the buffer are
2270          * used for encoding method and host endian.
2271          */
2272         switch (nvs_op) {
2273         case NVS_OP_ENCODE:
2274                 if (buf == NULL || *buflen < sizeof (nvs_header_t))
2275                         return (EINVAL);
2276
2277                 nvh->nvh_encoding = encoding;
2278                 nvh->nvh_endian = nvl_endian = host_endian;
2279                 nvh->nvh_reserved1 = 0;
2280                 nvh->nvh_reserved2 = 0;
2281                 break;
2282
2283         case NVS_OP_DECODE:
2284                 if (buf == NULL || *buflen < sizeof (nvs_header_t))
2285                         return (EINVAL);
2286
2287                 /* get method of encoding from first byte */
2288                 encoding = nvh->nvh_encoding;
2289                 nvl_endian = nvh->nvh_endian;
2290                 break;
2291
2292         case NVS_OP_GETSIZE:
2293                 nvl_endian = host_endian;
2294
2295                 /*
2296                  * add the size for encoding
2297                  */
2298                 *buflen = sizeof (nvs_header_t);
2299                 break;
2300
2301         default:
2302                 return (ENOTSUP);
2303         }
2304
2305         /*
2306          * Create an nvstream with proper encoding method
2307          */
2308         switch (encoding) {
2309         case NV_ENCODE_NATIVE:
2310                 /*
2311                  * check endianness, in case we are unpacking
2312                  * from a file
2313                  */
2314                 if (nvl_endian != host_endian)
2315                         return (ENOTSUP);
2316                 err = nvs_native(&nvs, nvl, buf, buflen);
2317                 break;
2318         case NV_ENCODE_XDR:
2319                 err = nvs_xdr(&nvs, nvl, buf, buflen);
2320                 break;
2321         default:
2322                 err = ENOTSUP;
2323                 break;
2324         }
2325
2326         return (err);
2327 }
2328
2329 int
2330 nvlist_size(nvlist_t *nvl, size_t *size, int encoding)
2331 {
2332         return (nvlist_common(nvl, NULL, size, encoding, NVS_OP_GETSIZE));
2333 }
2334
2335 /*
2336  * Pack nvlist into contiguous memory
2337  */
2338 /*ARGSUSED1*/
2339 int
2340 nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
2341     int kmflag)
2342 {
2343 #if defined(_KERNEL) && !defined(_BOOT)
2344         return (nvlist_xpack(nvl, bufp, buflen, encoding,
2345             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
2346 #else
2347         return (nvlist_xpack(nvl, bufp, buflen, encoding, nv_alloc_nosleep));
2348 #endif
2349 }
2350
2351 int
2352 nvlist_xpack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
2353     nv_alloc_t *nva)
2354 {
2355         nvpriv_t nvpriv;
2356         size_t alloc_size;
2357         char *buf;
2358         int err;
2359
2360         if (nva == NULL || nvl == NULL || bufp == NULL || buflen == NULL)
2361                 return (EINVAL);
2362
2363         if (*bufp != NULL)
2364                 return (nvlist_common(nvl, *bufp, buflen, encoding,
2365                     NVS_OP_ENCODE));
2366
2367         /*
2368          * Here is a difficult situation:
2369          * 1. The nvlist has fixed allocator properties.
2370          *    All other nvlist routines (like nvlist_add_*, ...) use
2371          *    these properties.
2372          * 2. When using nvlist_pack() the user can specify his own
2373          *    allocator properties (e.g. by using KM_NOSLEEP).
2374          *
2375          * We use the user specified properties (2). A clearer solution
2376          * will be to remove the kmflag from nvlist_pack(), but we will
2377          * not change the interface.
2378          */
2379         nv_priv_init(&nvpriv, nva, 0);
2380
2381         if (err = nvlist_size(nvl, &alloc_size, encoding))
2382                 return (err);
2383
2384         if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL)
2385                 return (ENOMEM);
2386
2387         if ((err = nvlist_common(nvl, buf, &alloc_size, encoding,
2388             NVS_OP_ENCODE)) != 0) {
2389                 nv_mem_free(&nvpriv, buf, alloc_size);
2390         } else {
2391                 *buflen = alloc_size;
2392                 *bufp = buf;
2393         }
2394
2395         return (err);
2396 }
2397
2398 /*
2399  * Unpack buf into an nvlist_t
2400  */
2401 /*ARGSUSED1*/
2402 int
2403 nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag)
2404 {
2405 #if defined(_KERNEL) && !defined(_BOOT)
2406         return (nvlist_xunpack(buf, buflen, nvlp,
2407             (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
2408 #else
2409         return (nvlist_xunpack(buf, buflen, nvlp, nv_alloc_nosleep));
2410 #endif
2411 }
2412
2413 int
2414 nvlist_xunpack(char *buf, size_t buflen, nvlist_t **nvlp, nv_alloc_t *nva)
2415 {
2416         nvlist_t *nvl;
2417         int err;
2418
2419         if (nvlp == NULL)
2420                 return (EINVAL);
2421
2422         if ((err = nvlist_xalloc(&nvl, 0, nva)) != 0)
2423                 return (err);
2424
2425         if ((err = nvlist_common(nvl, buf, &buflen, 0, NVS_OP_DECODE)) != 0)
2426                 nvlist_free(nvl);
2427         else
2428                 *nvlp = nvl;
2429
2430         return (err);
2431 }
2432
2433 /*
2434  * Native encoding functions
2435  */
2436 typedef struct {
2437         /*
2438          * This structure is used when decoding a packed nvpair in
2439          * the native format.  n_base points to a buffer containing the
2440          * packed nvpair.  n_end is a pointer to the end of the buffer.
2441          * (n_end actually points to the first byte past the end of the
2442          * buffer.)  n_curr is a pointer that lies between n_base and n_end.
2443          * It points to the current data that we are decoding.
2444          * The amount of data left in the buffer is equal to n_end - n_curr.
2445          * n_flag is used to recognize a packed embedded list.
2446          */
2447         caddr_t n_base;
2448         caddr_t n_end;
2449         caddr_t n_curr;
2450         uint_t  n_flag;
2451 } nvs_native_t;
2452
2453 static int
2454 nvs_native_create(nvstream_t *nvs, nvs_native_t *native, char *buf,
2455     size_t buflen)
2456 {
2457         switch (nvs->nvs_op) {
2458         case NVS_OP_ENCODE:
2459         case NVS_OP_DECODE:
2460                 nvs->nvs_private = native;
2461                 native->n_curr = native->n_base = buf;
2462                 native->n_end = buf + buflen;
2463                 native->n_flag = 0;
2464                 return (0);
2465
2466         case NVS_OP_GETSIZE:
2467                 nvs->nvs_private = native;
2468                 native->n_curr = native->n_base = native->n_end = NULL;
2469                 native->n_flag = 0;
2470                 return (0);
2471         default:
2472                 return (EINVAL);
2473         }
2474 }
2475
2476 /*ARGSUSED*/
2477 static void
2478 nvs_native_destroy(nvstream_t *nvs)
2479 {
2480 }
2481
2482 static int
2483 native_cp(nvstream_t *nvs, void *buf, size_t size)
2484 {
2485         nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2486
2487         if (native->n_curr + size > native->n_end)
2488                 return (EFAULT);
2489
2490         /*
2491          * The bcopy() below eliminates alignment requirement
2492          * on the buffer (stream) and is preferred over direct access.
2493          */
2494         switch (nvs->nvs_op) {
2495         case NVS_OP_ENCODE:
2496                 bcopy(buf, native->n_curr, size);
2497                 break;
2498         case NVS_OP_DECODE:
2499                 bcopy(native->n_curr, buf, size);
2500                 break;
2501         default:
2502                 return (EINVAL);
2503         }
2504
2505         native->n_curr += size;
2506         return (0);
2507 }
2508
2509 /*
2510  * operate on nvlist_t header
2511  */
2512 static int
2513 nvs_native_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
2514 {
2515         nvs_native_t *native = nvs->nvs_private;
2516
2517         switch (nvs->nvs_op) {
2518         case NVS_OP_ENCODE:
2519         case NVS_OP_DECODE:
2520                 if (native->n_flag)
2521                         return (0);     /* packed embedded list */
2522
2523                 native->n_flag = 1;
2524
2525                 /* copy version and nvflag of the nvlist_t */
2526                 if (native_cp(nvs, &nvl->nvl_version, sizeof (int32_t)) != 0 ||
2527                     native_cp(nvs, &nvl->nvl_nvflag, sizeof (int32_t)) != 0)
2528                         return (EFAULT);
2529
2530                 return (0);
2531
2532         case NVS_OP_GETSIZE:
2533                 /*
2534                  * if calculate for packed embedded list
2535                  *      4 for end of the embedded list
2536                  * else
2537                  *      2 * sizeof (int32_t) for nvl_version and nvl_nvflag
2538                  *      and 4 for end of the entire list
2539                  */
2540                 if (native->n_flag) {
2541                         *size += 4;
2542                 } else {
2543                         native->n_flag = 1;
2544                         *size += 2 * sizeof (int32_t) + 4;
2545                 }
2546
2547                 return (0);
2548
2549         default:
2550                 return (EINVAL);
2551         }
2552 }
2553
2554 static int
2555 nvs_native_nvl_fini(nvstream_t *nvs)
2556 {
2557         if (nvs->nvs_op == NVS_OP_ENCODE) {
2558                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2559                 /*
2560                  * Add 4 zero bytes at end of nvlist. They are used
2561                  * for end detection by the decode routine.
2562                  */
2563                 if (native->n_curr + sizeof (int) > native->n_end)
2564                         return (EFAULT);
2565
2566                 bzero(native->n_curr, sizeof (int));
2567                 native->n_curr += sizeof (int);
2568         }
2569
2570         return (0);
2571 }
2572
2573 static int
2574 nvpair_native_embedded(nvstream_t *nvs, nvpair_t *nvp)
2575 {
2576         if (nvs->nvs_op == NVS_OP_ENCODE) {
2577                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2578                 char *packed = (void *)
2579                     (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
2580                 /*
2581                  * Null out the pointer that is meaningless in the packed
2582                  * structure. The address may not be aligned, so we have
2583                  * to use bzero.
2584                  */
2585                 bzero(packed + offsetof(nvlist_t, nvl_priv),
2586                     sizeof(((nvlist_t *)NULL)->nvl_priv));
2587         }
2588
2589         return (nvs_embedded(nvs, EMBEDDED_NVL(nvp)));
2590 }
2591
2592 static int
2593 nvpair_native_embedded_array(nvstream_t *nvs, nvpair_t *nvp)
2594 {
2595         if (nvs->nvs_op == NVS_OP_ENCODE) {
2596                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2597                 char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp);
2598                 size_t len = NVP_NELEM(nvp) * sizeof (uint64_t);
2599                 int i;
2600                 /*
2601                  * Null out pointers that are meaningless in the packed
2602                  * structure. The addresses may not be aligned, so we have
2603                  * to use bzero.
2604                  */
2605                 bzero(value, len);
2606
2607                 value += len;
2608                 for (i = 0; i < NVP_NELEM(nvp); i++) {
2609                         /*
2610                          * Null out the pointer that is meaningless in the
2611                          * packed structure. The address may not be aligned,
2612                          * so we have to use bzero.
2613                          */
2614                         bzero(value + offsetof(nvlist_t, nvl_priv),
2615                             sizeof(((nvlist_t *)NULL)->nvl_priv));
2616                         value += sizeof(nvlist_t);
2617                 }
2618         }
2619
2620         return (nvs_embedded_nvl_array(nvs, nvp, NULL));
2621 }
2622
2623 static void
2624 nvpair_native_string_array(nvstream_t *nvs, nvpair_t *nvp)
2625 {
2626         switch (nvs->nvs_op) {
2627         case NVS_OP_ENCODE: {
2628                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2629                 uint64_t *strp = (void *)
2630                     (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
2631                 /*
2632                  * Null out pointers that are meaningless in the packed
2633                  * structure. The addresses may not be aligned, so we have
2634                  * to use bzero.
2635                  */
2636                 bzero(strp, NVP_NELEM(nvp) * sizeof (uint64_t));
2637                 break;
2638         }
2639         case NVS_OP_DECODE: {
2640                 char **strp = (void *)NVP_VALUE(nvp);
2641                 char *buf = ((char *)strp + NVP_NELEM(nvp) * sizeof (uint64_t));
2642                 int i;
2643
2644                 for (i = 0; i < NVP_NELEM(nvp); i++) {
2645                         strp[i] = buf;
2646                         buf += strlen(buf) + 1;
2647                 }
2648                 break;
2649         }
2650         }
2651 }
2652
2653 static int
2654 nvs_native_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
2655 {
2656         data_type_t type;
2657         int value_sz;
2658         int ret = 0;
2659
2660         /*
2661          * We do the initial bcopy of the data before we look at
2662          * the nvpair type, because when we're decoding, we won't
2663          * have the correct values for the pair until we do the bcopy.
2664          */
2665         switch (nvs->nvs_op) {
2666         case NVS_OP_ENCODE:
2667         case NVS_OP_DECODE:
2668                 if (native_cp(nvs, nvp, nvp->nvp_size) != 0)
2669                         return (EFAULT);
2670                 break;
2671         default:
2672                 return (EINVAL);
2673         }
2674
2675         /* verify nvp_name_sz, check the name string length */
2676         if (i_validate_nvpair_name(nvp) != 0)
2677                 return (EFAULT);
2678
2679         type = NVP_TYPE(nvp);
2680
2681         /*
2682          * Verify type and nelem and get the value size.
2683          * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
2684          * is the size of the string(s) excluded.
2685          */
2686         if ((value_sz = i_get_value_size(type, NULL, NVP_NELEM(nvp))) < 0)
2687                 return (EFAULT);
2688
2689         if (NVP_SIZE_CALC(nvp->nvp_name_sz, value_sz) > nvp->nvp_size)
2690                 return (EFAULT);
2691
2692         switch (type) {
2693         case DATA_TYPE_NVLIST:
2694                 ret = nvpair_native_embedded(nvs, nvp);
2695                 break;
2696         case DATA_TYPE_NVLIST_ARRAY:
2697                 ret = nvpair_native_embedded_array(nvs, nvp);
2698                 break;
2699         case DATA_TYPE_STRING_ARRAY:
2700                 nvpair_native_string_array(nvs, nvp);
2701                 break;
2702         default:
2703                 break;
2704         }
2705
2706         return (ret);
2707 }
2708
2709 static int
2710 nvs_native_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2711 {
2712         uint64_t nvp_sz = nvp->nvp_size;
2713
2714         switch (NVP_TYPE(nvp)) {
2715         case DATA_TYPE_NVLIST: {
2716                 size_t nvsize = 0;
2717
2718                 if (nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize) != 0)
2719                         return (EINVAL);
2720
2721                 nvp_sz += nvsize;
2722                 break;
2723         }
2724         case DATA_TYPE_NVLIST_ARRAY: {
2725                 size_t nvsize;
2726
2727                 if (nvs_embedded_nvl_array(nvs, nvp, &nvsize) != 0)
2728                         return (EINVAL);
2729
2730                 nvp_sz += nvsize;
2731                 break;
2732         }
2733         default:
2734                 break;
2735         }
2736
2737         if (nvp_sz > INT32_MAX)
2738                 return (EINVAL);
2739
2740         *size = nvp_sz;
2741
2742         return (0);
2743 }
2744
2745 static int
2746 nvs_native_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
2747 {
2748         switch (nvs->nvs_op) {
2749         case NVS_OP_ENCODE:
2750                 return (nvs_native_nvp_op(nvs, nvp));
2751
2752         case NVS_OP_DECODE: {
2753                 nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
2754                 int32_t decode_len;
2755
2756                 /* try to read the size value from the stream */
2757                 if (native->n_curr + sizeof (int32_t) > native->n_end)
2758                         return (EFAULT);
2759                 bcopy(native->n_curr, &decode_len, sizeof (int32_t));
2760
2761                 /* sanity check the size value */
2762                 if (decode_len < 0 ||
2763                     decode_len > native->n_end - native->n_curr)
2764                         return (EFAULT);
2765
2766                 *size = decode_len;
2767
2768                 /*
2769                  * If at the end of the stream then move the cursor
2770                  * forward, otherwise nvpair_native_op() will read
2771                  * the entire nvpair at the same cursor position.
2772                  */
2773                 if (*size == 0)
2774                         native->n_curr += sizeof (int32_t);
2775                 break;
2776         }
2777
2778         default:
2779                 return (EINVAL);
2780         }
2781
2782         return (0);
2783 }
2784
2785 static const nvs_ops_t nvs_native_ops = {
2786         nvs_native_nvlist,
2787         nvs_native_nvpair,
2788         nvs_native_nvp_op,
2789         nvs_native_nvp_size,
2790         nvs_native_nvl_fini
2791 };
2792
2793 static int
2794 nvs_native(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
2795 {
2796         nvs_native_t native;
2797         int err;
2798
2799         nvs->nvs_ops = &nvs_native_ops;
2800
2801         if ((err = nvs_native_create(nvs, &native, buf + sizeof (nvs_header_t),
2802             *buflen - sizeof (nvs_header_t))) != 0)
2803                 return (err);
2804
2805         err = nvs_operation(nvs, nvl, buflen);
2806
2807         nvs_native_destroy(nvs);
2808
2809         return (err);
2810 }
2811
2812 /*
2813  * XDR encoding functions
2814  *
2815  * An xdr packed nvlist is encoded as:
2816  *
2817  *  - encoding methode and host endian (4 bytes)
2818  *  - nvl_version (4 bytes)
2819  *  - nvl_nvflag (4 bytes)
2820  *
2821  *  - encoded nvpairs, the format of one xdr encoded nvpair is:
2822  *      - encoded size of the nvpair (4 bytes)
2823  *      - decoded size of the nvpair (4 bytes)
2824  *      - name string, (4 + sizeof(NV_ALIGN4(string))
2825  *        a string is coded as size (4 bytes) and data
2826  *      - data type (4 bytes)
2827  *      - number of elements in the nvpair (4 bytes)
2828  *      - data
2829  *
2830  *  - 2 zero's for end of the entire list (8 bytes)
2831  */
2832 static int
2833 nvs_xdr_create(nvstream_t *nvs, XDR *xdr, char *buf, size_t buflen)
2834 {
2835         /* xdr data must be 4 byte aligned */
2836         if ((ulong_t)buf % 4 != 0)
2837                 return (EFAULT);
2838
2839         switch (nvs->nvs_op) {
2840         case NVS_OP_ENCODE:
2841                 xdrmem_create(xdr, buf, (uint_t)buflen, XDR_ENCODE);
2842                 nvs->nvs_private = xdr;
2843                 return (0);
2844         case NVS_OP_DECODE:
2845                 xdrmem_create(xdr, buf, (uint_t)buflen, XDR_DECODE);
2846                 nvs->nvs_private = xdr;
2847                 return (0);
2848         case NVS_OP_GETSIZE:
2849                 nvs->nvs_private = NULL;
2850                 return (0);
2851         default:
2852                 return (EINVAL);
2853         }
2854 }
2855
2856 static void
2857 nvs_xdr_destroy(nvstream_t *nvs)
2858 {
2859         switch (nvs->nvs_op) {
2860         case NVS_OP_ENCODE:
2861         case NVS_OP_DECODE:
2862                 xdr_destroy((XDR *)nvs->nvs_private);
2863                 break;
2864         default:
2865                 break;
2866         }
2867 }
2868
2869 static int
2870 nvs_xdr_nvlist(nvstream_t *nvs, nvlist_t *nvl, size_t *size)
2871 {
2872         switch (nvs->nvs_op) {
2873         case NVS_OP_ENCODE:
2874         case NVS_OP_DECODE: {
2875                 XDR     *xdr = nvs->nvs_private;
2876
2877                 if (!xdr_int(xdr, &nvl->nvl_version) ||
2878                     !xdr_u_int(xdr, &nvl->nvl_nvflag))
2879                         return (EFAULT);
2880                 break;
2881         }
2882         case NVS_OP_GETSIZE: {
2883                 /*
2884                  * 2 * 4 for nvl_version + nvl_nvflag
2885                  * and 8 for end of the entire list
2886                  */
2887                 *size += 2 * 4 + 8;
2888                 break;
2889         }
2890         default:
2891                 return (EINVAL);
2892         }
2893         return (0);
2894 }
2895
2896 static int
2897 nvs_xdr_nvl_fini(nvstream_t *nvs)
2898 {
2899         if (nvs->nvs_op == NVS_OP_ENCODE) {
2900                 XDR *xdr = nvs->nvs_private;
2901                 int zero = 0;
2902
2903                 if (!xdr_int(xdr, &zero) || !xdr_int(xdr, &zero))
2904                         return (EFAULT);
2905         }
2906
2907         return (0);
2908 }
2909
2910 /*
2911  * The format of xdr encoded nvpair is:
2912  * encode_size, decode_size, name string, data type, nelem, data
2913  */
2914 static int
2915 nvs_xdr_nvp_op(nvstream_t *nvs, nvpair_t *nvp)
2916 {
2917         data_type_t type;
2918         char    *buf;
2919         char    *buf_end = (char *)nvp + nvp->nvp_size;
2920         int     value_sz;
2921         uint_t  nelem, buflen;
2922         bool_t  ret = FALSE;
2923         XDR     *xdr = nvs->nvs_private;
2924
2925         ASSERT(xdr != NULL && nvp != NULL);
2926
2927         /* name string */
2928         if ((buf = NVP_NAME(nvp)) >= buf_end)
2929                 return (EFAULT);
2930         buflen = buf_end - buf;
2931
2932         if (!xdr_string(xdr, &buf, buflen - 1))
2933                 return (EFAULT);
2934         nvp->nvp_name_sz = strlen(buf) + 1;
2935
2936         /* type and nelem */
2937         if (!xdr_int(xdr, (int *)&nvp->nvp_type) ||
2938             !xdr_int(xdr, &nvp->nvp_value_elem))
2939                 return (EFAULT);
2940
2941         type = NVP_TYPE(nvp);
2942         nelem = nvp->nvp_value_elem;
2943
2944         /*
2945          * Verify type and nelem and get the value size.
2946          * In case of data types DATA_TYPE_STRING and DATA_TYPE_STRING_ARRAY
2947          * is the size of the string(s) excluded.
2948          */
2949         if ((value_sz = i_get_value_size(type, NULL, nelem)) < 0)
2950                 return (EFAULT);
2951
2952         /* if there is no data to extract then return */
2953         if (nelem == 0)
2954                 return (0);
2955
2956         /* value */
2957         if ((buf = NVP_VALUE(nvp)) >= buf_end)
2958                 return (EFAULT);
2959         buflen = buf_end - buf;
2960
2961         if (buflen < value_sz)
2962                 return (EFAULT);
2963
2964         switch (type) {
2965         case DATA_TYPE_NVLIST:
2966                 if (nvs_embedded(nvs, (void *)buf) == 0)
2967                         return (0);
2968                 break;
2969
2970         case DATA_TYPE_NVLIST_ARRAY:
2971                 if (nvs_embedded_nvl_array(nvs, nvp, NULL) == 0)
2972                         return (0);
2973                 break;
2974
2975         case DATA_TYPE_BOOLEAN:
2976                 ret = TRUE;
2977                 break;
2978
2979         case DATA_TYPE_BYTE:
2980         case DATA_TYPE_INT8:
2981         case DATA_TYPE_UINT8:
2982                 ret = xdr_char(xdr, buf);
2983                 break;
2984
2985         case DATA_TYPE_INT16:
2986                 ret = xdr_short(xdr, (void *)buf);
2987                 break;
2988
2989         case DATA_TYPE_UINT16:
2990                 ret = xdr_u_short(xdr, (void *)buf);
2991                 break;
2992
2993         case DATA_TYPE_BOOLEAN_VALUE:
2994         case DATA_TYPE_INT32:
2995                 ret = xdr_int(xdr, (void *)buf);
2996                 break;
2997
2998         case DATA_TYPE_UINT32:
2999                 ret = xdr_u_int(xdr, (void *)buf);
3000                 break;
3001
3002         case DATA_TYPE_INT64:
3003                 ret = xdr_longlong_t(xdr, (void *)buf);
3004                 break;
3005
3006         case DATA_TYPE_UINT64:
3007                 ret = xdr_u_longlong_t(xdr, (void *)buf);
3008                 break;
3009
3010         case DATA_TYPE_HRTIME:
3011                 /*
3012                  * NOTE: must expose the definition of hrtime_t here
3013                  */
3014                 ret = xdr_longlong_t(xdr, (void *)buf);
3015                 break;
3016 #if !defined(_KERNEL)
3017         case DATA_TYPE_DOUBLE:
3018                 ret = xdr_double(xdr, (void *)buf);
3019                 break;
3020 #endif
3021         case DATA_TYPE_STRING:
3022                 ret = xdr_string(xdr, &buf, buflen - 1);
3023                 break;
3024
3025         case DATA_TYPE_BYTE_ARRAY:
3026                 ret = xdr_opaque(xdr, buf, nelem);
3027                 break;
3028
3029         case DATA_TYPE_INT8_ARRAY:
3030         case DATA_TYPE_UINT8_ARRAY:
3031                 ret = xdr_array(xdr, &buf, &nelem, buflen, sizeof (int8_t),
3032                     (xdrproc_t)xdr_char);
3033                 break;
3034
3035         case DATA_TYPE_INT16_ARRAY:
3036                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int16_t),
3037                     sizeof (int16_t), (xdrproc_t)xdr_short);
3038                 break;
3039
3040         case DATA_TYPE_UINT16_ARRAY:
3041                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint16_t),
3042                     sizeof (uint16_t), (xdrproc_t)xdr_u_short);
3043                 break;
3044
3045         case DATA_TYPE_BOOLEAN_ARRAY:
3046         case DATA_TYPE_INT32_ARRAY:
3047                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int32_t),
3048                     sizeof (int32_t), (xdrproc_t)xdr_int);
3049                 break;
3050
3051         case DATA_TYPE_UINT32_ARRAY:
3052                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint32_t),
3053                     sizeof (uint32_t), (xdrproc_t)xdr_u_int);
3054                 break;
3055
3056         case DATA_TYPE_INT64_ARRAY:
3057                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (int64_t),
3058                     sizeof (int64_t), (xdrproc_t)xdr_longlong_t);
3059                 break;
3060
3061         case DATA_TYPE_UINT64_ARRAY:
3062                 ret = xdr_array(xdr, &buf, &nelem, buflen / sizeof (uint64_t),
3063                     sizeof (uint64_t), (xdrproc_t)xdr_u_longlong_t);
3064                 break;
3065
3066         case DATA_TYPE_STRING_ARRAY: {
3067                 size_t len = nelem * sizeof (uint64_t);
3068                 char **strp = (void *)buf;
3069                 int i;
3070
3071                 if (nvs->nvs_op == NVS_OP_DECODE)
3072                         bzero(buf, len);        /* don't trust packed data */
3073
3074                 for (i = 0; i < nelem; i++) {
3075                         if (buflen <= len)
3076                                 return (EFAULT);
3077
3078                         buf += len;
3079                         buflen -= len;
3080
3081                         if (xdr_string(xdr, &buf, buflen - 1) != TRUE)
3082                                 return (EFAULT);
3083
3084                         if (nvs->nvs_op == NVS_OP_DECODE)
3085                                 strp[i] = buf;
3086                         len = strlen(buf) + 1;
3087                 }
3088                 ret = TRUE;
3089                 break;
3090         }
3091         default:
3092                 break;
3093         }
3094
3095         return (ret == TRUE ? 0 : EFAULT);
3096 }
3097
3098 static int
3099 nvs_xdr_nvp_size(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3100 {
3101         data_type_t type = NVP_TYPE(nvp);
3102         /*
3103          * encode_size + decode_size + name string size + data type + nelem
3104          * where name string size = 4 + NV_ALIGN4(strlen(NVP_NAME(nvp)))
3105          */
3106         uint64_t nvp_sz = 4 + 4 + 4 + NV_ALIGN4(strlen(NVP_NAME(nvp))) + 4 + 4;
3107
3108         switch (type) {
3109         case DATA_TYPE_BOOLEAN:
3110                 break;
3111
3112         case DATA_TYPE_BOOLEAN_VALUE:
3113         case DATA_TYPE_BYTE:
3114         case DATA_TYPE_INT8:
3115         case DATA_TYPE_UINT8:
3116         case DATA_TYPE_INT16:
3117         case DATA_TYPE_UINT16:
3118         case DATA_TYPE_INT32:
3119         case DATA_TYPE_UINT32:
3120                 nvp_sz += 4;    /* 4 is the minimum xdr unit */
3121                 break;
3122
3123         case DATA_TYPE_INT64:
3124         case DATA_TYPE_UINT64:
3125         case DATA_TYPE_HRTIME:
3126 #if !defined(_KERNEL)
3127         case DATA_TYPE_DOUBLE:
3128 #endif
3129                 nvp_sz += 8;
3130                 break;
3131
3132         case DATA_TYPE_STRING:
3133                 nvp_sz += 4 + NV_ALIGN4(strlen((char *)NVP_VALUE(nvp)));
3134                 break;
3135
3136         case DATA_TYPE_BYTE_ARRAY:
3137                 nvp_sz += NV_ALIGN4(NVP_NELEM(nvp));
3138                 break;
3139
3140         case DATA_TYPE_BOOLEAN_ARRAY:
3141         case DATA_TYPE_INT8_ARRAY:
3142         case DATA_TYPE_UINT8_ARRAY:
3143         case DATA_TYPE_INT16_ARRAY:
3144         case DATA_TYPE_UINT16_ARRAY:
3145         case DATA_TYPE_INT32_ARRAY:
3146         case DATA_TYPE_UINT32_ARRAY:
3147                 nvp_sz += 4 + 4 * (uint64_t)NVP_NELEM(nvp);
3148                 break;
3149
3150         case DATA_TYPE_INT64_ARRAY:
3151         case DATA_TYPE_UINT64_ARRAY:
3152                 nvp_sz += 4 + 8 * (uint64_t)NVP_NELEM(nvp);
3153                 break;
3154
3155         case DATA_TYPE_STRING_ARRAY: {
3156                 int i;
3157                 char **strs = (void *)NVP_VALUE(nvp);
3158
3159                 for (i = 0; i < NVP_NELEM(nvp); i++)
3160                         nvp_sz += 4 + NV_ALIGN4(strlen(strs[i]));
3161
3162                 break;
3163         }
3164
3165         case DATA_TYPE_NVLIST:
3166         case DATA_TYPE_NVLIST_ARRAY: {
3167                 size_t nvsize = 0;
3168                 int old_nvs_op = nvs->nvs_op;
3169                 int err;
3170
3171                 nvs->nvs_op = NVS_OP_GETSIZE;
3172                 if (type == DATA_TYPE_NVLIST)
3173                         err = nvs_operation(nvs, EMBEDDED_NVL(nvp), &nvsize);
3174                 else
3175                         err = nvs_embedded_nvl_array(nvs, nvp, &nvsize);
3176                 nvs->nvs_op = old_nvs_op;
3177
3178                 if (err != 0)
3179                         return (EINVAL);
3180
3181                 nvp_sz += nvsize;
3182                 break;
3183         }
3184
3185         default:
3186                 return (EINVAL);
3187         }
3188
3189         if (nvp_sz > INT32_MAX)
3190                 return (EINVAL);
3191
3192         *size = nvp_sz;
3193
3194         return (0);
3195 }
3196
3197
3198 /*
3199  * The NVS_XDR_MAX_LEN macro takes a packed xdr buffer of size x and estimates
3200  * the largest nvpair that could be encoded in the buffer.
3201  *
3202  * See comments above nvpair_xdr_op() for the format of xdr encoding.
3203  * The size of a xdr packed nvpair without any data is 5 words.
3204  *
3205  * Using the size of the data directly as an estimate would be ok
3206  * in all cases except one.  If the data type is of DATA_TYPE_STRING_ARRAY
3207  * then the actual nvpair has space for an array of pointers to index
3208  * the strings.  These pointers are not encoded into the packed xdr buffer.
3209  *
3210  * If the data is of type DATA_TYPE_STRING_ARRAY and all the strings are
3211  * of length 0, then each string is endcoded in xdr format as a single word.
3212  * Therefore when expanded to an nvpair there will be 2.25 word used for
3213  * each string.  (a int64_t allocated for pointer usage, and a single char
3214  * for the null termination.)
3215  *
3216  * This is the calculation performed by the NVS_XDR_MAX_LEN macro.
3217  */
3218 #define NVS_XDR_HDR_LEN         ((size_t)(5 * 4))
3219 #define NVS_XDR_DATA_LEN(y)     (((size_t)(y) <= NVS_XDR_HDR_LEN) ? \
3220                                         0 : ((size_t)(y) - NVS_XDR_HDR_LEN))
3221 #define NVS_XDR_MAX_LEN(x)      (NVP_SIZE_CALC(1, 0) + \
3222                                         (NVS_XDR_DATA_LEN(x) * 2) + \
3223                                         NV_ALIGN4((NVS_XDR_DATA_LEN(x) / 4)))
3224
3225 static int
3226 nvs_xdr_nvpair(nvstream_t *nvs, nvpair_t *nvp, size_t *size)
3227 {
3228         XDR     *xdr = nvs->nvs_private;
3229         int32_t encode_len, decode_len;
3230
3231         switch (nvs->nvs_op) {
3232         case NVS_OP_ENCODE: {
3233                 size_t nvsize;
3234
3235                 if (nvs_xdr_nvp_size(nvs, nvp, &nvsize) != 0)
3236                         return (EFAULT);
3237
3238                 decode_len = nvp->nvp_size;
3239                 encode_len = nvsize;
3240                 if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
3241                         return (EFAULT);
3242
3243                 return (nvs_xdr_nvp_op(nvs, nvp));
3244         }
3245         case NVS_OP_DECODE: {
3246                 struct xdr_bytesrec bytesrec;
3247
3248                 /* get the encode and decode size */
3249                 if (!xdr_int(xdr, &encode_len) || !xdr_int(xdr, &decode_len))
3250                         return (EFAULT);
3251                 *size = decode_len;
3252
3253                 /* are we at the end of the stream? */
3254                 if (*size == 0)
3255                         return (0);
3256
3257                 /* sanity check the size parameter */
3258                 if (!xdr_control(xdr, XDR_GET_BYTES_AVAIL, &bytesrec))
3259                         return (EFAULT);
3260
3261                 if (*size > NVS_XDR_MAX_LEN(bytesrec.xc_num_avail))
3262                         return (EFAULT);
3263                 break;
3264         }
3265
3266         default:
3267                 return (EINVAL);
3268         }
3269         return (0);
3270 }
3271
3272 static const struct nvs_ops nvs_xdr_ops = {
3273         nvs_xdr_nvlist,
3274         nvs_xdr_nvpair,
3275         nvs_xdr_nvp_op,
3276         nvs_xdr_nvp_size,
3277         nvs_xdr_nvl_fini
3278 };
3279
3280 static int
3281 nvs_xdr(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
3282 {
3283         XDR xdr;
3284         int err;
3285
3286         nvs->nvs_ops = &nvs_xdr_ops;
3287
3288         if ((err = nvs_xdr_create(nvs, &xdr, buf + sizeof (nvs_header_t),
3289             *buflen - sizeof (nvs_header_t))) != 0)
3290                 return (err);
3291
3292         err = nvs_operation(nvs, nvl, buflen);
3293
3294         nvs_xdr_destroy(nvs);
3295
3296         return (err);
3297 }