Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/ipp/flowacct/flowacctddi.c
+++ new/usr/src/uts/common/ipp/flowacct/flowacctddi.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, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 #include <sys/types.h>
30 28 #include <sys/conf.h>
31 29 #include <sys/atomic.h>
32 30 #include <sys/systm.h>
33 31 #include <sys/socket.h>
34 32 #include <sys/spl.h>
35 33 #include <netinet/in.h>
36 34 #include <sys/modctl.h>
37 35 #include <sys/sunddi.h>
38 36 #include <ipp/ipp.h>
39 37 #include <ipp/ipp_config.h>
40 38 #include <inet/common.h>
41 39 #include <ipp/flowacct/flowacct_impl.h>
42 40 #include <sys/ddi.h>
43 41
44 42 #define D_SM_COMMENT "IPP Flow Accounting Module"
45 43
46 44 /* DDI file for flowacct ipp module */
47 45
48 46 static int flowacct_create_action(ipp_action_id_t, nvlist_t **, ipp_flags_t);
49 47 static int flowacct_modify_action(ipp_action_id_t, nvlist_t **, ipp_flags_t);
50 48 static int flowacct_destroy_action(ipp_action_id_t, ipp_flags_t);
51 49 static int flowacct_info(ipp_action_id_t, int (*)(nvlist_t *, void *), void *,
52 50 ipp_flags_t);
53 51 static int flowacct_invoke_action(ipp_action_id_t, ipp_packet_t *);
54 52
55 53 static int update_flowacct_kstats(ipp_stat_t *, void *, int);
56 54
57 55 ipp_ops_t flowacct_ops = {
58 56 IPPO_REV,
59 57 flowacct_create_action, /* ippo_action_create */
60 58 flowacct_modify_action, /* ippo_action_modify */
61 59 flowacct_destroy_action, /* ippo_action_destroy */
62 60 flowacct_info, /* ippo_action_info */
63 61 flowacct_invoke_action /* ippo_action_invoke */
64 62 };
65 63
66 64 extern struct mod_ops mod_ippops;
67 65
68 66 /*
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
69 67 * Module linkage information for the kernel.
70 68 */
71 69 static struct modlipp modlipp = {
72 70 &mod_ippops,
73 71 D_SM_COMMENT " 1.12",
74 72 &flowacct_ops
75 73 };
76 74
77 75 static struct modlinkage modlinkage = {
78 76 MODREV_1,
79 - (void *)&modlipp,
80 - NULL
77 + { (void *)&modlipp, NULL }
81 78 };
82 79
83 80 int
84 81 _init(void)
85 82 {
86 83 return (mod_install(&modlinkage));
87 84 }
88 85
89 86 int
90 87 _fini(void)
91 88 {
92 89 return (mod_remove(&modlinkage));
93 90 }
94 91
95 92 int
96 93 _info(struct modinfo *modinfop)
97 94 {
98 95 return (mod_info(&modlinkage, modinfop));
99 96 }
100 97
101 98 /* Update global stats */
102 99 static int
103 100 update_flowacct_kstats(ipp_stat_t *sp, void *arg, int rw)
104 101 {
105 102 flowacct_data_t *flowacct_data = (flowacct_data_t *)arg;
106 103 flowacct_stat_t *fl_stat = (flowacct_stat_t *)sp->ipps_data;
107 104 ASSERT((fl_stat != NULL) && (flowacct_data != 0));
108 105
109 106 (void) ipp_stat_named_op(&fl_stat->nbytes, &flowacct_data->nbytes, rw);
110 107 (void) ipp_stat_named_op(&fl_stat->tbytes, &flowacct_data->tbytes, rw);
111 108 (void) ipp_stat_named_op(&fl_stat->nflows, &flowacct_data->nflows, rw);
112 109 (void) ipp_stat_named_op(&fl_stat->usedmem, &flowacct_data->usedmem,
113 110 rw);
114 111 (void) ipp_stat_named_op(&fl_stat->npackets, &flowacct_data->npackets,
115 112 rw);
116 113 (void) ipp_stat_named_op(&fl_stat->epackets, &flowacct_data->epackets,
117 114 rw);
118 115 return (0);
119 116 }
120 117
121 118 /* Initialize global stats */
122 119 static int
123 120 global_statinit(ipp_action_id_t aid, flowacct_data_t *flowacct_data)
124 121 {
125 122 flowacct_stat_t *flacct_stat;
126 123 int err = 0;
127 124
128 125 if ((err = ipp_stat_create(aid, FLOWACCT_STATS_STRING,
129 126 FLOWACCT_STATS_COUNT, update_flowacct_kstats, flowacct_data,
130 127 &flowacct_data->stats)) != 0) {
131 128 flowacct0dbg(("global_statinit: error creating flowacct "\
132 129 "stats\n"));
133 130 return (err);
134 131 }
135 132 flacct_stat = (flowacct_stat_t *)(flowacct_data->stats)->ipps_data;
136 133 ASSERT(flacct_stat != NULL);
137 134
138 135 if ((err = ipp_stat_named_init(flowacct_data->stats, "bytes_in_tbl",
139 136 IPP_STAT_UINT64, &flacct_stat->tbytes)) != 0) {
140 137 flowacct0dbg(("global_statinit: ipp_stat_named_init returned "\
141 138 "with error %d\n", err));
142 139 return (err);
143 140 }
144 141 if ((err = ipp_stat_named_init(flowacct_data->stats, "nbytes",
145 142 IPP_STAT_UINT64, &flacct_stat->nbytes)) != 0) {
146 143 flowacct0dbg(("global_statinit: ipp_stat_named_init returned "\
147 144 "with error %d\n", err));
148 145 return (err);
149 146 }
150 147 if ((err = ipp_stat_named_init(flowacct_data->stats, "npackets",
151 148 IPP_STAT_UINT64, &flacct_stat->npackets)) != 0) {
152 149 flowacct0dbg(("global_statinit:ipp_stat_named_init returned "\
153 150 "with error %d\n", err));
154 151 return (err);
155 152 }
156 153 if ((err = ipp_stat_named_init(flowacct_data->stats, "usedmem",
157 154 IPP_STAT_UINT64, &flacct_stat->usedmem)) != 0) {
158 155 flowacct0dbg(("global_statinit:ipp_stat_named_init returned "\
159 156 "with error %d\n", err));
160 157 return (err);
161 158 }
162 159 if ((err = ipp_stat_named_init(flowacct_data->stats, "flows_in_tbl",
163 160 IPP_STAT_UINT32, &flacct_stat->nflows)) != 0) {
164 161 flowacct0dbg(("global_statinit:ipp_stat_named_init returned "\
165 162 "with error %d\n", err));
166 163 return (err);
167 164 }
168 165 if ((err = ipp_stat_named_init(flowacct_data->stats, "epackets",
169 166 IPP_STAT_UINT64, &flacct_stat->epackets)) != 0) {
170 167 flowacct0dbg(("global_statinit:ipp_stat_named_init returned "\
171 168 "with error %d\n", err));
172 169 return (err);
173 170 }
174 171 ipp_stat_install(flowacct_data->stats);
175 172
176 173 return (err);
177 174 }
178 175
179 176 static int
180 177 flowacct_create_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags)
181 178 {
182 179 nvlist_t *nvlp;
183 180 flowacct_data_t *flowacct_data;
184 181 char *next_action;
185 182 int rc, flow_count;
186 183 list_head_t *head;
187 184 uint32_t bstats;
188 185 uint32_t timeout = FLOWACCT_DEF_TIMEOUT;
189 186 uint32_t timer = FLOWACCT_DEF_TIMER;
190 187
191 188 nvlp = *nvlpp;
192 189 *nvlpp = NULL; /* nvlist should be NULL on return */
193 190
194 191 if ((flowacct_data = kmem_zalloc(FLOWACCT_DATA_SZ, KM_NOSLEEP))
195 192 == NULL) {
196 193 nvlist_free(nvlp);
197 194 return (ENOMEM);
198 195 }
199 196
200 197 /* parse next action name */
201 198 if ((rc = nvlist_lookup_string(nvlp, FLOWACCT_NEXT_ACTION_NAME,
202 199 &next_action)) != 0) {
203 200 nvlist_free(nvlp);
204 201 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
205 202 flowacct0dbg(("flowacct_create_action: invalid config, "\
206 203 "next_action missing\n"));
207 204 return (rc);
208 205 }
209 206 if ((flowacct_data->next_action = ipp_action_lookup(next_action))
210 207 == IPP_ACTION_INVAL) {
211 208 nvlist_free(nvlp);
212 209 flowacct0dbg(("flowacct_create_action: invalid next_action\n"));
213 210 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
214 211 return (EINVAL);
215 212 }
216 213
217 214 if ((rc = ipp_action_name(aid, &flowacct_data->act_name)) != 0) {
218 215 nvlist_free(nvlp);
219 216 flowacct0dbg(("flowacct_create_action: invalid next aid\n"));
220 217 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
221 218 return (EINVAL);
222 219 }
223 220
224 221 /* parse flow timeout - in millisec, if present */
225 222 (void) nvlist_lookup_uint32(nvlp, FLOWACCT_TIMEOUT, &timeout);
226 223
227 224 /* Convert to FLOWACCT_MSEC_TO_NSEC */
228 225 flowacct_data->timeout = (uint64_t)timeout * FLOWACCT_MSEC_TO_NSEC;
229 226
230 227 /* parse flow timer - in millisec, if present */
231 228 (void) nvlist_lookup_uint32(nvlp, FLOWACCT_TIMER, &timer);
232 229
233 230 /* Convert to FLOWACCT_MSEC_TO_USEC */
234 231 flowacct_data->timer = (uint64_t)timer * FLOWACCT_MSEC_TO_USEC;
235 232
236 233 if ((rc = nvlist_lookup_uint32(nvlp, FLOWACCT_MAX_LIMIT,
237 234 &flowacct_data->max_limit)) != 0) {
238 235 nvlist_free(nvlp);
239 236 flowacct0dbg(("flowacct_create_action: invalid config, "\
240 237 "max_limit missing\n"));
241 238 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
242 239 return (rc);
243 240 }
244 241
245 242 if ((rc = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE,
246 243 &bstats)) != 0) {
247 244 flowacct_data->global_stats = B_FALSE;
248 245 } else {
249 246 flowacct_data->global_stats = (boolean_t)bstats;
250 247 if (flowacct_data->global_stats) {
251 248 if ((rc = global_statinit(aid, flowacct_data)) != 0) {
252 249 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
253 250 return (rc);
254 251 }
255 252 }
256 253 }
257 254
258 255 nvlist_free(nvlp);
259 256
260 257 /* set action chain reference */
261 258 if ((rc = ipp_action_ref(aid, flowacct_data->next_action,
262 259 flags)) != 0) {
263 260 flowacct0dbg(("flowacct_create_action: ipp_action_ref " \
264 261 "returned with error %d\n", rc));
265 262 if (flowacct_data->stats != NULL) {
266 263 ipp_stat_destroy(flowacct_data->stats);
267 264 }
268 265 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
269 266 return (rc);
270 267 }
271 268
272 269 /* Initialize locks */
273 270 for (flow_count = 0, head = flowacct_data->flows_tbl;
274 271 flow_count < (FLOW_TBL_COUNT + 1); flow_count++, head++) {
275 272 mutex_init(&head->lock, NULL, MUTEX_DEFAULT, 0);
276 273 }
277 274
278 275 ipp_action_set_ptr(aid, (void *)flowacct_data);
279 276 return (0);
280 277 }
281 278
282 279 static int
283 280 flowacct_modify_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags)
284 281 {
285 282 nvlist_t *nvlp;
286 283 int rc = 0;
287 284 uint8_t config_type;
288 285 char *next_action_name, *act_name;
289 286 ipp_action_id_t next_action;
290 287 uint32_t timeout, timer, bstats, max_limit;
291 288 flowacct_data_t *flowacct_data;
292 289
293 290 nvlp = *nvlpp;
294 291 *nvlpp = NULL; /* nvlist should be NULL when this returns */
295 292
296 293 if ((rc = nvlist_lookup_byte(nvlp, IPP_CONFIG_TYPE, &config_type))
297 294 != 0) {
298 295 nvlist_free(nvlp);
299 296 flowacct0dbg(("flowacct_modify_action: invalid configuration "\
300 297 "type\n"));
301 298 return (rc);
302 299 }
303 300
304 301 if (config_type != IPP_SET) {
305 302 nvlist_free(nvlp);
306 303 flowacct0dbg(("flowacct_modify_action: invalid configuration "\
307 304 "type %d\n", config_type));
308 305 return (EINVAL);
309 306 }
310 307
311 308 flowacct_data = (flowacct_data_t *)ipp_action_get_ptr(aid);
312 309
313 310 /* parse next action name, if present */
314 311 if ((rc = nvlist_lookup_string(nvlp, FLOWACCT_NEXT_ACTION_NAME,
315 312 &next_action_name)) == 0) {
316 313 /* lookup action name to get action id */
317 314 if ((next_action = ipp_action_lookup(next_action_name))
318 315 == IPP_ACTION_INVAL) {
319 316 nvlist_free(nvlp);
320 317 flowacct0dbg(("flowacct_modify_action: next_action "\
321 318 "invalid\n"));
322 319 return (EINVAL);
323 320 }
324 321 /* reference new action */
325 322 if ((rc = ipp_action_ref(aid, next_action, flags)) != 0) {
326 323 nvlist_free(nvlp);
327 324 flowacct0dbg(("flowacct_modify_action: "\
328 325 "ipp_action_ref returned with error %d\n", rc));
329 326 return (rc);
330 327 }
331 328
332 329 if ((rc = ipp_action_name(aid, &act_name)) != 0) {
333 330 nvlist_free(nvlp);
334 331 flowacct0dbg(("flowacct_modify_action: invalid next "\
335 332 "aid\n"));
336 333 return (EINVAL);
337 334 }
338 335
339 336 /* unref old action */
340 337 rc = ipp_action_unref(aid, flowacct_data->next_action, flags);
341 338 ASSERT(rc == 0);
342 339 flowacct_data->next_action = next_action;
343 340 kmem_free(flowacct_data->act_name,
344 341 (strlen(flowacct_data->act_name) + 1));
345 342 flowacct_data->act_name = act_name;
346 343 }
347 344
348 345 /* parse timeout, if present */
349 346 if ((rc = nvlist_lookup_uint32(nvlp, FLOWACCT_TIMEOUT, &timeout))
350 347 == 0) {
351 348 flowacct_data->timeout = (uint64_t)timeout *
352 349 FLOWACCT_MSEC_TO_NSEC;
353 350 }
354 351
355 352 /* parse timer, if present */
356 353 if ((rc = nvlist_lookup_uint32(nvlp, FLOWACCT_TIMER, &timer)) == 0) {
357 354 flowacct_data->timer = (uint64_t)timer * FLOWACCT_MSEC_TO_USEC;
358 355 }
359 356
360 357 /* parse max_flow, if present */
361 358 if ((rc = nvlist_lookup_uint32(nvlp, FLOWACCT_MAX_LIMIT, &max_limit))
362 359 == 0) {
363 360 flowacct_data->max_limit = max_limit;
364 361 }
365 362
366 363 /* parse gather_stats boolean, if present */
367 364 if ((rc = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &bstats))
368 365 == 0) {
369 366 boolean_t new_val = (boolean_t)bstats;
370 367
371 368 /* Turning global stats on */
372 369 if (new_val && !flowacct_data->global_stats) {
373 370 rc = global_statinit(aid, flowacct_data);
374 371 if (rc == 0) {
375 372 flowacct_data->global_stats = new_val;
376 373 } else {
377 374 flowacct0dbg(("flowacct_modify_action: error "\
378 375 "enabling stats\n"));
379 376 }
380 377 } else if (!new_val && flowacct_data->global_stats) {
381 378 flowacct_data->global_stats = new_val;
382 379 ipp_stat_destroy(flowacct_data->stats);
383 380 }
384 381 }
385 382 return (0);
386 383 }
387 384
388 385 static int
389 386 flowacct_destroy_action(ipp_action_id_t aid, ipp_flags_t flags)
390 387 {
391 388 flowacct_data_t *flowacct_data;
392 389 int rc, flow_count;
393 390 list_head_t *head;
394 391
395 392 flowacct_data = (flowacct_data_t *)ipp_action_get_ptr(aid);
396 393 ASSERT(flowacct_data != NULL);
397 394
398 395 while (flowacct_data->flow_tid != 0) {
399 396 timeout_id_t tid = flowacct_data->flow_tid;
400 397 flowacct_data->flow_tid = 0;
401 398 (void) untimeout(tid);
402 399 }
403 400
404 401 if (flowacct_data->stats != NULL) {
405 402 ipp_stat_destroy(flowacct_data->stats);
406 403 }
407 404
408 405 /* Dump all the flows to the file */
409 406 flowacct_timer(FLOWACCT_PURGE_FLOW, flowacct_data);
410 407
411 408 kmem_free(flowacct_data->act_name, (strlen(flowacct_data->act_name)
412 409 + 1));
413 410
414 411 /* Destroy the locks */
415 412 for (flow_count = 0, head = flowacct_data->flows_tbl;
416 413 flow_count < FLOW_TBL_COUNT; flow_count++, head++) {
417 414 mutex_destroy(&head->lock);
418 415 }
419 416 /* unreference the action */
420 417 rc = ipp_action_unref(aid, flowacct_data->next_action, flags);
421 418 ASSERT(rc == 0);
422 419
423 420
424 421 kmem_free(flowacct_data, FLOWACCT_DATA_SZ);
425 422 return (0);
426 423 }
427 424
428 425 static int
429 426 flowacct_invoke_action(ipp_action_id_t aid, ipp_packet_t *packet)
430 427 {
431 428 flowacct_data_t *flowacct_data;
432 429 mblk_t *mp = NULL;
433 430 int rc;
434 431
435 432 /* get mblk from ipp_packet structure */
436 433 mp = ipp_packet_get_data(packet);
437 434 flowacct_data = (flowacct_data_t *)ipp_action_get_ptr(aid);
438 435 ASSERT(flowacct_data != NULL);
439 436
440 437 /* flowacct packet as configured */
441 438 if ((rc = flowacct_process(&mp, flowacct_data)) != 0) {
442 439 return (rc);
443 440 } else {
444 441 /* return packet with next action set */
445 442 return (ipp_packet_next(packet, flowacct_data->next_action));
446 443 }
447 444 }
448 445
449 446 /* ARGSUSED */
450 447 static int
451 448 flowacct_info(ipp_action_id_t aid, int (*fn)(nvlist_t *, void *), void *arg,
452 449 ipp_flags_t flags)
453 450 {
454 451 nvlist_t *nvlp;
455 452 flowacct_data_t *flowacct_data;
456 453 char *next_action;
457 454 uint32_t param;
458 455 int rc;
459 456
460 457 flowacct_data = (flowacct_data_t *)ipp_action_get_ptr(aid);
461 458 ASSERT(flowacct_data != NULL);
462 459 ASSERT(fn != NULL);
463 460
464 461 /* allocate nvlist to be passed back */
465 462 if ((rc = nvlist_alloc(&nvlp, NV_UNIQUE_NAME, KM_NOSLEEP)) != 0) {
466 463 flowacct0dbg(("flowacct_info: memory allocation failure\n"));
467 464 return (rc);
468 465 }
469 466
470 467 /* look up next action with the next action id */
471 468 if ((rc = ipp_action_name(flowacct_data->next_action,
472 469 &next_action)) != 0) {
473 470 flowacct0dbg(("flowacct_info: next action not available\n"));
474 471 nvlist_free(nvlp);
475 472 return (rc);
476 473 }
477 474
478 475 /* add next action name */
479 476 if ((rc = nvlist_add_string(nvlp, FLOWACCT_NEXT_ACTION_NAME,
480 477 next_action)) != 0) {
481 478 flowacct0dbg(("flowacct_info: error adding next action\n"));
482 479 nvlist_free(nvlp);
483 480 kmem_free(next_action, (strlen(next_action) + 1));
484 481 return (rc);
485 482 }
486 483
487 484 /* free action name */
488 485 kmem_free(next_action, (strlen(next_action) + 1));
489 486
490 487 /* add config type */
491 488 if ((rc = nvlist_add_byte(nvlp, IPP_CONFIG_TYPE, IPP_SET)) != 0) {
492 489 flowacct0dbg(("flowacct_info: error adding config type\n"));
493 490 nvlist_free(nvlp);
494 491 return (rc);
495 492 }
496 493
497 494 /* add timer */
498 495 param = flowacct_data->timer / FLOWACCT_MSEC_TO_USEC;
499 496 if ((rc = nvlist_add_uint32(nvlp, FLOWACCT_TIMER, param)) != 0) {
500 497 flowacct0dbg(("flowacct_info: error adding timer info.\n"));
501 498 nvlist_free(nvlp);
502 499 return (rc);
503 500 }
504 501
505 502 /* add max_limit */
506 503 if ((rc = nvlist_add_uint32(nvlp, FLOWACCT_MAX_LIMIT,
507 504 flowacct_data->max_limit)) != 0) {
508 505 flowacct0dbg(("flowacct_info: error adding max_flow info.\n"));
509 506 nvlist_free(nvlp);
510 507 return (rc);
511 508 }
512 509
513 510
514 511 param = flowacct_data->timeout / FLOWACCT_MSEC_TO_NSEC;
515 512 /* add timeout */
516 513 if ((rc = nvlist_add_uint32(nvlp, FLOWACCT_TIMEOUT, param)) != 0) {
517 514 flowacct0dbg(("flowacct_info: error adding timeout info.\n"));
518 515 nvlist_free(nvlp);
519 516 return (rc);
520 517 }
521 518
522 519 /* add global stats boolean */
523 520 if ((rc = nvlist_add_uint32(nvlp, IPP_ACTION_STATS_ENABLE,
524 521 (uint32_t)flowacct_data->global_stats)) != 0) {
525 522 flowacct0dbg(("flowacct_info: error adding global stats "\
526 523 "info.\n"));
527 524 nvlist_free(nvlp);
528 525 return (rc);
529 526 }
530 527
531 528 /* call back with nvlist */
532 529 rc = fn(nvlp, arg);
533 530
534 531 nvlist_free(nvlp);
535 532 return (rc);
536 533 }
↓ open down ↓ |
446 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX