17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*39b361b2SRichard Bean * Common Development and Distribution License (the "License").
6*39b361b2SRichard Bean * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*39b361b2SRichard Bean * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/systm.h>
287c478bd9Sstevel@tonic-gate #include <sys/socket.h>
297c478bd9Sstevel@tonic-gate #include <netinet/in.h>
307c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
317c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
327c478bd9Sstevel@tonic-gate #include <ipp/ipp.h>
337c478bd9Sstevel@tonic-gate #include <ipp/ipp_config.h>
347c478bd9Sstevel@tonic-gate #include <inet/common.h>
357c478bd9Sstevel@tonic-gate #include <ipp/dscpmk/dscpmk_impl.h>
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate #define D_SM_COMMENT "IPP dscpmk marker module"
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate /* DDI file for dscpmk ipp module */
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /* default dscp map - dscp unchanged */
427c478bd9Sstevel@tonic-gate uint8_t default_dscp_map[DSCPMK_ARRAY_COUNT] = {
437c478bd9Sstevel@tonic-gate 0, 1, 2, 3,
447c478bd9Sstevel@tonic-gate 4, 5, 6, 7,
457c478bd9Sstevel@tonic-gate 8, 9, 10, 11,
467c478bd9Sstevel@tonic-gate 12, 13, 14, 15,
477c478bd9Sstevel@tonic-gate 16, 17, 18, 19,
487c478bd9Sstevel@tonic-gate 20, 21, 22, 23,
497c478bd9Sstevel@tonic-gate 24, 25, 26, 27,
507c478bd9Sstevel@tonic-gate 28, 29, 30, 31,
517c478bd9Sstevel@tonic-gate 32, 33, 34, 35,
527c478bd9Sstevel@tonic-gate 36, 37, 38, 39,
537c478bd9Sstevel@tonic-gate 40, 41, 42, 43,
547c478bd9Sstevel@tonic-gate 44, 45, 46, 47,
557c478bd9Sstevel@tonic-gate 48, 49, 50, 51,
567c478bd9Sstevel@tonic-gate 52, 53, 54, 55,
577c478bd9Sstevel@tonic-gate 56, 57, 58, 59,
587c478bd9Sstevel@tonic-gate 60, 61, 62, 63
597c478bd9Sstevel@tonic-gate };
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate static int dscpmk_create_action(ipp_action_id_t, nvlist_t **, ipp_flags_t);
627c478bd9Sstevel@tonic-gate static int dscpmk_modify_action(ipp_action_id_t, nvlist_t **, ipp_flags_t);
637c478bd9Sstevel@tonic-gate static int dscpmk_destroy_action(ipp_action_id_t, ipp_flags_t);
647c478bd9Sstevel@tonic-gate static int dscpmk_info(ipp_action_id_t, int (*)(nvlist_t *, void *), void *,
657c478bd9Sstevel@tonic-gate ipp_flags_t);
667c478bd9Sstevel@tonic-gate static int dscpmk_invoke_action(ipp_action_id_t, ipp_packet_t *);
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate /* Creating and updating summary stats */
697c478bd9Sstevel@tonic-gate static int dscpmk_summ_statinit(ipp_action_id_t, dscpmk_data_t *);
707c478bd9Sstevel@tonic-gate static int dscpmk_update_stats(ipp_stat_t *, void *, int);
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate /* Creating and updating per-dscp stats */
737c478bd9Sstevel@tonic-gate static int dscpmk_det_statinit(ipp_action_id_t, dscpmk_data_t *, int);
747c478bd9Sstevel@tonic-gate static int dscpmk_update_det_stats(ipp_stat_t *, void *, int);
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate /* Entry points for this IPP module */
777c478bd9Sstevel@tonic-gate ipp_ops_t dscpmk_ops = {
787c478bd9Sstevel@tonic-gate IPPO_REV,
797c478bd9Sstevel@tonic-gate dscpmk_create_action, /* ippo_action_create */
807c478bd9Sstevel@tonic-gate dscpmk_modify_action, /* ippo_action_modify */
817c478bd9Sstevel@tonic-gate dscpmk_destroy_action, /* ippo_action_destroy */
827c478bd9Sstevel@tonic-gate dscpmk_info, /* ippo_action_info */
837c478bd9Sstevel@tonic-gate dscpmk_invoke_action /* ippo_action_invoke */
847c478bd9Sstevel@tonic-gate };
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate extern struct mod_ops mod_ippops;
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate * Module linkage information for the kernel.
907c478bd9Sstevel@tonic-gate */
917c478bd9Sstevel@tonic-gate static struct modlipp modlipp = {
927c478bd9Sstevel@tonic-gate &mod_ippops,
93*39b361b2SRichard Bean D_SM_COMMENT,
947c478bd9Sstevel@tonic-gate &dscpmk_ops
957c478bd9Sstevel@tonic-gate };
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
987c478bd9Sstevel@tonic-gate MODREV_1,
997c478bd9Sstevel@tonic-gate (void *)&modlipp,
1007c478bd9Sstevel@tonic-gate NULL
1017c478bd9Sstevel@tonic-gate };
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate int
_init(void)1057c478bd9Sstevel@tonic-gate _init(void)
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage));
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate int
_fini(void)1117c478bd9Sstevel@tonic-gate _fini(void)
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate return (mod_remove(&modlinkage));
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate int
_info(struct modinfo * modinfop)1177c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
1187c478bd9Sstevel@tonic-gate {
1197c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop));
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate static int
dscpmk_create_action(ipp_action_id_t aid,nvlist_t ** nvlpp,ipp_flags_t flags)1237c478bd9Sstevel@tonic-gate dscpmk_create_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags)
1247c478bd9Sstevel@tonic-gate {
1257c478bd9Sstevel@tonic-gate nvlist_t *nvlp;
1267c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data;
1277c478bd9Sstevel@tonic-gate char *next_action;
1287c478bd9Sstevel@tonic-gate int err, cnt;
1297c478bd9Sstevel@tonic-gate int32_t *tbl;
1307c478bd9Sstevel@tonic-gate uint_t nelem = DSCPMK_ARRAY_COUNT;
1317c478bd9Sstevel@tonic-gate uint32_t bstats;
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate ASSERT((nvlpp != NULL) && (*nvlpp != NULL));
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate nvlp = *nvlpp;
1367c478bd9Sstevel@tonic-gate *nvlpp = NULL; /* nvlist should be NULL on return */
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate if ((dscpmk_data = kmem_zalloc(DSCPMK_DATA_SZ, KM_NOSLEEP)) == NULL) {
1397c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
1407c478bd9Sstevel@tonic-gate return (ENOMEM);
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /* parse next action name */
1447c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_string(nvlp, DSCPMK_NEXT_ACTION_NAME,
1457c478bd9Sstevel@tonic-gate &next_action)) != 0) {
1467c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
1477c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_create_action: invalid config, " \
1487c478bd9Sstevel@tonic-gate "next_action name missing\n"));
1497c478bd9Sstevel@tonic-gate kmem_free(dscpmk_data, DSCPMK_DATA_SZ);
1507c478bd9Sstevel@tonic-gate return (err);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate if ((dscpmk_data->next_action = ipp_action_lookup(next_action))
1547c478bd9Sstevel@tonic-gate == IPP_ACTION_INVAL) {
1557c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
1567c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_create_action: next_action "\
1577c478bd9Sstevel@tonic-gate "invalid\n"));
1587c478bd9Sstevel@tonic-gate kmem_free(dscpmk_data, DSCPMK_DATA_SZ);
1597c478bd9Sstevel@tonic-gate return (EINVAL);
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate /* Fill in the default value */
1637c478bd9Sstevel@tonic-gate bcopy(default_dscp_map, dscpmk_data->dscp_map,
1647c478bd9Sstevel@tonic-gate sizeof (default_dscp_map));
1657c478bd9Sstevel@tonic-gate /*
1667c478bd9Sstevel@tonic-gate * parse dscp_map, if present. Note that the module gets
1677c478bd9Sstevel@tonic-gate * the entire array with unchanged entries marked with -1.
1687c478bd9Sstevel@tonic-gate */
1697c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_int32_array(nvlp, DSCPMK_DSCP_MAP,
1707c478bd9Sstevel@tonic-gate &tbl, &nelem)) == 0) {
1717c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
1727c478bd9Sstevel@tonic-gate if ((tbl[cnt] != DSCPMK_UNCHANGED_DSCP) && (tbl[cnt] !=
1737c478bd9Sstevel@tonic-gate dscpmk_data->dscp_map[cnt])) {
1747c478bd9Sstevel@tonic-gate dscpmk_data->dscp_map[cnt] = tbl[cnt];
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate /* parse summary_stats boolean */
1817c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats))
1827c478bd9Sstevel@tonic-gate != 0) {
1837c478bd9Sstevel@tonic-gate dscpmk_data->summary_stats = B_FALSE;
1847c478bd9Sstevel@tonic-gate } else {
1857c478bd9Sstevel@tonic-gate dscpmk_data->summary_stats = (bstats != 0) ? B_TRUE : B_FALSE;
1867c478bd9Sstevel@tonic-gate /* If stats is needed, initialize the stats structure */
1877c478bd9Sstevel@tonic-gate if (dscpmk_data->summary_stats) {
1887c478bd9Sstevel@tonic-gate if ((err = dscpmk_summ_statinit(aid, dscpmk_data))
1897c478bd9Sstevel@tonic-gate != 0) {
1907c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
1917c478bd9Sstevel@tonic-gate kmem_free(dscpmk_data, DSCPMK_DATA_SZ);
1927c478bd9Sstevel@tonic-gate return (err);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate }
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate /*
1987c478bd9Sstevel@tonic-gate * Initialize per-dscp stats; B_FALSE in present indicates a dscp
1997c478bd9Sstevel@tonic-gate * with this value (count) is not present in the map.
2007c478bd9Sstevel@tonic-gate */
2017c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
2027c478bd9Sstevel@tonic-gate dscpmk_data->dscp_stats[cnt].present = B_FALSE;
2037c478bd9Sstevel@tonic-gate dscpmk_data->dscp_stats[cnt].npackets = 0;
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate /* parse detailed_stats boolean */
2077c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, DSCPMK_DETAILED_STATS, &bstats))
2087c478bd9Sstevel@tonic-gate != 0) {
2097c478bd9Sstevel@tonic-gate dscpmk_data->detailed_stats = B_FALSE;
2107c478bd9Sstevel@tonic-gate } else {
2117c478bd9Sstevel@tonic-gate dscpmk_data->detailed_stats = (bstats != 0) ? B_TRUE : B_FALSE;
2127c478bd9Sstevel@tonic-gate /* If stats is needed, initialize the stats structure */
2137c478bd9Sstevel@tonic-gate if (dscpmk_data->detailed_stats) {
2147c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
2157c478bd9Sstevel@tonic-gate int val = dscpmk_data->dscp_map[cnt];
2167c478bd9Sstevel@tonic-gate if (dscpmk_data->dscp_stats[val].present) {
2177c478bd9Sstevel@tonic-gate continue;
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate dscpmk_data->dscp_stats[val].present = B_TRUE;
2207c478bd9Sstevel@tonic-gate if ((err = dscpmk_det_statinit(aid, dscpmk_data,
2217c478bd9Sstevel@tonic-gate val)) != 0) {
2227c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
2237c478bd9Sstevel@tonic-gate kmem_free(dscpmk_data, DSCPMK_DATA_SZ);
2247c478bd9Sstevel@tonic-gate return (err);
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate /* Free the nvlist */
2317c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate /* set action chain reference */
2347c478bd9Sstevel@tonic-gate if ((err = ipp_action_ref(aid, dscpmk_data->next_action, flags)) != 0) {
2357c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_create_action: ipp_action_ref " \
2367c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
2377c478bd9Sstevel@tonic-gate if (dscpmk_data->summary_stats) {
2387c478bd9Sstevel@tonic-gate ipp_stat_destroy(dscpmk_data->stats);
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate if (dscpmk_data->detailed_stats) {
2417c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
2427c478bd9Sstevel@tonic-gate if (dscpmk_data->dscp_stats[cnt].present) {
2437c478bd9Sstevel@tonic-gate ipp_stat_destroy(
2447c478bd9Sstevel@tonic-gate dscpmk_data->dscp_stats[cnt].stats);
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate kmem_free(dscpmk_data, DSCPMK_DATA_SZ);
2497c478bd9Sstevel@tonic-gate return (err);
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate ipp_action_set_ptr(aid, (void *)dscpmk_data);
2537c478bd9Sstevel@tonic-gate return (0);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate static int
dscpmk_modify_action(ipp_action_id_t aid,nvlist_t ** nvlpp,ipp_flags_t flags)2577c478bd9Sstevel@tonic-gate dscpmk_modify_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags)
2587c478bd9Sstevel@tonic-gate {
2597c478bd9Sstevel@tonic-gate nvlist_t *nvlp;
2607c478bd9Sstevel@tonic-gate int err = 0, cnt;
2617c478bd9Sstevel@tonic-gate uint8_t config_type;
2627c478bd9Sstevel@tonic-gate char *next_action_name;
2637c478bd9Sstevel@tonic-gate uint32_t bstats;
2647c478bd9Sstevel@tonic-gate uint_t nelem = DSCPMK_ARRAY_COUNT;
2657c478bd9Sstevel@tonic-gate int32_t *tbl;
2667c478bd9Sstevel@tonic-gate ipp_action_id_t next_action;
2677c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data;
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate ASSERT((nvlpp != NULL) && (*nvlpp != NULL));
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate nvlp = *nvlpp;
2727c478bd9Sstevel@tonic-gate *nvlpp = NULL; /* nvlist should be NULL when this returns */
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_byte(nvlp, IPP_CONFIG_TYPE, &config_type))
2757c478bd9Sstevel@tonic-gate != 0) {
2767c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
2777c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_modify_action: invalid cfg. type\n"));
2787c478bd9Sstevel@tonic-gate return (err);
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate if (config_type != IPP_SET) {
2827c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
2837c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_modify_action: invalid cfg. type " \
2847c478bd9Sstevel@tonic-gate "%d\n", config_type));
2857c478bd9Sstevel@tonic-gate return (EINVAL);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate dscpmk_data = (dscpmk_data_t *)ipp_action_get_ptr(aid);
2897c478bd9Sstevel@tonic-gate ASSERT(dscpmk_data != NULL);
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate /* parse next action name, if present */
2927c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_string(nvlp, DSCPMK_NEXT_ACTION_NAME,
2937c478bd9Sstevel@tonic-gate &next_action_name)) == 0) {
2947c478bd9Sstevel@tonic-gate /* lookup action name to get action id */
2957c478bd9Sstevel@tonic-gate if ((next_action = ipp_action_lookup(next_action_name))
2967c478bd9Sstevel@tonic-gate == IPP_ACTION_INVAL) {
2977c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
2987c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_modify_action: next_action "\
2997c478bd9Sstevel@tonic-gate "invalid\n"));
3007c478bd9Sstevel@tonic-gate return (EINVAL);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate /* reference new action */
3037c478bd9Sstevel@tonic-gate if ((err = ipp_action_ref(aid, next_action, flags)) != 0) {
3047c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
3057c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_modify_action: ipp_action_ref " \
3067c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
3077c478bd9Sstevel@tonic-gate return (err);
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate /* unref old action */
3107c478bd9Sstevel@tonic-gate err = ipp_action_unref(aid, dscpmk_data->next_action, flags);
3117c478bd9Sstevel@tonic-gate ASSERT(err == 0);
3127c478bd9Sstevel@tonic-gate dscpmk_data->next_action = next_action;
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate /*
3167c478bd9Sstevel@tonic-gate * parse dscp_map, if present. Note that the module gets
3177c478bd9Sstevel@tonic-gate * the entire array with unchanged entries marked with -1.
3187c478bd9Sstevel@tonic-gate * If this array is absent during modification, it means revert to
3197c478bd9Sstevel@tonic-gate * the default table.
3207c478bd9Sstevel@tonic-gate */
3217c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_int32_array(nvlp, DSCPMK_DSCP_MAP,
3227c478bd9Sstevel@tonic-gate &tbl, &nelem)) == 0) {
3237c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
3247c478bd9Sstevel@tonic-gate if ((tbl[cnt] != DSCPMK_UNCHANGED_DSCP) && (tbl[cnt] !=
3257c478bd9Sstevel@tonic-gate dscpmk_data->dscp_map[cnt])) {
3267c478bd9Sstevel@tonic-gate dscpmk_data->dscp_map[cnt] = tbl[cnt];
3277c478bd9Sstevel@tonic-gate }
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate } else {
3307c478bd9Sstevel@tonic-gate bcopy(default_dscp_map, dscpmk_data->dscp_map,
3317c478bd9Sstevel@tonic-gate sizeof (default_dscp_map));
3327c478bd9Sstevel@tonic-gate }
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate /* parse summary_stats boolean, if present */
3357c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats))
3367c478bd9Sstevel@tonic-gate == 0) {
3377c478bd9Sstevel@tonic-gate boolean_t val = (bstats != 0) ? B_TRUE : B_FALSE;
3387c478bd9Sstevel@tonic-gate /* Turning on stats */
3397c478bd9Sstevel@tonic-gate if (!dscpmk_data->summary_stats && val) {
3407c478bd9Sstevel@tonic-gate if ((err = dscpmk_summ_statinit(aid, dscpmk_data))
3417c478bd9Sstevel@tonic-gate != 0) {
3427c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
3437c478bd9Sstevel@tonic-gate return (err);
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate /* Turning off stats */
3467c478bd9Sstevel@tonic-gate } else if (!val && dscpmk_data->summary_stats) {
3477c478bd9Sstevel@tonic-gate ipp_stat_destroy(dscpmk_data->stats);
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate }
3507c478bd9Sstevel@tonic-gate dscpmk_data->summary_stats = val;
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate /* parse detailed_stats boolean */
3547c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, DSCPMK_DETAILED_STATS, &bstats))
3557c478bd9Sstevel@tonic-gate == 0) {
3567c478bd9Sstevel@tonic-gate boolean_t val = (bstats != 0) ? B_TRUE : B_FALSE;
3577c478bd9Sstevel@tonic-gate if (dscpmk_data->detailed_stats && !val) {
3587c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
3597c478bd9Sstevel@tonic-gate if (dscpmk_data->dscp_stats[cnt].present) {
3607c478bd9Sstevel@tonic-gate dscpmk_data->dscp_stats[cnt].present =
3617c478bd9Sstevel@tonic-gate B_FALSE;
3627c478bd9Sstevel@tonic-gate ipp_stat_destroy(dscpmk_data->
3637c478bd9Sstevel@tonic-gate dscp_stats[cnt].stats);
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate }
3677c478bd9Sstevel@tonic-gate dscpmk_data->detailed_stats = val;
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate /* The map might have changed */
3717c478bd9Sstevel@tonic-gate if (dscpmk_data->detailed_stats) {
3727c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
3737c478bd9Sstevel@tonic-gate int val = dscpmk_data->dscp_map[cnt];
3747c478bd9Sstevel@tonic-gate if (!dscpmk_data->dscp_stats[val].present) {
3757c478bd9Sstevel@tonic-gate dscpmk_data->dscp_stats[val].present = B_TRUE;
3767c478bd9Sstevel@tonic-gate if ((err = dscpmk_det_statinit(aid, dscpmk_data,
3777c478bd9Sstevel@tonic-gate val)) != 0) {
3787c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
3797c478bd9Sstevel@tonic-gate return (err);
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate /* Free the nvlist */
3867c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
3877c478bd9Sstevel@tonic-gate return (0);
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate static int
dscpmk_destroy_action(ipp_action_id_t aid,ipp_flags_t flags)3917c478bd9Sstevel@tonic-gate dscpmk_destroy_action(ipp_action_id_t aid, ipp_flags_t flags)
3927c478bd9Sstevel@tonic-gate {
3937c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data;
3947c478bd9Sstevel@tonic-gate int err, cnt;
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate dscpmk_data = (dscpmk_data_t *)ipp_action_get_ptr(aid);
3977c478bd9Sstevel@tonic-gate ASSERT(dscpmk_data != NULL);
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate /* Destroy stats, if gathered */
4007c478bd9Sstevel@tonic-gate if (dscpmk_data->summary_stats) {
4017c478bd9Sstevel@tonic-gate ipp_stat_destroy(dscpmk_data->stats);
4027c478bd9Sstevel@tonic-gate }
4037c478bd9Sstevel@tonic-gate
4047c478bd9Sstevel@tonic-gate if (dscpmk_data->detailed_stats) {
4057c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
4067c478bd9Sstevel@tonic-gate if (dscpmk_data->dscp_stats[cnt].present) {
4077c478bd9Sstevel@tonic-gate ipp_stat_destroy(dscpmk_data->dscp_stats[cnt].
4087c478bd9Sstevel@tonic-gate stats);
4097c478bd9Sstevel@tonic-gate }
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate
4137c478bd9Sstevel@tonic-gate /* unreference the action */
4147c478bd9Sstevel@tonic-gate err = ipp_action_unref(aid, dscpmk_data->next_action, flags);
4157c478bd9Sstevel@tonic-gate ASSERT(err == 0);
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate kmem_free(dscpmk_data, DSCPMK_DATA_SZ);
4187c478bd9Sstevel@tonic-gate return (0);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate static int
dscpmk_invoke_action(ipp_action_id_t aid,ipp_packet_t * packet)4227c478bd9Sstevel@tonic-gate dscpmk_invoke_action(ipp_action_id_t aid, ipp_packet_t *packet)
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data;
4257c478bd9Sstevel@tonic-gate mblk_t *mp = NULL;
4267c478bd9Sstevel@tonic-gate ip_priv_t *priv;
4277c478bd9Sstevel@tonic-gate int err;
4287c478bd9Sstevel@tonic-gate
4297c478bd9Sstevel@tonic-gate ASSERT(packet != NULL);
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate /* get mblk from ipp_packet structure */
4327c478bd9Sstevel@tonic-gate mp = ipp_packet_get_data(packet);
4337c478bd9Sstevel@tonic-gate priv = (ip_priv_t *)ipp_packet_get_private(packet);
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate dscpmk_data = (dscpmk_data_t *)ipp_action_get_ptr(aid);
4367c478bd9Sstevel@tonic-gate ASSERT(dscpmk_data != NULL);
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate /* dscpmk packet as configured */
4397c478bd9Sstevel@tonic-gate if ((err = dscpmk_process(&mp, dscpmk_data, priv->proc)) != 0) {
4407c478bd9Sstevel@tonic-gate return (err);
4417c478bd9Sstevel@tonic-gate } else {
4427c478bd9Sstevel@tonic-gate /* return packet with next action set */
4437c478bd9Sstevel@tonic-gate return (ipp_packet_next(packet, dscpmk_data->next_action));
4447c478bd9Sstevel@tonic-gate }
4457c478bd9Sstevel@tonic-gate }
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate static int
dscpmk_det_statinit(ipp_action_id_t aid,dscpmk_data_t * dscpmk_data,int val)4487c478bd9Sstevel@tonic-gate dscpmk_det_statinit(ipp_action_id_t aid, dscpmk_data_t *dscpmk_data, int val)
4497c478bd9Sstevel@tonic-gate {
4507c478bd9Sstevel@tonic-gate int err = 0;
4517c478bd9Sstevel@tonic-gate dscpmk_dscp_stats_t *statp;
4527c478bd9Sstevel@tonic-gate char stats_string[15];
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate (void) sprintf(stats_string, "dscpmk_dscp0x%x", val);
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate /* install stats entry */
4577c478bd9Sstevel@tonic-gate if ((err = ipp_stat_create(aid, stats_string, DSCPMK_DSCP_STATS_COUNT,
4587c478bd9Sstevel@tonic-gate dscpmk_update_det_stats, dscpmk_data,
4597c478bd9Sstevel@tonic-gate &dscpmk_data->dscp_stats[val].stats)) != 0) {
4607c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_det_statinit: ipp_stat_create returned "\
4617c478bd9Sstevel@tonic-gate "with error %d\n", err));
4627c478bd9Sstevel@tonic-gate return (err);
4637c478bd9Sstevel@tonic-gate }
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate statp = (dscpmk_dscp_stats_t *)
4667c478bd9Sstevel@tonic-gate (dscpmk_data->dscp_stats[val].stats)->ipps_data;
4677c478bd9Sstevel@tonic-gate ASSERT(statp != NULL);
4687c478bd9Sstevel@tonic-gate
4697c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->dscp_stats[val].stats,
4707c478bd9Sstevel@tonic-gate "dscp", IPP_STAT_UINT32, &statp->dscp)) != 0) {
4717c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_det_statinit: ipp_stat_named_init "\
4727c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
4737c478bd9Sstevel@tonic-gate return (err);
4747c478bd9Sstevel@tonic-gate }
4757c478bd9Sstevel@tonic-gate
4767c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->dscp_stats[val].stats,
4777c478bd9Sstevel@tonic-gate "npackets", IPP_STAT_UINT64, &statp->npackets)) != 0) {
4787c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_det_statinit: ipp_stat_named_init "\
4797c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
4807c478bd9Sstevel@tonic-gate return (err);
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate
4837c478bd9Sstevel@tonic-gate ipp_stat_install(dscpmk_data->dscp_stats[val].stats);
4847c478bd9Sstevel@tonic-gate return (0);
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate static int
dscpmk_summ_statinit(ipp_action_id_t aid,dscpmk_data_t * dscpmk_data)4897c478bd9Sstevel@tonic-gate dscpmk_summ_statinit(ipp_action_id_t aid, dscpmk_data_t *dscpmk_data)
4907c478bd9Sstevel@tonic-gate {
4917c478bd9Sstevel@tonic-gate int err = 0;
4927c478bd9Sstevel@tonic-gate dscpmk_stat_t *statp;
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate /* install stats entry */
4957c478bd9Sstevel@tonic-gate if ((err = ipp_stat_create(aid, DSCPMK_STATS_STRING, DSCPMK_STATS_COUNT,
4967c478bd9Sstevel@tonic-gate dscpmk_update_stats, dscpmk_data, &dscpmk_data->stats)) != 0) {
4977c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_create_action: ipp_stat_create returned " \
4987c478bd9Sstevel@tonic-gate "with error %d\n", err));
4997c478bd9Sstevel@tonic-gate return (err);
5007c478bd9Sstevel@tonic-gate }
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gate statp = (dscpmk_stat_t *)(dscpmk_data->stats)->ipps_data;
5037c478bd9Sstevel@tonic-gate ASSERT(statp != NULL);
5047c478bd9Sstevel@tonic-gate
5057c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->stats, "npackets",
5067c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->npackets)) != 0) {
5077c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_summ_statinit: ipp_stat_named_init " \
5087c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
5097c478bd9Sstevel@tonic-gate return (err);
5107c478bd9Sstevel@tonic-gate }
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->stats, "dscp_changed",
5137c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->dscp_changed)) != 0) {
5147c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_summ_statinit: ipp_stat_named_init " \
5157c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
5167c478bd9Sstevel@tonic-gate return (err);
5177c478bd9Sstevel@tonic-gate }
5187c478bd9Sstevel@tonic-gate
5197c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->stats, "dscp_unchanged",
5207c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->dscp_unchanged)) != 0) {
5217c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_summ_statinit: ipp_stat_named_init " \
5227c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
5237c478bd9Sstevel@tonic-gate return (err);
5247c478bd9Sstevel@tonic-gate }
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->stats, "ipackets",
5277c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->ipackets)) != 0) {
5287c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_summ_statinit: ipp_stat_named_init " \
5297c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
5307c478bd9Sstevel@tonic-gate return (err);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dscpmk_data->stats, "epackets",
5347c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->epackets)) != 0) {
5357c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_summ_statinit: ipp_stat_named_init " \
5367c478bd9Sstevel@tonic-gate "returned with error %d\n", err));
5377c478bd9Sstevel@tonic-gate return (err);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate ipp_stat_install(dscpmk_data->stats);
5417c478bd9Sstevel@tonic-gate return (0);
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate /* ARGSUSED */
5457c478bd9Sstevel@tonic-gate static int
dscpmk_update_det_stats(ipp_stat_t * sp,void * arg,int rw)5467c478bd9Sstevel@tonic-gate dscpmk_update_det_stats(ipp_stat_t *sp, void *arg, int rw)
5477c478bd9Sstevel@tonic-gate {
5487c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data = (dscpmk_data_t *)arg;
5497c478bd9Sstevel@tonic-gate dscpmk_dscp_stats_t *statp;
5507c478bd9Sstevel@tonic-gate uint32_t count;
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate for (count = 0; count < DSCPMK_ARRAY_COUNT; count++) {
5537c478bd9Sstevel@tonic-gate if (!dscpmk_data->dscp_stats[count].present)
5547c478bd9Sstevel@tonic-gate continue;
5557c478bd9Sstevel@tonic-gate statp = (dscpmk_dscp_stats_t *)
5567c478bd9Sstevel@tonic-gate (dscpmk_data->dscp_stats[count].stats)->ipps_data;
5577c478bd9Sstevel@tonic-gate ASSERT(statp != NULL);
5587c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&statp->npackets,
5597c478bd9Sstevel@tonic-gate &dscpmk_data->dscp_stats[count].npackets, rw);
5607c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&statp->dscp, &count, rw);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate return (0);
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate static int
dscpmk_update_stats(ipp_stat_t * sp,void * arg,int rw)5667c478bd9Sstevel@tonic-gate dscpmk_update_stats(ipp_stat_t *sp, void *arg, int rw)
5677c478bd9Sstevel@tonic-gate {
5687c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data = (dscpmk_data_t *)arg;
5697c478bd9Sstevel@tonic-gate dscpmk_stat_t *snames = (dscpmk_stat_t *)sp->ipps_data;
5707c478bd9Sstevel@tonic-gate ASSERT(dscpmk_data != NULL);
5717c478bd9Sstevel@tonic-gate ASSERT(snames != NULL);
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->npackets, &dscpmk_data->npackets, rw);
5747c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->dscp_changed, &dscpmk_data->changed,
5757c478bd9Sstevel@tonic-gate rw);
5767c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->dscp_unchanged,
5777c478bd9Sstevel@tonic-gate &dscpmk_data->unchanged, rw);
5787c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->ipackets, &dscpmk_data->ipackets, rw);
5797c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->epackets, &dscpmk_data->epackets, rw);
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate return (0);
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate
5847c478bd9Sstevel@tonic-gate /* ARGSUSED */
5857c478bd9Sstevel@tonic-gate static int
dscpmk_info(ipp_action_id_t aid,int (* fn)(nvlist_t *,void *),void * arg,ipp_flags_t flags)5867c478bd9Sstevel@tonic-gate dscpmk_info(ipp_action_id_t aid, int (*fn)(nvlist_t *, void *), void *arg,
5877c478bd9Sstevel@tonic-gate ipp_flags_t flags)
5887c478bd9Sstevel@tonic-gate {
5897c478bd9Sstevel@tonic-gate nvlist_t *nvlp;
5907c478bd9Sstevel@tonic-gate dscpmk_data_t *dscpmk_data;
5917c478bd9Sstevel@tonic-gate char *next_action;
5927c478bd9Sstevel@tonic-gate int err, cnt;
5937c478bd9Sstevel@tonic-gate int32_t dscp_map[DSCPMK_ARRAY_COUNT];
5947c478bd9Sstevel@tonic-gate
5957c478bd9Sstevel@tonic-gate ASSERT(fn != NULL);
5967c478bd9Sstevel@tonic-gate
5977c478bd9Sstevel@tonic-gate dscpmk_data = (dscpmk_data_t *)ipp_action_get_ptr(aid);
5987c478bd9Sstevel@tonic-gate ASSERT(dscpmk_data != NULL);
5997c478bd9Sstevel@tonic-gate
6007c478bd9Sstevel@tonic-gate /* allocate nvlist to be passed back */
6017c478bd9Sstevel@tonic-gate if ((err = nvlist_alloc(&nvlp, NV_UNIQUE_NAME, KM_NOSLEEP)) != 0) {
6027c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: error allocating memory\n"));
6037c478bd9Sstevel@tonic-gate return (err);
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate
6067c478bd9Sstevel@tonic-gate /* look up next action with the next action id */
6077c478bd9Sstevel@tonic-gate if ((err = ipp_action_name(dscpmk_data->next_action,
6087c478bd9Sstevel@tonic-gate &next_action)) != 0) {
6097c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: next action not available\n"));
6107c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6117c478bd9Sstevel@tonic-gate return (err);
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate /* add next action name */
6157c478bd9Sstevel@tonic-gate if ((err = nvlist_add_string(nvlp, DSCPMK_NEXT_ACTION_NAME,
6167c478bd9Sstevel@tonic-gate next_action)) != 0) {
6177c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: error adding next action\n"));
6187c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6197c478bd9Sstevel@tonic-gate kmem_free(next_action, (strlen(next_action) + 1));
6207c478bd9Sstevel@tonic-gate return (err);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate /* free action name */
6247c478bd9Sstevel@tonic-gate kmem_free(next_action, (strlen(next_action) + 1));
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate /* add config type */
6277c478bd9Sstevel@tonic-gate if ((err = nvlist_add_byte(nvlp, IPP_CONFIG_TYPE, IPP_SET)) != 0) {
6287c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: error adding config type\n"));
6297c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6307c478bd9Sstevel@tonic-gate return (err);
6317c478bd9Sstevel@tonic-gate }
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate /* add dscp map */
6347c478bd9Sstevel@tonic-gate bcopy(dscpmk_data->dscp_map, dscp_map, sizeof (dscp_map));
6357c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < DSCPMK_ARRAY_COUNT; cnt++) {
6367c478bd9Sstevel@tonic-gate dscp_map[cnt] = dscpmk_data->dscp_map[cnt];
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate if ((err = nvlist_add_int32_array(nvlp, DSCPMK_DSCP_MAP,
6397c478bd9Sstevel@tonic-gate dscp_map, DSCPMK_ARRAY_COUNT)) != 0) {
6407c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: error adding dscp map\n"));
6417c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6427c478bd9Sstevel@tonic-gate return (err);
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate /* add summary stats boolean */
6467c478bd9Sstevel@tonic-gate if ((err = nvlist_add_uint32(nvlp, IPP_ACTION_STATS_ENABLE,
6477c478bd9Sstevel@tonic-gate (dscpmk_data->summary_stats ? 1 : 0))) != 0) {
6487c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: error adding stats status\n"));
6497c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6507c478bd9Sstevel@tonic-gate return (err);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate /* add detailed stats boolean */
6547c478bd9Sstevel@tonic-gate if ((err = nvlist_add_uint32(nvlp, DSCPMK_DETAILED_STATS,
6557c478bd9Sstevel@tonic-gate (dscpmk_data->detailed_stats ? 1 : 0))) != 0) {
6567c478bd9Sstevel@tonic-gate dscpmk0dbg(("dscpmk_info: error adding det stats status\n"));
6577c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6587c478bd9Sstevel@tonic-gate return (err);
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate /* call back with nvlist */
6627c478bd9Sstevel@tonic-gate err = fn(nvlp, arg);
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate nvlist_free(nvlp);
6657c478bd9Sstevel@tonic-gate return (err);
6667c478bd9Sstevel@tonic-gate }
667