4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/atomic.h>
29 #include <sys/systm.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <sys/modctl.h>
33 #include <sys/sunddi.h>
35 #include <ipp/ipp_config.h>
36 #include <inet/common.h>
37 #include <ipp/meters/meter_impl.h>
39 #define D_SM_COMMENT "IPP Sliding Window Meter"
41 /* DDI file for tswtcl ipp module */
43 static int tswtcl_create_action(ipp_action_id_t
, nvlist_t
**, ipp_flags_t
);
44 static int tswtcl_modify_action(ipp_action_id_t
, nvlist_t
**, ipp_flags_t
);
45 static int tswtcl_destroy_action(ipp_action_id_t
, ipp_flags_t
);
46 static int tswtcl_info(ipp_action_id_t
, int (*)(nvlist_t
*, void *), void *,
48 static int tswtcl_invoke_action(ipp_action_id_t
, ipp_packet_t
*);
50 /* Stats init function */
51 static int tswtcl_statinit(ipp_action_id_t
, tswtcl_data_t
*);
53 /* Stats callback function */
54 static int tswtcl_update_stats(ipp_stat_t
*, void *, int);
56 ipp_ops_t tswtcl_ops
= {
58 tswtcl_create_action
, /* ippo_action_create */
59 tswtcl_modify_action
, /* ippo_action_modify */
60 tswtcl_destroy_action
, /* ippo_action_destroy */
61 tswtcl_info
, /* ippo_action_info */
62 tswtcl_invoke_action
/* ippo_action_invoke */
65 extern struct mod_ops mod_ippops
;
68 * Module linkage information for the kernel.
70 static struct modlipp modlipp
= {
76 static struct modlinkage modlinkage
= {
86 return (mod_install(&modlinkage
));
92 return (mod_remove(&modlinkage
));
96 _info(struct modinfo
*modinfop
)
98 return (mod_info(&modlinkage
, modinfop
));
103 tswtcl_create_action(ipp_action_id_t aid
, nvlist_t
**nvlpp
, ipp_flags_t flags
)
106 tswtcl_data_t
*tswtcl_data
;
107 tswtcl_cfg_t
*cfg_parms
;
113 *nvlpp
= NULL
; /* nvlist should be NULL on return */
116 if ((cfg_parms
= kmem_alloc(TSWTCL_CFG_SZ
, KM_NOSLEEP
)) == NULL
) {
121 /* parse red next action name */
122 if ((rc
= nvlist_lookup_string(nvlp
, TSWTCL_RED_ACTION_NAME
,
123 &next_action
)) != 0) {
125 tswtcl0dbg(("tswtcl_create_action:invalid config, red action" \
127 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
130 if ((cfg_parms
->red_action
= ipp_action_lookup(next_action
))
131 == IPP_ACTION_INVAL
) {
133 tswtcl0dbg(("tswtcl_create_action: red action invalid\n"));
134 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
138 /* parse yellow next action name */
139 if ((rc
= nvlist_lookup_string(nvlp
, TSWTCL_YELLOW_ACTION_NAME
,
140 &next_action
)) != 0) {
142 tswtcl0dbg(("tswtcl_create_action:invalid config, yellow " \
143 "action name missing\n"));
144 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
147 if ((cfg_parms
->yellow_action
= ipp_action_lookup(next_action
))
148 == IPP_ACTION_INVAL
) {
150 tswtcl0dbg(("tswtcl_create_action: yellow action invalid\n"));
151 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
155 /* parse green next action name */
156 if ((rc
= nvlist_lookup_string(nvlp
, TSWTCL_GREEN_ACTION_NAME
,
157 &next_action
)) != 0) {
159 tswtcl0dbg(("tswtcl_create_action:invalid config, green " \
160 "action name missing\n"));
161 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
164 if ((cfg_parms
->green_action
= ipp_action_lookup(next_action
))
165 == IPP_ACTION_INVAL
) {
167 tswtcl0dbg(("tswtcl_create_action: green action invalid\n"));
168 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
172 /* parse committed rate - in bits / sec */
173 if ((rc
= nvlist_lookup_uint32(nvlp
, TSWTCL_COMMITTED_RATE
,
174 &cfg_parms
->committed_rate
)) != 0) {
176 tswtcl0dbg(("tswtcl_create_action: invalid config, "\
177 " committed rate missing\n"));
178 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
182 /* parse peak rate - in bits / sec */
183 if ((rc
= nvlist_lookup_uint32(nvlp
, TSWTCL_PEAK_RATE
,
184 &cfg_parms
->peak_rate
)) != 0) {
186 tswtcl0dbg(("tswtcl_create_action: invalid config, "\
187 " peak rate missing\n"));
188 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
192 if (cfg_parms
->peak_rate
< cfg_parms
->committed_rate
) {
194 tswtcl0dbg(("tswtcl_create_action: invalid config, "\
195 " peak rate < committed rate\n"));
196 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
200 /* parse window - in msec */
201 if ((rc
= nvlist_lookup_uint32(nvlp
, TSWTCL_WINDOW
,
202 &cfg_parms
->window
)) != 0) {
204 tswtcl0dbg(("tswtcl_create_action: invalid config, "\
205 " window missing\n"));
206 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
209 /* convert to nsec */
210 cfg_parms
->nsecwindow
= (uint64_t)cfg_parms
->window
*
214 if ((rc
= nvlist_lookup_uint32(nvlp
, IPP_ACTION_STATS_ENABLE
, &bstats
))
216 cfg_parms
->stats
= B_FALSE
;
218 cfg_parms
->stats
= (boolean_t
)bstats
;
223 /* Initialize other stuff */
224 tswtcl_data
= kmem_zalloc(TSWTCL_DATA_SZ
, KM_NOSLEEP
);
225 if (tswtcl_data
== NULL
) {
226 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
230 if (cfg_parms
->stats
) {
231 if ((rc
= tswtcl_statinit(aid
, tswtcl_data
)) != 0) {
232 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
233 kmem_free(tswtcl_data
, TSWTCL_DATA_SZ
);
238 /* set action chain reference */
239 if ((rc
= ipp_action_ref(aid
, cfg_parms
->red_action
, flags
)) != 0) {
240 tswtcl0dbg(("tswtcl_create_action: ipp_action_ref " \
241 "returned with error %d", rc
));
244 if ((rc
= ipp_action_ref(aid
, cfg_parms
->yellow_action
, flags
)) != 0) {
245 tswtcl0dbg(("tswtcl_create_action: ipp_action_ref " \
246 "returned with error %d", rc
));
247 rc2
= ipp_action_unref(aid
, cfg_parms
->red_action
, flags
);
251 if ((rc
= ipp_action_ref(aid
, cfg_parms
->green_action
, flags
)) != 0) {
252 tswtcl0dbg(("tswtcl_create_action: ipp_action_ref " \
253 "returned with error %d", rc
));
254 rc2
= ipp_action_unref(aid
, cfg_parms
->red_action
, flags
);
256 rc2
= ipp_action_unref(aid
, cfg_parms
->yellow_action
, flags
);
261 /* Initializations */
262 cfg_parms
->pminusc
= cfg_parms
->peak_rate
- cfg_parms
->committed_rate
;
263 tswtcl_data
->cfg_parms
= cfg_parms
;
264 tswtcl_data
->avg_rate
= cfg_parms
->committed_rate
;
265 mutex_init(&tswtcl_data
->tswtcl_lock
, NULL
, MUTEX_DEFAULT
, 0);
266 tswtcl_data
->win_front
= gethrtime();
267 ipp_action_set_ptr(aid
, (void *)tswtcl_data
);
272 if (cfg_parms
->stats
) {
273 ipp_stat_destroy(tswtcl_data
->stats
);
275 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
276 kmem_free(tswtcl_data
, TSWTCL_DATA_SZ
);
282 tswtcl_modify_action(ipp_action_id_t aid
, nvlist_t
**nvlpp
, ipp_flags_t flags
)
288 char *next_action_name
;
289 ipp_action_id_t next_action
;
291 tswtcl_cfg_t
*cfg_parms
, *old_cfg
;
292 tswtcl_data_t
*tswtcl_data
;
296 *nvlpp
= NULL
; /* nvlist should be NULL when this returns */
298 if ((err
= nvlist_lookup_byte(nvlp
, IPP_CONFIG_TYPE
, &config_type
))
301 tswtcl0dbg(("tswtcl_modify_action:invalid configuration type"));
305 if (config_type
!= IPP_SET
) {
307 tswtcl0dbg(("tswtcl_modify_action:invalid configuration type " \
312 tswtcl_data
= (tswtcl_data_t
*)ipp_action_get_ptr(aid
);
313 old_cfg
= tswtcl_data
->cfg_parms
;
315 cfg_parms
= kmem_alloc(TSWTCL_CFG_SZ
, KM_NOSLEEP
);
316 if (cfg_parms
== NULL
) {
318 tswtcl0dbg(("tswtcl_modify_action:mem. allocation failure\n"));
322 /* Just copy all and change as needed */
323 bcopy(old_cfg
, cfg_parms
, TSWTCL_CFG_SZ
);
325 /* parse red action name, if present */
326 if ((err
= nvlist_lookup_string(nvlp
, TSWTCL_RED_ACTION_NAME
,
327 &next_action_name
)) == 0) {
329 if ((next_action
= ipp_action_lookup(next_action_name
))
330 == IPP_ACTION_INVAL
) {
332 tswtcl0dbg(("tswtcl_modify_action: red next_action"\
334 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
337 cfg_parms
->red_action
= next_action
;
340 /* parse yellow action name, if present */
341 if ((err
= nvlist_lookup_string(nvlp
, TSWTCL_YELLOW_ACTION_NAME
,
342 &next_action_name
)) == 0) {
344 if ((next_action
= ipp_action_lookup(next_action_name
))
345 == IPP_ACTION_INVAL
) {
347 tswtcl0dbg(("tswtcl_modify_action: yellow next_action"\
349 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
352 cfg_parms
->yellow_action
= next_action
;
355 /* parse green action name, if present */
356 if ((err
= nvlist_lookup_string(nvlp
, TSWTCL_GREEN_ACTION_NAME
,
357 &next_action_name
)) == 0) {
359 if ((next_action
= ipp_action_lookup(next_action_name
))
360 == IPP_ACTION_INVAL
) {
362 tswtcl0dbg(("tswtcl_modify_action: green next_action"\
364 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
367 cfg_parms
->green_action
= next_action
;
370 /* parse committed rate, if present */
371 if ((err
= nvlist_lookup_uint32(nvlp
, TSWTCL_COMMITTED_RATE
, &rate
))
373 cfg_parms
->committed_rate
= rate
;
376 /* parse peak rate, if present */
377 if ((err
= nvlist_lookup_uint32(nvlp
, TSWTCL_PEAK_RATE
, &rate
))
379 cfg_parms
->peak_rate
= rate
;
382 if (cfg_parms
->peak_rate
< cfg_parms
->committed_rate
) {
384 tswtcl0dbg(("tswtcl_create_action: invalid config, "\
385 " peak rate < committed rate\n"));
386 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
390 /* parse window - in msec */
391 if ((err
= nvlist_lookup_uint32(nvlp
, TSWTCL_WINDOW
,
392 &cfg_parms
->window
)) != 0) {
393 cfg_parms
->nsecwindow
= (uint64_t)cfg_parms
->window
*
397 /* parse stats, if present */
398 if (nvlist_lookup_uint32(nvlp
, IPP_ACTION_STATS_ENABLE
, &bstats
) == 0) {
399 cfg_parms
->stats
= (boolean_t
)bstats
;
400 if (cfg_parms
->stats
&& !old_cfg
->stats
) {
401 if ((err
= tswtcl_statinit(aid
, tswtcl_data
)) != 0) {
403 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
406 } else if (!cfg_parms
->stats
&& old_cfg
->stats
) {
407 ipp_stat_destroy(tswtcl_data
->stats
);
411 /* Can we ref all the new actions? */
412 if ((err
= ipp_action_ref(aid
, cfg_parms
->red_action
, flags
)) != 0) {
413 tswtcl0dbg(("tswtcl_modify_data: can't ref. red action\n"));
415 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
419 if ((err
= ipp_action_ref(aid
, cfg_parms
->yellow_action
, flags
)) != 0) {
420 tswtcl0dbg(("tswtcl_modify_data:can't ref. yellow action\n"));
422 err2
= ipp_action_unref(aid
, cfg_parms
->red_action
, flags
);
424 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
428 if ((err
= ipp_action_ref(aid
, cfg_parms
->green_action
, flags
)) != 0) {
429 tswtcl0dbg(("tswtcl_modify_data:can't ref. green action\n"));
431 err2
= ipp_action_unref(aid
, cfg_parms
->red_action
, flags
);
433 err2
= ipp_action_unref(aid
, cfg_parms
->yellow_action
, flags
);
435 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
439 /* Re-compute pminusc */
440 cfg_parms
->pminusc
= cfg_parms
->peak_rate
- cfg_parms
->committed_rate
;
442 /* Actually modify the configuration */
443 mutex_enter(&tswtcl_data
->tswtcl_lock
);
444 tswtcl_data
->cfg_parms
= cfg_parms
;
445 mutex_exit(&tswtcl_data
->tswtcl_lock
);
447 /* Un-ref the old actions */
448 err
= ipp_action_unref(aid
, old_cfg
->red_action
, flags
);
450 err
= ipp_action_unref(aid
, old_cfg
->yellow_action
, flags
);
452 err
= ipp_action_unref(aid
, old_cfg
->green_action
, flags
);
455 /* Free the old configuration */
456 kmem_free(old_cfg
, TSWTCL_CFG_SZ
);
464 tswtcl_destroy_action(ipp_action_id_t aid
, ipp_flags_t flags
)
466 tswtcl_data_t
*tswtcl_data
;
467 tswtcl_cfg_t
*cfg_parms
;
470 tswtcl_data
= (tswtcl_data_t
*)ipp_action_get_ptr(aid
);
471 ASSERT(tswtcl_data
!= NULL
);
473 cfg_parms
= tswtcl_data
->cfg_parms
;
475 if (cfg_parms
->stats
) {
476 ipp_stat_destroy(tswtcl_data
->stats
);
479 /* unreference the action */
480 rc
= ipp_action_unref(aid
, cfg_parms
->red_action
, flags
);
482 rc
= ipp_action_unref(aid
, cfg_parms
->yellow_action
, flags
);
484 rc
= ipp_action_unref(aid
, cfg_parms
->green_action
, flags
);
487 mutex_destroy(&tswtcl_data
->tswtcl_lock
);
488 kmem_free(cfg_parms
, TSWTCL_CFG_SZ
);
489 kmem_free(tswtcl_data
, TSWTCL_DATA_SZ
);
494 tswtcl_invoke_action(ipp_action_id_t aid
, ipp_packet_t
*packet
)
496 tswtcl_data_t
*tswtcl_data
;
497 ipp_action_id_t next_action
;
501 /* get mblk from ipp_packet structure */
502 mp
= ipp_packet_get_data(packet
);
503 tswtcl_data
= (tswtcl_data_t
*)ipp_action_get_ptr(aid
);
504 ASSERT(tswtcl_data
!= NULL
);
506 /* tswtcl packet as configured */
507 if ((rc
= tswtcl_process(&mp
, tswtcl_data
, &next_action
)) != 0) {
510 return (ipp_packet_next(packet
, next_action
));
515 tswtcl_statinit(ipp_action_id_t aid
, tswtcl_data_t
*tswtcl_data
)
518 meter_stat_t
*statsp
;
520 /* install stats entry */
521 if ((rc
= ipp_stat_create(aid
, TSWTCL_STATS_STRING
, METER_STATS_COUNT
,
522 tswtcl_update_stats
, tswtcl_data
, &tswtcl_data
->stats
)) != 0) {
523 tswtcl0dbg(("tswtcl_statinit:ipp_stat_create failed "\
528 statsp
= (meter_stat_t
*)(tswtcl_data
->stats
)->ipps_data
;
529 ASSERT(statsp
!= NULL
);
531 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "red_packets",
532 IPP_STAT_UINT64
, &statsp
->red_packets
)) != 0) {
533 tswtcl0dbg(("tswtcl_statinit:ipp_stat_create failed "\
537 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "red_bits",
538 IPP_STAT_UINT64
, &statsp
->red_bits
)) != 0) {
539 tswtcl0dbg(("tswtcl_statinit:ipp_stat_create failed "\
543 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "yellow_packets",
544 IPP_STAT_UINT64
, &statsp
->yellow_packets
)) != 0) {
545 tswtcl0dbg(("tswtcl_statinit:ipp_stat_named_init failed "\
549 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "yellow_bits",
550 IPP_STAT_UINT64
, &statsp
->yellow_bits
)) != 0) {
551 tswtcl0dbg(("tswtcl_statinit:ipp_stat_create failed "\
555 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "green_packets",
556 IPP_STAT_UINT64
, &statsp
->green_packets
)) != 0) {
557 tswtcl0dbg(("tswtcl_statinit:ipp_stat_named_init failed "\
561 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "green_bits",
562 IPP_STAT_UINT64
, &statsp
->green_bits
)) != 0) {
563 tswtcl0dbg(("tswtcl_statinit:ipp_stat_create failed "\
567 if ((rc
= ipp_stat_named_init(tswtcl_data
->stats
, "epackets",
568 IPP_STAT_UINT64
, &statsp
->epackets
)) != 0) {
569 tswtcl0dbg(("tswtcl_statinit:ipp_stat_named_init failed "\
573 ipp_stat_install(tswtcl_data
->stats
);
580 tswtcl_update_stats(ipp_stat_t
*sp
, void *args
, int rw
)
582 tswtcl_data_t
*tswtcl_data
= (tswtcl_data_t
*)args
;
583 meter_stat_t
*stats
= (meter_stat_t
*)sp
->ipps_data
;
585 ASSERT((tswtcl_data
!= NULL
) && (stats
!= NULL
));
587 (void) ipp_stat_named_op(&stats
->red_packets
, &tswtcl_data
->red_packets
,
589 (void) ipp_stat_named_op(&stats
->yellow_packets
,
590 &tswtcl_data
->yellow_packets
, rw
);
591 (void) ipp_stat_named_op(&stats
->green_packets
,
592 &tswtcl_data
->green_packets
, rw
);
594 (void) ipp_stat_named_op(&stats
->red_bits
, &tswtcl_data
->red_bits
, rw
);
595 (void) ipp_stat_named_op(&stats
->yellow_bits
,
596 &tswtcl_data
->yellow_bits
, rw
);
597 (void) ipp_stat_named_op(&stats
->green_bits
,
598 &tswtcl_data
->green_bits
, rw
);
600 (void) ipp_stat_named_op(&stats
->epackets
, &tswtcl_data
->epackets
,
608 tswtcl_info(ipp_action_id_t aid
, int (*fn
)(nvlist_t
*, void *), void *arg
,
612 tswtcl_data_t
*tswtcl_data
;
613 tswtcl_cfg_t
*cfg_parms
;
617 tswtcl_data
= (tswtcl_data_t
*)ipp_action_get_ptr(aid
);
618 ASSERT(tswtcl_data
!= NULL
);
620 cfg_parms
= tswtcl_data
->cfg_parms
;
622 /* allocate nvlist to be passed back */
623 if ((rc
= nvlist_alloc(&nvlp
, NV_UNIQUE_NAME
, KM_NOSLEEP
)) != 0) {
624 tswtcl0dbg(("tswtcl_info: memory allocation failure\n"));
628 /* look up red next action with the next action id */
629 if ((rc
= ipp_action_name(cfg_parms
->red_action
, &next_action
)) != 0) {
630 tswtcl0dbg(("tswtcl_info: red action not available\n"));
635 /* add next action name */
636 if ((rc
= nvlist_add_string(nvlp
, TSWTCL_RED_ACTION_NAME
,
637 next_action
)) != 0) {
638 tswtcl0dbg(("tswtcl_info: error adding\n"));
640 kmem_free(next_action
, (strlen(next_action
) + 1));
644 /* free action name */
645 kmem_free(next_action
, (strlen(next_action
) + 1));
647 /* look up yellow next action with the next action id */
648 if ((rc
= ipp_action_name(cfg_parms
->yellow_action
,
649 &next_action
)) != 0) {
650 tswtcl0dbg(("tswtcl_info: yellow action not available\n"));
655 /* add next action name */
656 if ((rc
= nvlist_add_string(nvlp
, TSWTCL_YELLOW_ACTION_NAME
,
657 next_action
)) != 0) {
658 tswtcl0dbg(("tswtcl_info: error adding yellow action\n"));
660 kmem_free(next_action
, (strlen(next_action
) + 1));
663 /* free action name */
664 kmem_free(next_action
, (strlen(next_action
) + 1));
666 /* look up green next action with the next action id */
667 if ((rc
= ipp_action_name(cfg_parms
->green_action
,
668 &next_action
)) != 0) {
669 tswtcl0dbg(("tswtcl_info: green action not available\n"));
674 /* add next action name */
675 if ((rc
= nvlist_add_string(nvlp
, TSWTCL_GREEN_ACTION_NAME
,
676 next_action
)) != 0) {
677 tswtcl0dbg(("tswtcl_info: error adding green action\n"));
679 kmem_free(next_action
, (strlen(next_action
) + 1));
683 /* free action name */
684 kmem_free(next_action
, (strlen(next_action
) + 1));
686 /* add config type */
687 if ((rc
= nvlist_add_byte(nvlp
, IPP_CONFIG_TYPE
, IPP_SET
)) != 0) {
688 tswtcl0dbg(("tswtcl_info: error adding config_type\n"));
693 /* add committed_rate */
694 if ((rc
= nvlist_add_uint32(nvlp
, TSWTCL_COMMITTED_RATE
,
695 cfg_parms
->committed_rate
)) != 0) {
696 tswtcl0dbg(("tswtcl_info: error adding committed_rate\n"));
702 if ((rc
= nvlist_add_uint32(nvlp
, TSWTCL_PEAK_RATE
,
703 cfg_parms
->peak_rate
)) != 0) {
704 tswtcl0dbg(("tswtcl_info: error adding peak_rate\n"));
710 if ((rc
= nvlist_add_uint32(nvlp
, TSWTCL_WINDOW
,
711 cfg_parms
->window
)) != 0) {
712 tswtcl0dbg(("tswtcl_info: error adding window\n"));
717 if ((rc
= nvlist_add_uint32(nvlp
, IPP_ACTION_STATS_ENABLE
,
718 (uint32_t)(uintptr_t)tswtcl_data
->stats
)) != 0) {
719 tswtcl0dbg(("tswtcl_info: error adding stats status\n"));
724 /* call back with nvlist */