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 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 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 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 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 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 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 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 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 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 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 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 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