Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/ipp/meters/tokenmtddi.c
+++ new/usr/src/uts/common/ipp/meters/tokenmtddi.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <sys/atomic.h>
28 28 #include <sys/systm.h>
29 29 #include <sys/socket.h>
30 30 #include <netinet/in.h>
31 31 #include <sys/modctl.h>
32 32 #include <sys/sunddi.h>
33 33 #include <ipp/ipp.h>
34 34 #include <ipp/ipp_config.h>
35 35 #include <inet/common.h>
36 36 #include <ipp/meters/meter_impl.h>
37 37
38 38 #define D_SM_COMMENT "IPP Single-Two Rate Token Meter"
39 39
40 40 /* DDI file for tokenmt ipp module */
41 41
42 42 /* Default DSCP to colour mapping for colour-aware meter */
43 43 enum meter_colour default_dscp_to_colour[64] = {
44 44 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
45 45 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
46 46 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
47 47 TOKENMT_YELLOW, TOKENMT_GREEN, TOKENMT_RED, TOKENMT_GREEN,
48 48 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
49 49 TOKENMT_YELLOW, TOKENMT_GREEN, TOKENMT_RED, TOKENMT_GREEN,
50 50 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
51 51 TOKENMT_YELLOW, TOKENMT_GREEN, TOKENMT_RED, TOKENMT_GREEN,
52 52 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
53 53 TOKENMT_YELLOW, TOKENMT_GREEN, TOKENMT_RED, TOKENMT_GREEN,
54 54 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
55 55 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
56 56 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
57 57 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
58 58 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN,
59 59 TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN, TOKENMT_GREEN
60 60 };
61 61
62 62 static int tokenmt_create_action(ipp_action_id_t, nvlist_t **, ipp_flags_t);
63 63 static int tokenmt_modify_action(ipp_action_id_t, nvlist_t **, ipp_flags_t);
64 64 static int tokenmt_destroy_action(ipp_action_id_t, ipp_flags_t);
65 65 static int tokenmt_info(ipp_action_id_t, int (*)(nvlist_t *, void *), void *,
66 66 ipp_flags_t);
67 67 static int tokenmt_invoke_action(ipp_action_id_t, ipp_packet_t *);
68 68
69 69 /* Initialize stats */
70 70 static int tokenmt_statinit(ipp_action_id_t, tokenmt_data_t *);
71 71
72 72 /* Stats callback function */
73 73 static int tokenmt_update_stats(ipp_stat_t *, void *, int);
74 74
75 75 ipp_ops_t tokenmt_ops = {
76 76 IPPO_REV,
77 77 tokenmt_create_action, /* ippo_action_create */
78 78 tokenmt_modify_action, /* ippo_action_modify */
79 79 tokenmt_destroy_action, /* ippo_action_destroy */
80 80 tokenmt_info, /* ippo_action_info */
81 81 tokenmt_invoke_action /* ippo_action_invoke */
82 82 };
83 83
84 84 extern struct mod_ops mod_ippops;
85 85
86 86 /*
↓ open down ↓ |
86 lines elided |
↑ open up ↑ |
87 87 * Module linkage information for the kernel.
88 88 */
89 89 static struct modlipp modlipp = {
90 90 &mod_ippops,
91 91 D_SM_COMMENT,
92 92 &tokenmt_ops
93 93 };
94 94
95 95 static struct modlinkage modlinkage = {
96 96 MODREV_1,
97 - (void *)&modlipp,
98 - NULL
97 + { (void *)&modlipp, NULL }
99 98 };
100 99
101 100
102 101 int
103 102 _init(void)
104 103 {
105 104 return (mod_install(&modlinkage));
106 105 }
107 106
108 107 int
109 108 _fini(void)
110 109 {
111 110 return (mod_remove(&modlinkage));
112 111 }
113 112
114 113 int
115 114 _info(struct modinfo *modinfop)
116 115 {
117 116 return (mod_info(&modlinkage, modinfop));
118 117 }
119 118
120 119 /* ARGSUSED */
121 120 static int
122 121 tokenmt_create_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags)
123 122 {
124 123 nvlist_t *nvlp;
125 124 tokenmt_data_t *tokenmt_data;
126 125 char *next_action;
127 126 tokenmt_cfg_t *cfg_parms;
128 127 uint32_t mode;
129 128 uint32_t bstats;
130 129 int rc, rc2;
131 130 int32_t *colour_tbl;
132 131 uint_t nelem = 64;
133 132
134 133 nvlp = *nvlpp;
135 134 *nvlpp = NULL; /* nvlist should be NULL on return */
136 135
137 136 if ((cfg_parms = kmem_zalloc(TOKENMT_CFG_SZ, KM_NOSLEEP)) == NULL) {
138 137 nvlist_free(nvlp);
139 138 return (ENOMEM);
140 139 }
141 140
142 141 /* parse red next action name */
143 142 if ((rc = nvlist_lookup_string(nvlp, TOKENMT_RED_ACTION_NAME,
144 143 &next_action)) != 0) {
145 144 nvlist_free(nvlp);
146 145 tokenmt0dbg(("tokenmt_create_action:invalid config, red "\
147 146 "action name missing\n"));
148 147 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
149 148 return (rc);
150 149 }
151 150 if ((cfg_parms->red_action = ipp_action_lookup(next_action))
152 151 == IPP_ACTION_INVAL) {
153 152 nvlist_free(nvlp);
154 153 tokenmt0dbg(("tokenmt_create_action: red action invalid\n"));
155 154 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
156 155 return (EINVAL);
157 156 }
158 157
159 158 /* parse yellow next action name, if present this is Two Rate meter */
160 159 if ((rc = nvlist_lookup_string(nvlp, TOKENMT_YELLOW_ACTION_NAME,
161 160 &next_action)) == 0) {
162 161 if ((cfg_parms->yellow_action = ipp_action_lookup(next_action))
163 162 == IPP_ACTION_INVAL) {
164 163 nvlist_free(nvlp);
165 164 tokenmt0dbg(("tokenmt_create_action: yellow action "\
166 165 "invalid\n"));
167 166 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
168 167 return (EINVAL);
169 168 }
170 169 } else {
171 170 cfg_parms->yellow_action = TOKENMT_NO_ACTION;
172 171 }
173 172
174 173 /* parse green next action name */
175 174 if ((rc = nvlist_lookup_string(nvlp, TOKENMT_GREEN_ACTION_NAME,
176 175 &next_action)) != 0) {
177 176 nvlist_free(nvlp);
178 177 tokenmt0dbg(("tokenmt_create_action:invalid config, green " \
179 178 "action name missing\n"));
180 179 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
181 180 return (rc);
182 181 }
183 182 if ((cfg_parms->green_action = ipp_action_lookup(next_action))
184 183 == IPP_ACTION_INVAL) {
185 184 nvlist_free(nvlp);
186 185 tokenmt0dbg(("tokenmt_create_action: green action invalid\n"));
187 186 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
188 187 return (EINVAL);
189 188 }
190 189
191 190 /* parse committed rate - in kilo bits / sec */
192 191 if ((rc = nvlist_lookup_uint32(nvlp, TOKENMT_COMMITTED_RATE,
193 192 &cfg_parms->committed_rate)) != 0) {
194 193 nvlist_free(nvlp);
195 194 tokenmt0dbg(("tokenmt_create_action: invalid config, "\
196 195 " committed rate missing\n"));
197 196 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
198 197 return (rc);
199 198 }
200 199 if (cfg_parms->committed_rate == 0) {
201 200 nvlist_free(nvlp);
202 201 tokenmt0dbg(("tokenmt_create_action: invalid committed rate, "\
203 202 "%u\n", cfg_parms->committed_rate));
204 203 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
205 204 return (EINVAL);
206 205 }
207 206
208 207 /* parse committed burst in bits */
209 208 if ((rc = nvlist_lookup_uint32(nvlp, TOKENMT_COMMITTED_BURST,
210 209 &cfg_parms->committed_burst)) != 0) {
211 210 nvlist_free(nvlp);
212 211 tokenmt0dbg(("tokenmt_create_action: invalid config, "\
213 212 " committed burst missing\n"));
214 213 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
215 214 return (rc);
216 215 }
217 216
218 217
219 218 /*
220 219 * If the peak burst size is specified, make sure we have the
221 220 * yellow action.
222 221 */
223 222 if ((rc = nvlist_lookup_uint32(nvlp, TOKENMT_PEAK_BURST,
224 223 &cfg_parms->peak_burst)) == 0) {
225 224 if (cfg_parms->yellow_action == TOKENMT_NO_ACTION) {
226 225 nvlist_free(nvlp);
227 226 tokenmt0dbg(("tokenmt_create_action: peak burst "\
228 227 "specified without yellow action\n"));
229 228 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
230 229 return (EINVAL);
231 230 }
232 231 } else if (cfg_parms->yellow_action != TOKENMT_NO_ACTION) {
233 232 nvlist_free(nvlp);
234 233 tokenmt0dbg(("tokenmt_create_action: peak burst must be "\
235 234 "provided with yellow action\n"));
236 235 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
237 236 return (EINVAL);
238 237 }
239 238
240 239 /* Check if we have a peak_rate */
241 240 if ((rc = nvlist_lookup_uint32(nvlp, TOKENMT_PEAK_RATE,
242 241 &cfg_parms->peak_rate)) == 0) {
243 242 if (cfg_parms->yellow_action == TOKENMT_NO_ACTION) {
244 243 nvlist_free(nvlp);
245 244 tokenmt0dbg(("tokenmt_create_action: peak rate "\
246 245 "specified without yellow action\n"));
247 246 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
248 247 return (EINVAL);
249 248 } else if ((cfg_parms->peak_rate == 0) ||
250 249 (cfg_parms->peak_rate < cfg_parms->committed_rate)) {
251 250 nvlist_free(nvlp);
252 251 tokenmt0dbg(("tokenmt_create_action: invalid "\
253 252 "peak rate, %u\n", cfg_parms->peak_rate));
254 253 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
255 254 return (EINVAL);
256 255 }
257 256 cfg_parms->tokenmt_type = TRTCL_TOKENMT;
258 257 } else {
259 258 cfg_parms->tokenmt_type = SRTCL_TOKENMT;
260 259 }
261 260
262 261 /* Validate the committed and peak burst size */
263 262 if (cfg_parms->tokenmt_type == SRTCL_TOKENMT) {
264 263 if ((cfg_parms->committed_burst == 0) &&
265 264 (cfg_parms->peak_burst == 0)) {
266 265 nvlist_free(nvlp);
267 266 tokenmt0dbg(("tokenmt_create_action: at least one "\
268 267 "burst size must be non-zero\n"));
269 268 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
270 269 return (EINVAL);
271 270 }
272 271 } else { /* TRTCL_TOKENMT */
273 272 if ((cfg_parms->committed_burst == 0) ||
274 273 (cfg_parms->peak_burst == 0)) {
275 274 nvlist_free(nvlp);
276 275 tokenmt0dbg(("tokenmt_create_action: both the "\
277 276 "burst sizes must be non-zero\n"));
278 277 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
279 278 return (EINVAL);
280 279 }
281 280 }
282 281
283 282 /* just copy default colour mapping */
284 283 bcopy(default_dscp_to_colour, cfg_parms->dscp_to_colour,
285 284 sizeof (default_dscp_to_colour));
286 285
287 286 /* parse mode, if present */
288 287 if ((rc = nvlist_lookup_uint32(nvlp, TOKENMT_COLOUR_AWARE,
289 288 &mode)) != 0) {
290 289 cfg_parms->colour_aware = B_FALSE;
291 290 } else {
292 291 cfg_parms->colour_aware = (mode == 0) ? B_FALSE : B_TRUE;
293 292 }
294 293
295 294 /* Get the dscp to colour mapping array */
296 295 if (cfg_parms->colour_aware) {
297 296 if ((rc = nvlist_lookup_int32_array(nvlp,
298 297 TOKENMT_COLOUR_MAP, &colour_tbl, &nelem)) == 0) {
299 298 int count;
300 299 for (count = 0; count < 64; count++) {
301 300 if (colour_tbl[count] == -1)
302 301 continue;
303 302 cfg_parms->dscp_to_colour[count] =
304 303 colour_tbl[count];
305 304 }
306 305 }
307 306 }
308 307
309 308 /* parse stats */
310 309 if ((rc = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats))
311 310 != 0) {
312 311 cfg_parms->stats = B_FALSE;
313 312 } else {
314 313 cfg_parms->stats = (bstats == 0) ? B_FALSE : B_TRUE;
315 314 }
316 315
317 316 nvlist_free(nvlp);
318 317
319 318 /* Initialize other stuff */
320 319 tokenmt_data = kmem_zalloc(TOKENMT_DATA_SZ, KM_NOSLEEP);
321 320 if (tokenmt_data == NULL) {
322 321 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
323 322 return (ENOMEM);
324 323 }
325 324
326 325 /* Initialize stats, if required */
327 326 if (cfg_parms->stats) {
328 327 if ((rc = tokenmt_statinit(aid, tokenmt_data)) != 0) {
329 328 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
330 329 kmem_free(tokenmt_data, TOKENMT_DATA_SZ);
331 330 return (rc);
332 331 }
333 332 }
334 333
335 334 /* set action chain reference */
336 335 if ((rc = ipp_action_ref(aid, cfg_parms->red_action, flags)) != 0) {
337 336 tokenmt0dbg(("tokenmt_create_action: ipp_action_ref " \
338 337 "returned with error %d", rc));
339 338 goto cleanup;
340 339 }
341 340 if ((rc = ipp_action_ref(aid, cfg_parms->green_action, flags)) != 0) {
342 341 tokenmt0dbg(("tokenmt_create_action: ipp_action_ref " \
343 342 "returned with error %d", rc));
344 343 rc2 = ipp_action_unref(aid, cfg_parms->red_action, flags);
345 344 ASSERT(rc2 == 0);
346 345 goto cleanup;
347 346 }
348 347
349 348 if (cfg_parms->yellow_action != TOKENMT_NO_ACTION) {
350 349 if ((rc = ipp_action_ref(aid, cfg_parms->yellow_action,
351 350 flags)) != 0) {
352 351 tokenmt0dbg(("tokenmt_create_action: ipp_action_ref "\
353 352 "returned with error %d", rc));
354 353 rc2 = ipp_action_unref(aid, cfg_parms->red_action,
355 354 flags);
356 355 ASSERT(rc2 == 0);
357 356 rc2 = ipp_action_unref(aid, cfg_parms->green_action,
358 357 flags);
359 358 ASSERT(rc2 == 0);
360 359 goto cleanup;
361 360 }
362 361 }
363 362
364 363
365 364 tokenmt_data->cfg_parms = cfg_parms;
366 365
367 366 tokenmt_data->committed_tokens = cfg_parms->committed_burst;
368 367 tokenmt_data->peak_tokens = cfg_parms->peak_burst;
369 368 tokenmt_data->last_seen = gethrtime();
370 369
371 370 mutex_init(&tokenmt_data->tokenmt_lock, NULL, MUTEX_DEFAULT, 0);
372 371 ipp_action_set_ptr(aid, (void *)tokenmt_data);
373 372 return (0);
374 373
375 374 cleanup:
376 375 if (cfg_parms->stats) {
377 376 ipp_stat_destroy(tokenmt_data->stats);
378 377 }
379 378 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
380 379 kmem_free(tokenmt_data, TOKENMT_DATA_SZ);
381 380 return (rc);
382 381 }
383 382
384 383 static int
385 384 tokenmt_modify_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags)
386 385 {
387 386 nvlist_t *nvlp;
388 387 int err = 0, err2;
389 388 uint8_t config_type;
390 389 char *next_action_name;
391 390 ipp_action_id_t next_action;
392 391 uint32_t rate, cbs, pbs;
393 392 tokenmt_cfg_t *cfg_parms, *old_cfg;
394 393 tokenmt_data_t *tokenmt_data;
395 394 uint32_t bstats, mode;
396 395 int32_t *colour_tbl;
397 396 uint_t nelem = 64;
398 397
399 398 nvlp = *nvlpp;
400 399 *nvlpp = NULL; /* nvlist should be NULL when this returns */
401 400
402 401 if ((err = nvlist_lookup_byte(nvlp, IPP_CONFIG_TYPE, &config_type))
403 402 != 0) {
404 403 nvlist_free(nvlp);
405 404 tokenmt0dbg(("tokenmt_modify_action: invalid configuration "\
406 405 "type"));
407 406 return (err);
408 407 }
409 408
410 409 if (config_type != IPP_SET) {
411 410 nvlist_free(nvlp);
412 411 tokenmt0dbg(("tokenmt_modify_action: invalid configuration "\
413 412 "type %d", config_type));
414 413 return (EINVAL);
415 414 }
416 415
417 416 tokenmt_data = (tokenmt_data_t *)ipp_action_get_ptr(aid);
418 417 old_cfg = tokenmt_data->cfg_parms;
419 418
420 419 cfg_parms = kmem_zalloc(TOKENMT_CFG_SZ, KM_NOSLEEP);
421 420 if (cfg_parms == NULL) {
422 421 nvlist_free(nvlp);
423 422 tokenmt0dbg(("tokenmt_modify_action: memory allocation "\
424 423 "failure\n"));
425 424 return (ENOMEM);
426 425 }
427 426
428 427 /* Just copy all and change as needed */
429 428 bcopy(old_cfg, cfg_parms, TOKENMT_CFG_SZ);
430 429
431 430 /* parse red action name, if present */
432 431 if ((err = nvlist_lookup_string(nvlp, TOKENMT_RED_ACTION_NAME,
433 432 &next_action_name)) == 0) {
434 433 /* Get action id */
435 434 if ((next_action = ipp_action_lookup(next_action_name))
436 435 == IPP_ACTION_INVAL) {
437 436 nvlist_free(nvlp);
438 437 tokenmt0dbg(("tokenmt_modify_action: next_action "\
439 438 "invalid"));
440 439 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
441 440 return (EINVAL);
442 441 }
443 442 cfg_parms->red_action = next_action;
444 443 }
445 444
446 445 /* parse yellow action name, if present */
447 446 if ((err = nvlist_lookup_string(nvlp, TOKENMT_YELLOW_ACTION_NAME,
448 447 &next_action_name)) == 0) {
449 448 /* Get action id */
450 449 if ((next_action = ipp_action_lookup(next_action_name))
451 450 == IPP_ACTION_INVAL) {
452 451 nvlist_free(nvlp);
453 452 tokenmt0dbg(("tokenmt_modify_action: next_action "\
454 453 "invalid"));
455 454 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
456 455 return (EINVAL);
457 456 }
458 457 cfg_parms->yellow_action = next_action;
459 458 } else {
460 459 cfg_parms->yellow_action = TOKENMT_NO_ACTION;
461 460 }
462 461
463 462 /* parse green action name, if present */
464 463 if ((err = nvlist_lookup_string(nvlp, TOKENMT_GREEN_ACTION_NAME,
465 464 &next_action_name)) == 0) {
466 465 /* Get action id */
467 466 if ((next_action = ipp_action_lookup(next_action_name))
468 467 == IPP_ACTION_INVAL) {
469 468 nvlist_free(nvlp);
470 469 tokenmt0dbg(("tokenmt_modify_action: next_action "\
471 470 "invalid"));
472 471 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
473 472 return (EINVAL);
474 473 }
475 474 cfg_parms->green_action = next_action;
476 475 }
477 476
478 477 /* parse committed rate, if present */
479 478 if ((err = nvlist_lookup_uint32(nvlp, TOKENMT_COMMITTED_RATE, &rate))
480 479 == 0) {
481 480 if (rate == 0) {
482 481 nvlist_free(nvlp);
483 482 tokenmt0dbg(("tokenmt_modify_action: invalid "\
484 483 "committed rate %u\n", cfg_parms->committed_rate));
485 484 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
486 485 return (EINVAL);
487 486 }
488 487 cfg_parms->committed_rate = rate;
489 488 }
490 489
491 490 /* parse committed burst, if present */
492 491 if (nvlist_lookup_uint32(nvlp, TOKENMT_COMMITTED_BURST, &cbs) == 0) {
493 492 cfg_parms->committed_burst = cbs;
494 493 }
495 494
496 495
497 496 if (nvlist_lookup_uint32(nvlp, TOKENMT_PEAK_BURST, &pbs) == 0) {
498 497 cfg_parms->peak_burst = pbs;
499 498 } else {
500 499 cfg_parms->peak_burst = 0;
501 500 }
502 501
503 502 /* If the peak rate is not specified, then it means single rate meter */
504 503 if (nvlist_lookup_uint32(nvlp, TOKENMT_PEAK_RATE, &rate) == 0) {
505 504 cfg_parms->peak_rate = rate;
506 505 if ((rate == 0) || (rate < cfg_parms->committed_rate)) {
507 506 nvlist_free(nvlp);
508 507 tokenmt0dbg(("tokenmt_modify_action: invalid "\
509 508 "committed rate %u\n", cfg_parms->committed_rate));
510 509 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
511 510 return (EINVAL);
512 511 }
513 512 cfg_parms->tokenmt_type = TRTCL_TOKENMT;
514 513 } else {
515 514 cfg_parms->peak_rate = 0;
516 515 cfg_parms->tokenmt_type = SRTCL_TOKENMT;
517 516 }
518 517
519 518 if (cfg_parms->yellow_action == TOKENMT_NO_ACTION) {
520 519 if ((cfg_parms->peak_burst != 0) ||
521 520 (cfg_parms->tokenmt_type == TRTCL_TOKENMT)) {
522 521 nvlist_free(nvlp);
523 522 tokenmt0dbg(("tokenmt_modify_action: yellow action "\
524 523 "missing\n"));
525 524 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
526 525 return (EINVAL);
527 526 }
528 527 } else {
529 528 if ((cfg_parms->tokenmt_type != TRTCL_TOKENMT) &&
530 529 (cfg_parms->peak_burst == 0)) {
531 530 nvlist_free(nvlp);
532 531 tokenmt0dbg(("tokenmt_modify_action: peak "\
533 532 "burst/rate missing\n"));
534 533 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
535 534 return (EINVAL);
536 535 }
537 536 }
538 537
539 538 /* Validate the committed and peak burst size */
540 539 if (cfg_parms->tokenmt_type == SRTCL_TOKENMT) {
541 540 if ((cfg_parms->committed_burst == 0) &&
542 541 (cfg_parms->peak_burst == 0)) {
543 542 nvlist_free(nvlp);
544 543 tokenmt0dbg(("tokenmt_modify_action: at least one "\
545 544 "burst size must be non-zero\n"));
546 545 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
547 546 return (EINVAL);
548 547 }
549 548 } else { /* TRTCL_TOKENMT */
550 549 if ((cfg_parms->committed_burst == 0) ||
551 550 (cfg_parms->peak_burst == 0)) {
552 551 nvlist_free(nvlp);
553 552 tokenmt0dbg(("tokenmt_modify_action: both the "\
554 553 "burst sizes must be non-zero\n"));
555 554 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
556 555 return (EINVAL);
557 556 }
558 557 }
559 558
560 559 /* parse mode */
561 560 if (nvlist_lookup_uint32(nvlp, TOKENMT_COLOUR_AWARE, &mode) == 0) {
562 561 cfg_parms->colour_aware = (mode == 0) ? B_FALSE : B_TRUE;
563 562 } else {
564 563 cfg_parms->colour_aware = B_FALSE;
565 564 }
566 565
567 566 if (cfg_parms->colour_aware) {
568 567 if (nvlist_lookup_int32_array(nvlp, TOKENMT_COLOUR_MAP,
569 568 &colour_tbl, &nelem) == 0) {
570 569 int count;
571 570 for (count = 0; count < 64; count++) {
572 571 if (colour_tbl[count] == -1)
573 572 continue;
574 573 cfg_parms->dscp_to_colour[count] =
575 574 colour_tbl[count];
576 575 }
577 576 } else {
578 577 bcopy(default_dscp_to_colour, cfg_parms->dscp_to_colour,
579 578 sizeof (default_dscp_to_colour));
580 579 }
581 580 }
582 581
583 582 /* parse stats, if present */
584 583 if (nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats) == 0) {
585 584 cfg_parms->stats = (bstats == 0) ? B_FALSE : B_TRUE;
586 585 if (cfg_parms->stats && !old_cfg->stats) {
587 586 if ((err = tokenmt_statinit(aid, tokenmt_data)) != 0) {
588 587 nvlist_free(nvlp);
589 588 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
590 589 return (err);
591 590 }
592 591 } else if (!cfg_parms->stats && old_cfg->stats) {
593 592 ipp_stat_destroy(tokenmt_data->stats);
594 593 }
595 594 }
596 595
597 596 /* Can we ref all the new actions? */
598 597 if ((err = ipp_action_ref(aid, cfg_parms->red_action, flags)) != 0) {
599 598 tokenmt0dbg(("tokenmt_modify_data: can't ref. red action\n"));
600 599 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
601 600 return (err);
602 601 }
603 602 if ((err = ipp_action_ref(aid, cfg_parms->green_action, flags)) != 0) {
604 603 tokenmt0dbg(("tokenmt_modify_data:can't ref. green action\n"));
605 604 err2 = ipp_action_unref(aid, cfg_parms->red_action, flags);
606 605 ASSERT(err2 == 0);
607 606 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
608 607 return (err);
609 608 }
610 609
611 610 if (cfg_parms->yellow_action != TOKENMT_NO_ACTION) {
612 611 if ((err = ipp_action_ref(aid, cfg_parms->yellow_action,
613 612 flags)) != 0) {
614 613 tokenmt0dbg(("tokenmt_modify_data:can't ref. yellow "\
615 614 "action\n"));
616 615 err2 = ipp_action_unref(aid, cfg_parms->red_action,
617 616 flags);
618 617 ASSERT(err2 == 0);
619 618 err2 = ipp_action_unref(aid, cfg_parms->green_action,
620 619 flags);
621 620 ASSERT(err2 == 0);
622 621 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
623 622 return (err);
624 623 }
625 624 }
626 625
627 626
628 627 /* Actually modify the configuration */
629 628 mutex_enter(&tokenmt_data->tokenmt_lock);
630 629 tokenmt_data->cfg_parms = cfg_parms;
631 630 mutex_exit(&tokenmt_data->tokenmt_lock);
632 631
633 632 /* Un-ref the old actions */
634 633 err = ipp_action_unref(aid, old_cfg->red_action, flags);
635 634 ASSERT(err == 0);
636 635 if (old_cfg->yellow_action != TOKENMT_NO_ACTION) {
637 636 err = ipp_action_unref(aid, old_cfg->yellow_action, flags);
638 637 ASSERT(err == 0);
639 638 }
640 639 err = ipp_action_unref(aid, old_cfg->green_action, flags);
641 640 ASSERT(err == 0);
642 641
643 642 /* Free the old configuration */
644 643 kmem_free(old_cfg, TOKENMT_CFG_SZ);
645 644 return (0);
646 645 }
647 646
648 647 static int
649 648 tokenmt_destroy_action(ipp_action_id_t aid, ipp_flags_t flags)
650 649 {
651 650 tokenmt_data_t *tokenmt_data;
652 651 tokenmt_cfg_t *cfg_parms;
653 652 int rc;
654 653
655 654 tokenmt_data = (tokenmt_data_t *)ipp_action_get_ptr(aid);
656 655 ASSERT(tokenmt_data != NULL);
657 656
658 657 cfg_parms = tokenmt_data->cfg_parms;
659 658
660 659 if (cfg_parms->stats) {
661 660 ipp_stat_destroy(tokenmt_data->stats);
662 661 }
663 662
664 663 /* unreference the action */
665 664 rc = ipp_action_unref(aid, cfg_parms->red_action, flags);
666 665 ASSERT(rc == 0);
667 666 if (cfg_parms->yellow_action != TOKENMT_NO_ACTION) {
668 667 rc = ipp_action_unref(aid, cfg_parms->yellow_action, flags);
669 668 ASSERT(rc == 0);
670 669 }
671 670 rc = ipp_action_unref(aid, cfg_parms->green_action, flags);
672 671 ASSERT(rc == 0);
673 672
674 673 mutex_destroy(&tokenmt_data->tokenmt_lock);
675 674 kmem_free(cfg_parms, TOKENMT_CFG_SZ);
676 675 kmem_free(tokenmt_data, TOKENMT_DATA_SZ);
677 676 return (0);
678 677 }
679 678
680 679 static int
681 680 tokenmt_invoke_action(ipp_action_id_t aid, ipp_packet_t *packet)
682 681 {
683 682 tokenmt_data_t *tokenmt_data;
684 683 ipp_action_id_t next_action;
685 684 mblk_t *mp = NULL;
686 685 int rc;
687 686
688 687 /* get mblk from ipp_packet structure */
689 688 mp = ipp_packet_get_data(packet);
690 689 tokenmt_data = (tokenmt_data_t *)ipp_action_get_ptr(aid);
691 690 ASSERT(tokenmt_data != NULL);
692 691
693 692 /* meter packet as configured */
694 693 if ((rc = tokenmt_process(&mp, tokenmt_data, &next_action)) != 0) {
695 694 return (rc);
696 695 } else {
697 696 return (ipp_packet_next(packet, next_action));
698 697 }
699 698 }
700 699
701 700 static int
702 701 tokenmt_statinit(ipp_action_id_t aid, tokenmt_data_t *tokenmt_data) {
703 702
704 703 int rc = 0;
705 704 meter_stat_t *statsp;
706 705
707 706 /* install stats entry */
708 707 if ((rc = ipp_stat_create(aid, TOKENMT_STATS_STRING, METER_STATS_COUNT,
709 708 tokenmt_update_stats, tokenmt_data, &tokenmt_data->stats)) != 0) {
710 709 tokenmt0dbg(("tokenmt_statinit: ipp_stat_create failed "\
711 710 " with %d\n", rc));
712 711 return (rc);
713 712 }
714 713
715 714 statsp = (meter_stat_t *)(tokenmt_data->stats)->ipps_data;
716 715 ASSERT(statsp != NULL);
717 716
718 717 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "red_packets",
719 718 IPP_STAT_UINT64, &statsp->red_packets)) != 0) {
720 719 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
721 720 " with %d\n", rc));
722 721 return (rc);
723 722 }
724 723 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "yellow_packets",
725 724 IPP_STAT_UINT64, &statsp->yellow_packets)) != 0) {
726 725 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
727 726 " with %d\n", rc));
728 727 return (rc);
729 728 }
730 729 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "green_packets",
731 730 IPP_STAT_UINT64, &statsp->green_packets)) != 0) {
732 731 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
733 732 " with %d\n", rc));
734 733 return (rc);
735 734 }
736 735 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "red_bits",
737 736 IPP_STAT_UINT64, &statsp->red_bits)) != 0) {
738 737 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
739 738 " with %d\n", rc));
740 739 return (rc);
741 740 }
742 741 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "yellow_bits",
743 742 IPP_STAT_UINT64, &statsp->yellow_bits)) != 0) {
744 743 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
745 744 " with %d\n", rc));
746 745 return (rc);
747 746 }
748 747 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "green_bits",
749 748 IPP_STAT_UINT64, &statsp->green_bits)) != 0) {
750 749 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
751 750 " with %d\n", rc));
752 751 return (rc);
753 752 }
754 753 if ((rc = ipp_stat_named_init(tokenmt_data->stats, "epackets",
755 754 IPP_STAT_UINT64, &statsp->epackets)) != 0) {
756 755 tokenmt0dbg(("tokenmt_statinit:ipp_stat_named_init failed "\
757 756 " with %d\n", rc));
758 757 return (rc);
759 758 }
760 759
761 760 ipp_stat_install(tokenmt_data->stats);
762 761
763 762 return (rc);
764 763 }
765 764
766 765 static int
767 766 tokenmt_update_stats(ipp_stat_t *sp, void *args, int rw)
768 767 {
769 768 tokenmt_data_t *tokenmt_data = (tokenmt_data_t *)args;
770 769 meter_stat_t *stats = (meter_stat_t *)sp->ipps_data;
771 770
772 771 ASSERT((tokenmt_data != NULL) && (stats != NULL));
773 772
774 773 (void) ipp_stat_named_op(&stats->red_packets,
775 774 &tokenmt_data->red_packets, rw);
776 775 (void) ipp_stat_named_op(&stats->yellow_packets,
777 776 &tokenmt_data->yellow_packets, rw);
778 777 (void) ipp_stat_named_op(&stats->green_packets,
779 778 &tokenmt_data->green_packets, rw);
780 779 (void) ipp_stat_named_op(&stats->red_bits,
781 780 &tokenmt_data->red_bits, rw);
782 781 (void) ipp_stat_named_op(&stats->yellow_bits,
783 782 &tokenmt_data->yellow_bits, rw);
784 783 (void) ipp_stat_named_op(&stats->green_bits,
785 784 &tokenmt_data->green_bits, rw);
786 785 (void) ipp_stat_named_op(&stats->epackets, &tokenmt_data->epackets,
787 786 rw);
788 787
789 788 return (0);
790 789 }
791 790
792 791 /* ARGSUSED */
793 792 static int
794 793 tokenmt_info(ipp_action_id_t aid, int (*fn)(nvlist_t *, void *), void *arg,
795 794 ipp_flags_t flags)
796 795 {
797 796 nvlist_t *nvlp;
798 797 tokenmt_data_t *tokenmt_data;
799 798 tokenmt_cfg_t *cfg_parms;
800 799 char *next_action;
801 800 int32_t dscp_to_colour[64];
802 801 int rc;
803 802
804 803 tokenmt_data = (tokenmt_data_t *)ipp_action_get_ptr(aid);
805 804 ASSERT(tokenmt_data != NULL);
806 805
807 806 cfg_parms = tokenmt_data->cfg_parms;
808 807
809 808 /* allocate nvlist to be passed back */
810 809 if ((rc = nvlist_alloc(&nvlp, NV_UNIQUE_NAME, KM_NOSLEEP)) != 0) {
811 810 tokenmt0dbg(("tokenmt_info: memory allocation failure\n"));
812 811 return (rc);
813 812 }
814 813
815 814 /* look up red next action with the next action id */
816 815 if ((rc = ipp_action_name(cfg_parms->red_action, &next_action)) != 0) {
817 816 tokenmt0dbg(("tokenmt_info: red_action not available\n"));
818 817 nvlist_free(nvlp);
819 818 return (rc);
820 819 }
821 820
822 821 /* add next action name */
823 822 if ((rc = nvlist_add_string(nvlp, TOKENMT_RED_ACTION_NAME,
824 823 next_action)) != 0) {
825 824 nvlist_free(nvlp);
826 825 tokenmt0dbg(("tokenmt_info: error adding red_action\n"));
827 826 kmem_free(next_action, (strlen(next_action) + 1));
828 827 return (rc);
829 828 }
830 829
831 830 /* free action name */
832 831 kmem_free(next_action, (strlen(next_action) + 1));
833 832
834 833
835 834 /* look up yellow next action with the next action id */
836 835 if (cfg_parms->yellow_action != TOKENMT_NO_ACTION) {
837 836 if ((rc = ipp_action_name(cfg_parms->yellow_action,
838 837 &next_action)) != 0) {
839 838 tokenmt0dbg(("tokenmt_info: yellow_action not "\
840 839 "available\n"));
841 840 nvlist_free(nvlp);
842 841 return (rc);
843 842 }
844 843 /* add next action name */
845 844 if ((rc = nvlist_add_string(nvlp, TOKENMT_YELLOW_ACTION_NAME,
846 845 next_action)) != 0) {
847 846 nvlist_free(nvlp);
848 847 tokenmt0dbg(("tokenmt_info: error adding "\
849 848 "yellow_action\n"));
850 849 kmem_free(next_action, (strlen(next_action) + 1));
851 850 return (rc);
852 851 }
853 852 /* free action name */
854 853 kmem_free(next_action, (strlen(next_action) + 1));
855 854 }
856 855
857 856 /* look up green next action with the next action id */
858 857 if ((rc = ipp_action_name(cfg_parms->green_action,
859 858 &next_action)) != 0) {
860 859 tokenmt0dbg(("tokenmt_info: green_action not available\n"));
861 860 nvlist_free(nvlp);
862 861 return (rc);
863 862 }
864 863
865 864 /* add next action name */
866 865 if ((rc = nvlist_add_string(nvlp, TOKENMT_GREEN_ACTION_NAME,
867 866 next_action)) != 0) {
868 867 nvlist_free(nvlp);
869 868 tokenmt0dbg(("tokenmt_info: error adding green_action\n"));
870 869 kmem_free(next_action, (strlen(next_action) + 1));
871 870 return (rc);
872 871 }
873 872
874 873 /* free action name */
875 874 kmem_free(next_action, (strlen(next_action) + 1));
876 875
877 876 /* add config type */
878 877 if ((rc = nvlist_add_byte(nvlp, IPP_CONFIG_TYPE, IPP_SET)) != 0) {
879 878 tokenmt0dbg(("tokenmt_info: error adding config_type\n"));
880 879 nvlist_free(nvlp);
881 880 return (rc);
882 881 }
883 882
884 883 /* add committed_rate */
885 884 if ((rc = nvlist_add_uint32(nvlp, TOKENMT_COMMITTED_RATE,
886 885 cfg_parms->committed_rate)) != 0) {
887 886 tokenmt0dbg(("tokenmt_info: error adding committed_rate\n"));
888 887 nvlist_free(nvlp);
889 888 return (rc);
890 889 }
891 890
892 891 if (cfg_parms->tokenmt_type == TRTCL_TOKENMT) {
893 892 /* add peak rate */
894 893 if ((rc = nvlist_add_uint32(nvlp, TOKENMT_PEAK_RATE,
895 894 cfg_parms->peak_rate)) != 0) {
896 895 tokenmt0dbg(("tokenmt_info: error adding peak_rate\n"));
897 896 nvlist_free(nvlp);
898 897 return (rc);
899 898 }
900 899 }
901 900
902 901 /* add committed_burst */
903 902 if ((rc = nvlist_add_uint32(nvlp, TOKENMT_COMMITTED_BURST,
904 903 cfg_parms->committed_burst)) != 0) {
905 904 tokenmt0dbg(("tokenmt_info: error adding committed_burst\n"));
906 905 nvlist_free(nvlp);
907 906 return (rc);
908 907 }
909 908
910 909 /* add peak_burst */
911 910 if (cfg_parms->peak_burst != 0) {
912 911 if ((rc = nvlist_add_uint32(nvlp, TOKENMT_PEAK_BURST,
913 912 cfg_parms->peak_burst)) != 0) {
914 913 tokenmt0dbg(("tokenmt_info: error adding peak "\
915 914 "burst\n"));
916 915 nvlist_free(nvlp);
917 916 return (rc);
918 917 }
919 918 }
920 919
921 920 /* add colour aware */
922 921 if ((rc = nvlist_add_uint32(nvlp, TOKENMT_COLOUR_AWARE,
923 922 cfg_parms->colour_aware)) != 0) {
924 923 tokenmt0dbg(("tokenmt_info: error adding mode\n"));
925 924 nvlist_free(nvlp);
926 925 return (rc);
927 926 }
928 927
929 928 if (cfg_parms->colour_aware) {
930 929 bcopy(cfg_parms->dscp_to_colour, dscp_to_colour,
931 930 sizeof (cfg_parms->dscp_to_colour));
932 931 if ((rc = nvlist_add_int32_array(nvlp, TOKENMT_COLOUR_MAP,
933 932 dscp_to_colour, 64)) != 0) {
934 933 tokenmt0dbg(("tokenmt_info: error adding colour "\
935 934 "array\n"));
936 935 nvlist_free(nvlp);
937 936 return (rc);
938 937 }
939 938 }
940 939
941 940 if ((rc = nvlist_add_uint32(nvlp, IPP_ACTION_STATS_ENABLE,
942 941 (uint32_t)cfg_parms->stats)) != 0) {
943 942 tokenmt0dbg(("tokenmt_info: error adding stats status\n"));
944 943 nvlist_free(nvlp);
945 944 return (rc);
946 945 }
947 946
948 947 /* call back with nvlist */
949 948 rc = fn(nvlp, arg);
950 949
951 950 nvlist_free(nvlp);
952 951 return (rc);
953 952 }
↓ open down ↓ |
845 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX