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/atomic.h> 287c478bd9Sstevel@tonic-gate #include <sys/systm.h> 297c478bd9Sstevel@tonic-gate #include <sys/socket.h> 307c478bd9Sstevel@tonic-gate #include <netinet/in.h> 317c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 327c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 337c478bd9Sstevel@tonic-gate #include <ipp/ipp.h> 347c478bd9Sstevel@tonic-gate #include <ipp/ipp_config.h> 357c478bd9Sstevel@tonic-gate #include <inet/common.h> 367c478bd9Sstevel@tonic-gate #include <ipp/dlcosmk/dlcosmk_impl.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #define D_SM_COMMENT "IPP dlcosmk marker module" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* DDI file for dlcosmk ipp module */ 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate static int dlcosmk_create_action(ipp_action_id_t, nvlist_t **, ipp_flags_t); 437c478bd9Sstevel@tonic-gate static int dlcosmk_modify_action(ipp_action_id_t, nvlist_t **, ipp_flags_t); 447c478bd9Sstevel@tonic-gate static int dlcosmk_destroy_action(ipp_action_id_t, ipp_flags_t); 457c478bd9Sstevel@tonic-gate static int dlcosmk_info(ipp_action_id_t, int (*)(nvlist_t *, void *), void *, 467c478bd9Sstevel@tonic-gate ipp_flags_t); 477c478bd9Sstevel@tonic-gate static int dlcosmk_invoke_action(ipp_action_id_t, ipp_packet_t *); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate static int dlcosmk_statinit(ipp_action_id_t, dlcosmk_data_t *); 507c478bd9Sstevel@tonic-gate static int dlcosmk_update_stats(ipp_stat_t *, void *, int); 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* Entry points for this IPP module */ 537c478bd9Sstevel@tonic-gate ipp_ops_t dlcosmk_ops = { 547c478bd9Sstevel@tonic-gate IPPO_REV, 557c478bd9Sstevel@tonic-gate dlcosmk_create_action, /* ippo_action_create */ 567c478bd9Sstevel@tonic-gate dlcosmk_modify_action, /* ippo_action_modify */ 577c478bd9Sstevel@tonic-gate dlcosmk_destroy_action, /* ippo_action_destroy */ 587c478bd9Sstevel@tonic-gate dlcosmk_info, /* ippo_action_info */ 597c478bd9Sstevel@tonic-gate dlcosmk_invoke_action /* ippo_action_invoke */ 607c478bd9Sstevel@tonic-gate }; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate extern struct mod_ops mod_ippops; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * Module linkage information for the kernel. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate static struct modlipp modlipp = { 687c478bd9Sstevel@tonic-gate &mod_ippops, 69*39b361b2SRichard Bean D_SM_COMMENT, 707c478bd9Sstevel@tonic-gate &dlcosmk_ops 717c478bd9Sstevel@tonic-gate }; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 747c478bd9Sstevel@tonic-gate MODREV_1, 757c478bd9Sstevel@tonic-gate (void *)&modlipp, 767c478bd9Sstevel@tonic-gate NULL 777c478bd9Sstevel@tonic-gate }; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate int 817c478bd9Sstevel@tonic-gate _init(void) 827c478bd9Sstevel@tonic-gate { 837c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage)); 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate int 877c478bd9Sstevel@tonic-gate _fini(void) 887c478bd9Sstevel@tonic-gate { 897c478bd9Sstevel@tonic-gate return (mod_remove(&modlinkage)); 907c478bd9Sstevel@tonic-gate } 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate int 937c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 947c478bd9Sstevel@tonic-gate { 957c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate static int 997c478bd9Sstevel@tonic-gate dlcosmk_create_action(ipp_action_id_t aid, nvlist_t **nvlpp, 1007c478bd9Sstevel@tonic-gate ipp_flags_t flags) 1017c478bd9Sstevel@tonic-gate { 1027c478bd9Sstevel@tonic-gate nvlist_t *nvlp; 1037c478bd9Sstevel@tonic-gate dlcosmk_data_t *dlcosmk_data; 1047c478bd9Sstevel@tonic-gate char *next_action; 1057c478bd9Sstevel@tonic-gate int err; 1067c478bd9Sstevel@tonic-gate uint32_t bstats, param; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate ASSERT((nvlpp != NULL) && (*nvlpp != NULL)); 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate nvlp = *nvlpp; 1117c478bd9Sstevel@tonic-gate *nvlpp = NULL; /* nvlist should be NULL on return */ 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate if ((dlcosmk_data = kmem_zalloc(DLCOSMK_DATA_SZ, KM_NOSLEEP)) == NULL) { 1147c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1157c478bd9Sstevel@tonic-gate return (ENOMEM); 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate /* parse next action name */ 1197c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_string(nvlp, DLCOSMK_NEXT_ACTION_NAME, 1207c478bd9Sstevel@tonic-gate &next_action)) != 0) { 1217c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1227c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: invalid config, "\ 1237c478bd9Sstevel@tonic-gate "next_action name missing\n")); 1247c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1257c478bd9Sstevel@tonic-gate return (err); 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate if ((dlcosmk_data->next_action = 1287c478bd9Sstevel@tonic-gate ipp_action_lookup(next_action)) == IPP_ACTION_INVAL) { 1297c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1307c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: next_action invalid\n")); 1317c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1327c478bd9Sstevel@tonic-gate return (EINVAL); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* parse cos - from the config file */ 1367c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_byte(nvlp, DLCOSMK_COS, 1377c478bd9Sstevel@tonic-gate &dlcosmk_data->usr_pri)) != 0) { 1387c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1397c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: invalid config, "\ 1407c478bd9Sstevel@tonic-gate "cos missing\n")); 1417c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1427c478bd9Sstevel@tonic-gate return (err); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* parse b_band - mapped from cos */ 1467c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, DLCOSMK_BAND, ¶m)) != 0) { 1477c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1487c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: invalid config, "\ 1497c478bd9Sstevel@tonic-gate "b_band missing\n")); 1507c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1517c478bd9Sstevel@tonic-gate return (err); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate dlcosmk_data->b_band = param; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate /* parse dl_priority.dl_max - mapped from cos */ 1567c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, DLCOSMK_PRI, ¶m)) != 0) { 1577c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1587c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: invalid config, "\ 1597c478bd9Sstevel@tonic-gate "dl_priority missing\n")); 1607c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1617c478bd9Sstevel@tonic-gate return (err); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate dlcosmk_data->dl_max = param; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* parse gather_stats boolean */ 1667c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats)) 1677c478bd9Sstevel@tonic-gate != 0) { 1687c478bd9Sstevel@tonic-gate dlcosmk_data->gather_stats = B_FALSE; 1697c478bd9Sstevel@tonic-gate } else { 1707c478bd9Sstevel@tonic-gate /* If stats is needed, initialize the stats structure */ 1717c478bd9Sstevel@tonic-gate dlcosmk_data->gather_stats = (bstats != 0) ? B_TRUE : B_FALSE; 1727c478bd9Sstevel@tonic-gate if (dlcosmk_data->gather_stats) { 1737c478bd9Sstevel@tonic-gate if ((err = dlcosmk_statinit(aid, dlcosmk_data)) != 0) { 1747c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1757c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1767c478bd9Sstevel@tonic-gate return (err); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate /* Free the nvlist */ 1827c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* set action chain reference */ 1857c478bd9Sstevel@tonic-gate if ((err = ipp_action_ref(aid, dlcosmk_data->next_action, 1867c478bd9Sstevel@tonic-gate flags)) != 0) { 1877c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_action_ref " \ 1887c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 1897c478bd9Sstevel@tonic-gate ipp_stat_destroy(dlcosmk_data->stats); 1907c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 1917c478bd9Sstevel@tonic-gate return (err); 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate ipp_action_set_ptr(aid, (void *)dlcosmk_data); 1957c478bd9Sstevel@tonic-gate return (0); 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate static int 1997c478bd9Sstevel@tonic-gate dlcosmk_modify_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags) 2007c478bd9Sstevel@tonic-gate { 2017c478bd9Sstevel@tonic-gate nvlist_t *nvlp; 2027c478bd9Sstevel@tonic-gate int err = 0; 2037c478bd9Sstevel@tonic-gate uint32_t band, dlpri; 2047c478bd9Sstevel@tonic-gate uint8_t config_type; 2057c478bd9Sstevel@tonic-gate uint8_t cos; 2067c478bd9Sstevel@tonic-gate char *next_action_name; 2077c478bd9Sstevel@tonic-gate ipp_action_id_t next_action; 2087c478bd9Sstevel@tonic-gate dlcosmk_data_t *dlcosmk_data; 2097c478bd9Sstevel@tonic-gate uint32_t bstats; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate ASSERT((nvlpp != NULL) && (*nvlpp != NULL)); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate nvlp = *nvlpp; 2147c478bd9Sstevel@tonic-gate *nvlpp = NULL; /* nvlist should be NULL when this returns */ 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_byte(nvlp, IPP_CONFIG_TYPE, &config_type)) 2177c478bd9Sstevel@tonic-gate != 0) { 2187c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2197c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_modify_action: invalid configuration "\ 2207c478bd9Sstevel@tonic-gate "type\n")); 2217c478bd9Sstevel@tonic-gate return (err); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if (config_type != IPP_SET) { 2257c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2267c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_modify_action: invalid configuration "\ 2277c478bd9Sstevel@tonic-gate "type %d\n", config_type)); 2287c478bd9Sstevel@tonic-gate return (EINVAL); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate dlcosmk_data = (dlcosmk_data_t *)ipp_action_get_ptr(aid); 2327c478bd9Sstevel@tonic-gate ASSERT(dlcosmk_data != NULL); 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate /* parse next action name, if present */ 2357c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_string(nvlp, DLCOSMK_NEXT_ACTION_NAME, 2367c478bd9Sstevel@tonic-gate &next_action_name)) == 0) { 2377c478bd9Sstevel@tonic-gate /* lookup action name to get action id */ 2387c478bd9Sstevel@tonic-gate if ((next_action = ipp_action_lookup(next_action_name)) 2397c478bd9Sstevel@tonic-gate == IPP_ACTION_INVAL) { 2407c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2417c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_modify_action: next_action "\ 2427c478bd9Sstevel@tonic-gate "invalid\n")); 2437c478bd9Sstevel@tonic-gate return (EINVAL); 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate /* reference new action */ 2467c478bd9Sstevel@tonic-gate if ((err = ipp_action_ref(aid, next_action, flags)) != 0) { 2477c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2487c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_modify_action: ipp_action_ref "\ 2497c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 2507c478bd9Sstevel@tonic-gate return (err); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate /* unref old action */ 2537c478bd9Sstevel@tonic-gate err = ipp_action_unref(aid, dlcosmk_data->next_action, flags); 2547c478bd9Sstevel@tonic-gate ASSERT(err == 0); 2557c478bd9Sstevel@tonic-gate dlcosmk_data->next_action = next_action; 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* parse cos, if present */ 2597c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_byte(nvlp, DLCOSMK_COS, &cos)) == 0) { 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* parse b_band, mapped from cos */ 2627c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, DLCOSMK_BAND, 2637c478bd9Sstevel@tonic-gate &band)) != 0) { 2647c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2657c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_modify_action: b_band not "\ 2667c478bd9Sstevel@tonic-gate "provided\n")); 2677c478bd9Sstevel@tonic-gate return (err); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate /* parse dl_priority, mapped from cos */ 2717c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, DLCOSMK_PRI, 2727c478bd9Sstevel@tonic-gate &dlpri)) != 0) { 2737c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2747c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_modify_action: dl_priority not "\ 2757c478bd9Sstevel@tonic-gate "provided\n")); 2767c478bd9Sstevel@tonic-gate return (err); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /* Have all the three values, change them */ 2807c478bd9Sstevel@tonic-gate dlcosmk_data->usr_pri = cos; 2817c478bd9Sstevel@tonic-gate dlcosmk_data->b_band = band; 2827c478bd9Sstevel@tonic-gate dlcosmk_data->dl_max = dlpri; 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* parse gather_stats boolean, if present */ 2877c478bd9Sstevel@tonic-gate if ((err = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats)) 2887c478bd9Sstevel@tonic-gate == 0) { 2897c478bd9Sstevel@tonic-gate boolean_t val = (bstats != 0) ? B_TRUE : B_FALSE; 2907c478bd9Sstevel@tonic-gate /* Turning on stats */ 2917c478bd9Sstevel@tonic-gate if (!dlcosmk_data->gather_stats && val) { 2927c478bd9Sstevel@tonic-gate if ((err = dlcosmk_statinit(aid, dlcosmk_data)) != 0) { 2937c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 2947c478bd9Sstevel@tonic-gate return (err); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate /* Turning off stats */ 2977c478bd9Sstevel@tonic-gate } else if (!val && dlcosmk_data->gather_stats) { 2987c478bd9Sstevel@tonic-gate ipp_stat_destroy(dlcosmk_data->stats); 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate dlcosmk_data->gather_stats = val; 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* Free thenvlist */ 3057c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 3067c478bd9Sstevel@tonic-gate return (0); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate static int 3107c478bd9Sstevel@tonic-gate dlcosmk_destroy_action(ipp_action_id_t aid, ipp_flags_t flags) 3117c478bd9Sstevel@tonic-gate { 3127c478bd9Sstevel@tonic-gate dlcosmk_data_t *dlcosmk_data; 3137c478bd9Sstevel@tonic-gate int err; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate dlcosmk_data = (dlcosmk_data_t *)ipp_action_get_ptr(aid); 3167c478bd9Sstevel@tonic-gate ASSERT(dlcosmk_data != NULL); 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate /* Destroy stats, if gathered */ 3197c478bd9Sstevel@tonic-gate if (dlcosmk_data->gather_stats) { 3207c478bd9Sstevel@tonic-gate ipp_stat_destroy(dlcosmk_data->stats); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate /* unreference the action */ 3247c478bd9Sstevel@tonic-gate err = ipp_action_unref(aid, dlcosmk_data->next_action, flags); 3257c478bd9Sstevel@tonic-gate ASSERT(err == 0); 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate kmem_free(dlcosmk_data, DLCOSMK_DATA_SZ); 3287c478bd9Sstevel@tonic-gate return (0); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate static int 3327c478bd9Sstevel@tonic-gate dlcosmk_invoke_action(ipp_action_id_t aid, ipp_packet_t *packet) 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate dlcosmk_data_t *dlcosmk_data; 3357c478bd9Sstevel@tonic-gate mblk_t *mp = NULL; 3367c478bd9Sstevel@tonic-gate int err; 3377c478bd9Sstevel@tonic-gate ip_priv_t *priv; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate ASSERT(packet != NULL); 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate /* get mblk from ipp_packet structure */ 3427c478bd9Sstevel@tonic-gate mp = ipp_packet_get_data(packet); 3437c478bd9Sstevel@tonic-gate priv = (ip_priv_t *)ipp_packet_get_private(packet); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate dlcosmk_data = (dlcosmk_data_t *)ipp_action_get_ptr(aid); 3467c478bd9Sstevel@tonic-gate ASSERT(dlcosmk_data != NULL); 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate /* dlcosmk packet as configured */ 3497c478bd9Sstevel@tonic-gate if ((err = dlcosmk_process(&mp, dlcosmk_data, priv->ill_index, 3507c478bd9Sstevel@tonic-gate priv->proc)) != 0) { 3517c478bd9Sstevel@tonic-gate return (err); 3527c478bd9Sstevel@tonic-gate } else { 3537c478bd9Sstevel@tonic-gate /* return packet with next action set */ 3547c478bd9Sstevel@tonic-gate return (ipp_packet_next(packet, dlcosmk_data->next_action)); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate static int 3597c478bd9Sstevel@tonic-gate dlcosmk_statinit(ipp_action_id_t aid, dlcosmk_data_t *dlcosmk_data) 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate int err; 3627c478bd9Sstevel@tonic-gate dlcosmk_stat_t *statp; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate /* install stats entry */ 3657c478bd9Sstevel@tonic-gate if ((err = ipp_stat_create(aid, DLCOSMK_STATS_STRING, 3667c478bd9Sstevel@tonic-gate DLCOSMK_STATS_COUNT, dlcosmk_update_stats, dlcosmk_data, 3677c478bd9Sstevel@tonic-gate &dlcosmk_data->stats)) != 0) { 3687c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_create " \ 3697c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 3707c478bd9Sstevel@tonic-gate return (err); 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate statp = (dlcosmk_stat_t *)(dlcosmk_data->stats)->ipps_data; 3747c478bd9Sstevel@tonic-gate ASSERT(statp != NULL); 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dlcosmk_data->stats, "npackets", 3777c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->npackets)) != 0) { 3787c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_named_init " \ 3797c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 3807c478bd9Sstevel@tonic-gate return (err); 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dlcosmk_data->stats, "ipackets", 3847c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->ipackets)) != 0) { 3857c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_named_init " \ 3867c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 3877c478bd9Sstevel@tonic-gate return (err); 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dlcosmk_data->stats, "epackets", 3917c478bd9Sstevel@tonic-gate IPP_STAT_UINT64, &statp->epackets)) != 0) { 3927c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_named_init " \ 3937c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 3947c478bd9Sstevel@tonic-gate return (err); 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dlcosmk_data->stats, "usr_pri", 3987c478bd9Sstevel@tonic-gate IPP_STAT_INT32, &statp->usr_pri)) != 0) { 3997c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_named_init " \ 4007c478bd9Sstevel@tonic-gate "returned with error %d", err)); 4017c478bd9Sstevel@tonic-gate return (err); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dlcosmk_data->stats, "b_band", 4057c478bd9Sstevel@tonic-gate IPP_STAT_INT32, &statp->b_band)) != 0) { 4067c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_named_init " \ 4077c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 4087c478bd9Sstevel@tonic-gate return (err); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate if ((err = ipp_stat_named_init(dlcosmk_data->stats, "dl_max", 4127c478bd9Sstevel@tonic-gate IPP_STAT_INT32, &statp->dl_max)) != 0) { 4137c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_create_action: ipp_stat_named_init " \ 4147c478bd9Sstevel@tonic-gate "returned with error %d\n", err)); 4157c478bd9Sstevel@tonic-gate return (err); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate ipp_stat_install(dlcosmk_data->stats); 4197c478bd9Sstevel@tonic-gate return (0); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate static int 4237c478bd9Sstevel@tonic-gate dlcosmk_update_stats(ipp_stat_t *sp, void *arg, int rw) 4247c478bd9Sstevel@tonic-gate { 4257c478bd9Sstevel@tonic-gate dlcosmk_data_t *dlcosmk_data = (dlcosmk_data_t *)arg; 4267c478bd9Sstevel@tonic-gate dlcosmk_stat_t *snames = (dlcosmk_stat_t *)sp->ipps_data; 4277c478bd9Sstevel@tonic-gate uint32_t upri, bband; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate ASSERT(dlcosmk_data != NULL); 4307c478bd9Sstevel@tonic-gate ASSERT(snames != NULL); 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate upri = dlcosmk_data->usr_pri; 4337c478bd9Sstevel@tonic-gate bband = dlcosmk_data->b_band; 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->npackets, &dlcosmk_data->npackets, 4367c478bd9Sstevel@tonic-gate rw); 4377c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->ipackets, &dlcosmk_data->ipackets, 4387c478bd9Sstevel@tonic-gate rw); 4397c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->epackets, &dlcosmk_data->epackets, 4407c478bd9Sstevel@tonic-gate rw); 4417c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->usr_pri, &upri, rw); 4427c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->b_band, &bband, rw); 4437c478bd9Sstevel@tonic-gate (void) ipp_stat_named_op(&snames->dl_max, &dlcosmk_data->dl_max, rw); 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate return (0); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4497c478bd9Sstevel@tonic-gate static int 4507c478bd9Sstevel@tonic-gate dlcosmk_info(ipp_action_id_t aid, int (*fn)(nvlist_t *, void *), void *arg, 4517c478bd9Sstevel@tonic-gate ipp_flags_t flags) 4527c478bd9Sstevel@tonic-gate { 4537c478bd9Sstevel@tonic-gate nvlist_t *nvlp; 4547c478bd9Sstevel@tonic-gate dlcosmk_data_t *dlcosmk_data; 4557c478bd9Sstevel@tonic-gate char *next_action; 4567c478bd9Sstevel@tonic-gate int err; 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate ASSERT(fn != NULL); 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate dlcosmk_data = (dlcosmk_data_t *)ipp_action_get_ptr(aid); 4617c478bd9Sstevel@tonic-gate ASSERT(dlcosmk_data != NULL); 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate /* allocate nvlist to be passed back */ 4647c478bd9Sstevel@tonic-gate if ((err = nvlist_alloc(&nvlp, NV_UNIQUE_NAME, KM_NOSLEEP)) != 0) { 4657c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_info: error allocating memory\n")); 4667c478bd9Sstevel@tonic-gate return (err); 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate /* look up next action with the next action id */ 4707c478bd9Sstevel@tonic-gate if ((err = ipp_action_name(dlcosmk_data->next_action, 4717c478bd9Sstevel@tonic-gate &next_action)) != 0) { 4727c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_info: next action not available\n")); 4737c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 4747c478bd9Sstevel@tonic-gate return (err); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate /* add next action name */ 4787c478bd9Sstevel@tonic-gate if ((err = nvlist_add_string(nvlp, DLCOSMK_NEXT_ACTION_NAME, 4797c478bd9Sstevel@tonic-gate next_action)) != 0) { 4807c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_info: error adding next action\n")); 4817c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 4827c478bd9Sstevel@tonic-gate kmem_free(next_action, (strlen(next_action) + 1)); 4837c478bd9Sstevel@tonic-gate return (err); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate /* free action name */ 4877c478bd9Sstevel@tonic-gate kmem_free(next_action, (strlen(next_action) + 1)); 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate /* add config type */ 4907c478bd9Sstevel@tonic-gate if ((err = nvlist_add_byte(nvlp, IPP_CONFIG_TYPE, IPP_SET)) != 0) { 4917c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_info: error adding config. type\n")); 4927c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 4937c478bd9Sstevel@tonic-gate return (err); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate /* just give the cos, since that is what is provided in the config */ 4977c478bd9Sstevel@tonic-gate if ((err = nvlist_add_byte(nvlp, DLCOSMK_COS, dlcosmk_data->usr_pri)) 4987c478bd9Sstevel@tonic-gate != 0) { 4997c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_info: error adding cos\n")); 5007c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 5017c478bd9Sstevel@tonic-gate return (err); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate /* add gather stats boolean */ 5057c478bd9Sstevel@tonic-gate if ((err = nvlist_add_uint32(nvlp, IPP_ACTION_STATS_ENABLE, 5067c478bd9Sstevel@tonic-gate (dlcosmk_data->gather_stats ? 1 : 0))) != 0) { 5077c478bd9Sstevel@tonic-gate dlcosmk0dbg(("dlcosmk_info: error adding stats status\n")); 5087c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 5097c478bd9Sstevel@tonic-gate return (err); 5107c478bd9Sstevel@tonic-gate } 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate /* call back with nvlist */ 5137c478bd9Sstevel@tonic-gate err = fn(nvlp, arg); 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate nvlist_free(nvlp); 5167c478bd9Sstevel@tonic-gate return (err); 5177c478bd9Sstevel@tonic-gate } 518