diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/cipso_ipv4.c | 203 | ||||
-rw-r--r-- | net/netlabel/netlabel_domainhash.c | 183 | ||||
-rw-r--r-- | net/netlabel/netlabel_domainhash.h | 6 | ||||
-rw-r--r-- | net/netlabel/netlabel_user.c | 82 | ||||
-rw-r--r-- | net/netlabel/netlabel_user.h | 141 |
5 files changed, 67 insertions, 548 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 87e71563335d..e6ce0b3ba62a 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -530,197 +530,42 @@ struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) | |||
530 | } | 530 | } |
531 | 531 | ||
532 | /** | 532 | /** |
533 | * cipso_v4_doi_dump_all - Dump all the CIPSO DOI definitions into a sk_buff | 533 | * cipso_v4_doi_walk - Iterate through the DOI definitions |
534 | * @headroom: the amount of headroom to allocate for the sk_buff | 534 | * @skip_cnt: skip past this number of DOI definitions, updated |
535 | * @callback: callback for each DOI definition | ||
536 | * @cb_arg: argument for the callback function | ||
535 | * | 537 | * |
536 | * Description: | 538 | * Description: |
537 | * Dump a list of all the configured DOI values into a sk_buff. The returned | 539 | * Iterate over the DOI definition list, skipping the first @skip_cnt entries. |
538 | * sk_buff has room at the front of the sk_buff for @headroom bytes. See | 540 | * For each entry call @callback, if @callback returns a negative value stop |
539 | * net/netlabel/netlabel_cipso_v4.h for the LISTALL message format. This | 541 | * 'walking' through the list and return. Updates the value in @skip_cnt upon |
540 | * function may fail if another process is changing the DOI list at the same | 542 | * return. Returns zero on success, negative values on failure. |
541 | * time. Returns a pointer to a sk_buff on success, NULL on error. | ||
542 | * | 543 | * |
543 | */ | 544 | */ |
544 | struct sk_buff *cipso_v4_doi_dump_all(size_t headroom) | 545 | int cipso_v4_doi_walk(u32 *skip_cnt, |
546 | int (*callback) (struct cipso_v4_doi *doi_def, void *arg), | ||
547 | void *cb_arg) | ||
545 | { | 548 | { |
546 | struct sk_buff *skb = NULL; | 549 | int ret_val = -ENOENT; |
547 | struct cipso_v4_doi *iter; | ||
548 | u32 doi_cnt = 0; | 550 | u32 doi_cnt = 0; |
549 | ssize_t buf_len; | 551 | struct cipso_v4_doi *iter_doi; |
550 | |||
551 | buf_len = NETLBL_LEN_U32; | ||
552 | rcu_read_lock(); | ||
553 | list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list) | ||
554 | if (iter->valid) { | ||
555 | doi_cnt += 1; | ||
556 | buf_len += 2 * NETLBL_LEN_U32; | ||
557 | } | ||
558 | |||
559 | skb = netlbl_netlink_alloc_skb(headroom, buf_len, GFP_ATOMIC); | ||
560 | if (skb == NULL) | ||
561 | goto doi_dump_all_failure; | ||
562 | |||
563 | if (nla_put_u32(skb, NLA_U32, doi_cnt) != 0) | ||
564 | goto doi_dump_all_failure; | ||
565 | buf_len -= NETLBL_LEN_U32; | ||
566 | list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list) | ||
567 | if (iter->valid) { | ||
568 | if (buf_len < 2 * NETLBL_LEN_U32) | ||
569 | goto doi_dump_all_failure; | ||
570 | if (nla_put_u32(skb, NLA_U32, iter->doi) != 0) | ||
571 | goto doi_dump_all_failure; | ||
572 | if (nla_put_u32(skb, NLA_U32, iter->type) != 0) | ||
573 | goto doi_dump_all_failure; | ||
574 | buf_len -= 2 * NETLBL_LEN_U32; | ||
575 | } | ||
576 | rcu_read_unlock(); | ||
577 | |||
578 | return skb; | ||
579 | |||
580 | doi_dump_all_failure: | ||
581 | rcu_read_unlock(); | ||
582 | kfree(skb); | ||
583 | return NULL; | ||
584 | } | ||
585 | |||
586 | /** | ||
587 | * cipso_v4_doi_dump - Dump a CIPSO DOI definition into a sk_buff | ||
588 | * @doi: the DOI value | ||
589 | * @headroom: the amount of headroom to allocate for the sk_buff | ||
590 | * | ||
591 | * Description: | ||
592 | * Lookup the DOI definition matching @doi and dump it's contents into a | ||
593 | * sk_buff. The returned sk_buff has room at the front of the sk_buff for | ||
594 | * @headroom bytes. See net/netlabel/netlabel_cipso_v4.h for the LIST message | ||
595 | * format. This function may fail if another process is changing the DOI list | ||
596 | * at the same time. Returns a pointer to a sk_buff on success, NULL on error. | ||
597 | * | ||
598 | */ | ||
599 | struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom) | ||
600 | { | ||
601 | struct sk_buff *skb = NULL; | ||
602 | struct cipso_v4_doi *iter; | ||
603 | u32 tag_cnt = 0; | ||
604 | u32 lvl_cnt = 0; | ||
605 | u32 cat_cnt = 0; | ||
606 | ssize_t buf_len; | ||
607 | ssize_t tmp; | ||
608 | 552 | ||
609 | rcu_read_lock(); | 553 | rcu_read_lock(); |
610 | iter = cipso_v4_doi_getdef(doi); | 554 | list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list) |
611 | if (iter == NULL) | 555 | if (iter_doi->valid) { |
612 | goto doi_dump_failure; | 556 | if (doi_cnt++ < *skip_cnt) |
613 | buf_len = NETLBL_LEN_U32; | 557 | continue; |
614 | switch (iter->type) { | 558 | ret_val = callback(iter_doi, cb_arg); |
615 | case CIPSO_V4_MAP_PASS: | 559 | if (ret_val < 0) { |
616 | buf_len += NETLBL_LEN_U32; | 560 | doi_cnt--; |
617 | while(tag_cnt < CIPSO_V4_TAG_MAXCNT && | 561 | goto doi_walk_return; |
618 | iter->tags[tag_cnt] != CIPSO_V4_TAG_INVALID) { | ||
619 | tag_cnt += 1; | ||
620 | buf_len += NETLBL_LEN_U8; | ||
621 | } | ||
622 | break; | ||
623 | case CIPSO_V4_MAP_STD: | ||
624 | buf_len += 3 * NETLBL_LEN_U32; | ||
625 | while (tag_cnt < CIPSO_V4_TAG_MAXCNT && | ||
626 | iter->tags[tag_cnt] != CIPSO_V4_TAG_INVALID) { | ||
627 | tag_cnt += 1; | ||
628 | buf_len += NETLBL_LEN_U8; | ||
629 | } | ||
630 | for (tmp = 0; tmp < iter->map.std->lvl.local_size; tmp++) | ||
631 | if (iter->map.std->lvl.local[tmp] != | ||
632 | CIPSO_V4_INV_LVL) { | ||
633 | lvl_cnt += 1; | ||
634 | buf_len += NETLBL_LEN_U32 + NETLBL_LEN_U8; | ||
635 | } | 562 | } |
636 | for (tmp = 0; tmp < iter->map.std->cat.local_size; tmp++) | ||
637 | if (iter->map.std->cat.local[tmp] != | ||
638 | CIPSO_V4_INV_CAT) { | ||
639 | cat_cnt += 1; | ||
640 | buf_len += NETLBL_LEN_U32 + NETLBL_LEN_U16; | ||
641 | } | ||
642 | break; | ||
643 | } | ||
644 | |||
645 | skb = netlbl_netlink_alloc_skb(headroom, buf_len, GFP_ATOMIC); | ||
646 | if (skb == NULL) | ||
647 | goto doi_dump_failure; | ||
648 | |||
649 | if (nla_put_u32(skb, NLA_U32, iter->type) != 0) | ||
650 | goto doi_dump_failure; | ||
651 | buf_len -= NETLBL_LEN_U32; | ||
652 | if (iter != cipso_v4_doi_getdef(doi)) | ||
653 | goto doi_dump_failure; | ||
654 | switch (iter->type) { | ||
655 | case CIPSO_V4_MAP_PASS: | ||
656 | if (nla_put_u32(skb, NLA_U32, tag_cnt) != 0) | ||
657 | goto doi_dump_failure; | ||
658 | buf_len -= NETLBL_LEN_U32; | ||
659 | for (tmp = 0; | ||
660 | tmp < CIPSO_V4_TAG_MAXCNT && | ||
661 | iter->tags[tmp] != CIPSO_V4_TAG_INVALID; | ||
662 | tmp++) { | ||
663 | if (buf_len < NETLBL_LEN_U8) | ||
664 | goto doi_dump_failure; | ||
665 | if (nla_put_u8(skb, NLA_U8, iter->tags[tmp]) != 0) | ||
666 | goto doi_dump_failure; | ||
667 | buf_len -= NETLBL_LEN_U8; | ||
668 | } | 563 | } |
669 | break; | ||
670 | case CIPSO_V4_MAP_STD: | ||
671 | if (nla_put_u32(skb, NLA_U32, tag_cnt) != 0) | ||
672 | goto doi_dump_failure; | ||
673 | if (nla_put_u32(skb, NLA_U32, lvl_cnt) != 0) | ||
674 | goto doi_dump_failure; | ||
675 | if (nla_put_u32(skb, NLA_U32, cat_cnt) != 0) | ||
676 | goto doi_dump_failure; | ||
677 | buf_len -= 3 * NETLBL_LEN_U32; | ||
678 | for (tmp = 0; | ||
679 | tmp < CIPSO_V4_TAG_MAXCNT && | ||
680 | iter->tags[tmp] != CIPSO_V4_TAG_INVALID; | ||
681 | tmp++) { | ||
682 | if (buf_len < NETLBL_LEN_U8) | ||
683 | goto doi_dump_failure; | ||
684 | if (nla_put_u8(skb, NLA_U8, iter->tags[tmp]) != 0) | ||
685 | goto doi_dump_failure; | ||
686 | buf_len -= NETLBL_LEN_U8; | ||
687 | } | ||
688 | for (tmp = 0; tmp < iter->map.std->lvl.local_size; tmp++) | ||
689 | if (iter->map.std->lvl.local[tmp] != | ||
690 | CIPSO_V4_INV_LVL) { | ||
691 | if (buf_len < NETLBL_LEN_U32 + NETLBL_LEN_U8) | ||
692 | goto doi_dump_failure; | ||
693 | if (nla_put_u32(skb, NLA_U32, tmp) != 0) | ||
694 | goto doi_dump_failure; | ||
695 | if (nla_put_u8(skb, | ||
696 | NLA_U8, | ||
697 | iter->map.std->lvl.local[tmp]) != 0) | ||
698 | goto doi_dump_failure; | ||
699 | buf_len -= NETLBL_LEN_U32 + NETLBL_LEN_U8; | ||
700 | } | ||
701 | for (tmp = 0; tmp < iter->map.std->cat.local_size; tmp++) | ||
702 | if (iter->map.std->cat.local[tmp] != | ||
703 | CIPSO_V4_INV_CAT) { | ||
704 | if (buf_len < NETLBL_LEN_U32 + NETLBL_LEN_U16) | ||
705 | goto doi_dump_failure; | ||
706 | if (nla_put_u32(skb, NLA_U32, tmp) != 0) | ||
707 | goto doi_dump_failure; | ||
708 | if (nla_put_u16(skb, | ||
709 | NLA_U16, | ||
710 | iter->map.std->cat.local[tmp]) != 0) | ||
711 | goto doi_dump_failure; | ||
712 | buf_len -= NETLBL_LEN_U32 + NETLBL_LEN_U16; | ||
713 | } | ||
714 | break; | ||
715 | } | ||
716 | rcu_read_unlock(); | ||
717 | |||
718 | return skb; | ||
719 | 564 | ||
720 | doi_dump_failure: | 565 | doi_walk_return: |
721 | rcu_read_unlock(); | 566 | rcu_read_unlock(); |
722 | kfree(skb); | 567 | *skip_cnt = doi_cnt; |
723 | return NULL; | 568 | return ret_val; |
724 | } | 569 | } |
725 | 570 | ||
726 | /** | 571 | /** |
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 0489a1378101..f56d7a8ac7b7 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -354,160 +354,51 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain) | |||
354 | } | 354 | } |
355 | 355 | ||
356 | /** | 356 | /** |
357 | * netlbl_domhsh_dump - Dump the domain hash table into a sk_buff | 357 | * netlbl_domhsh_walk - Iterate through the domain mapping hash table |
358 | * @skip_bkt: the number of buckets to skip at the start | ||
359 | * @skip_chain: the number of entries to skip in the first iterated bucket | ||
360 | * @callback: callback for each entry | ||
361 | * @cb_arg: argument for the callback function | ||
358 | * | 362 | * |
359 | * Description: | 363 | * Description: |
360 | * Dump the domain hash table into a buffer suitable for returning to an | 364 | * Interate over the domain mapping hash table, skipping the first @skip_bkt |
361 | * application in response to a NetLabel management DOMAIN message. This | 365 | * buckets and @skip_chain entries. For each entry in the table call |
362 | * function may fail if another process is growing the hash table at the same | 366 | * @callback, if @callback returns a negative value stop 'walking' through the |
363 | * time. The returned sk_buff has room at the front of the sk_buff for | 367 | * table and return. Updates the values in @skip_bkt and @skip_chain on |
364 | * @headroom bytes. See netlabel.h for the DOMAIN message format. Returns a | 368 | * return. Returns zero on succcess, negative values on failure. |
365 | * pointer to a sk_buff on success, NULL on error. | ||
366 | * | 369 | * |
367 | */ | 370 | */ |
368 | struct sk_buff *netlbl_domhsh_dump(size_t headroom) | 371 | int netlbl_domhsh_walk(u32 *skip_bkt, |
372 | u32 *skip_chain, | ||
373 | int (*callback) (struct netlbl_dom_map *entry, void *arg), | ||
374 | void *cb_arg) | ||
369 | { | 375 | { |
370 | struct sk_buff *skb = NULL; | 376 | int ret_val = -ENOENT; |
371 | ssize_t buf_len; | 377 | u32 iter_bkt; |
372 | u32 bkt_iter; | 378 | struct netlbl_dom_map *iter_entry; |
373 | u32 dom_cnt = 0; | 379 | u32 chain_cnt = 0; |
374 | struct netlbl_domhsh_tbl *hsh_tbl; | ||
375 | struct netlbl_dom_map *list_iter; | ||
376 | ssize_t tmp_len; | ||
377 | 380 | ||
378 | buf_len = NETLBL_LEN_U32; | ||
379 | rcu_read_lock(); | 381 | rcu_read_lock(); |
380 | hsh_tbl = rcu_dereference(netlbl_domhsh); | 382 | for (iter_bkt = *skip_bkt; |
381 | for (bkt_iter = 0; bkt_iter < hsh_tbl->size; bkt_iter++) | 383 | iter_bkt < rcu_dereference(netlbl_domhsh)->size; |
382 | list_for_each_entry_rcu(list_iter, | 384 | iter_bkt++, chain_cnt = 0) { |
383 | &hsh_tbl->tbl[bkt_iter], list) { | 385 | list_for_each_entry_rcu(iter_entry, |
384 | buf_len += NETLBL_LEN_U32 + | 386 | &netlbl_domhsh->tbl[iter_bkt], |
385 | nla_total_size(strlen(list_iter->domain) + 1); | 387 | list) |
386 | switch (list_iter->type) { | 388 | if (iter_entry->valid) { |
387 | case NETLBL_NLTYPE_UNLABELED: | 389 | if (chain_cnt++ < *skip_chain) |
388 | break; | 390 | continue; |
389 | case NETLBL_NLTYPE_CIPSOV4: | 391 | ret_val = callback(iter_entry, cb_arg); |
390 | buf_len += 2 * NETLBL_LEN_U32; | 392 | if (ret_val < 0) { |
391 | break; | 393 | chain_cnt--; |
392 | } | 394 | goto walk_return; |
393 | dom_cnt++; | 395 | } |
394 | } | ||
395 | |||
396 | skb = netlbl_netlink_alloc_skb(headroom, buf_len, GFP_ATOMIC); | ||
397 | if (skb == NULL) | ||
398 | goto dump_failure; | ||
399 | |||
400 | if (nla_put_u32(skb, NLA_U32, dom_cnt) != 0) | ||
401 | goto dump_failure; | ||
402 | buf_len -= NETLBL_LEN_U32; | ||
403 | hsh_tbl = rcu_dereference(netlbl_domhsh); | ||
404 | for (bkt_iter = 0; bkt_iter < hsh_tbl->size; bkt_iter++) | ||
405 | list_for_each_entry_rcu(list_iter, | ||
406 | &hsh_tbl->tbl[bkt_iter], list) { | ||
407 | tmp_len = nla_total_size(strlen(list_iter->domain) + | ||
408 | 1); | ||
409 | if (buf_len < NETLBL_LEN_U32 + tmp_len) | ||
410 | goto dump_failure; | ||
411 | if (nla_put_string(skb, | ||
412 | NLA_STRING, | ||
413 | list_iter->domain) != 0) | ||
414 | goto dump_failure; | ||
415 | if (nla_put_u32(skb, NLA_U32, list_iter->type) != 0) | ||
416 | goto dump_failure; | ||
417 | buf_len -= NETLBL_LEN_U32 + tmp_len; | ||
418 | switch (list_iter->type) { | ||
419 | case NETLBL_NLTYPE_UNLABELED: | ||
420 | break; | ||
421 | case NETLBL_NLTYPE_CIPSOV4: | ||
422 | if (buf_len < 2 * NETLBL_LEN_U32) | ||
423 | goto dump_failure; | ||
424 | if (nla_put_u32(skb, | ||
425 | NLA_U32, | ||
426 | list_iter->type_def.cipsov4->type) != 0) | ||
427 | goto dump_failure; | ||
428 | if (nla_put_u32(skb, | ||
429 | NLA_U32, | ||
430 | list_iter->type_def.cipsov4->doi) != 0) | ||
431 | goto dump_failure; | ||
432 | buf_len -= 2 * NETLBL_LEN_U32; | ||
433 | break; | ||
434 | } | 396 | } |
435 | } | 397 | } |
436 | rcu_read_unlock(); | ||
437 | |||
438 | return skb; | ||
439 | |||
440 | dump_failure: | ||
441 | rcu_read_unlock(); | ||
442 | kfree_skb(skb); | ||
443 | return NULL; | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * netlbl_domhsh_dump_default - Dump the default domain mapping into a sk_buff | ||
448 | * | ||
449 | * Description: | ||
450 | * Dump the default domain mapping into a buffer suitable for returning to an | ||
451 | * application in response to a NetLabel management DEFDOMAIN message. This | ||
452 | * function may fail if another process is changing the default domain mapping | ||
453 | * at the same time. The returned sk_buff has room at the front of the | ||
454 | * skb_buff for @headroom bytes. See netlabel.h for the DEFDOMAIN message | ||
455 | * format. Returns a pointer to a sk_buff on success, NULL on error. | ||
456 | * | ||
457 | */ | ||
458 | struct sk_buff *netlbl_domhsh_dump_default(size_t headroom) | ||
459 | { | ||
460 | struct sk_buff *skb; | ||
461 | ssize_t buf_len; | ||
462 | struct netlbl_dom_map *entry; | ||
463 | |||
464 | buf_len = NETLBL_LEN_U32; | ||
465 | rcu_read_lock(); | ||
466 | entry = rcu_dereference(netlbl_domhsh_def); | ||
467 | if (entry != NULL) | ||
468 | switch (entry->type) { | ||
469 | case NETLBL_NLTYPE_UNLABELED: | ||
470 | break; | ||
471 | case NETLBL_NLTYPE_CIPSOV4: | ||
472 | buf_len += 2 * NETLBL_LEN_U32; | ||
473 | break; | ||
474 | } | ||
475 | |||
476 | skb = netlbl_netlink_alloc_skb(headroom, buf_len, GFP_ATOMIC); | ||
477 | if (skb == NULL) | ||
478 | goto dump_default_failure; | ||
479 | |||
480 | if (entry != rcu_dereference(netlbl_domhsh_def)) | ||
481 | goto dump_default_failure; | ||
482 | if (entry != NULL) { | ||
483 | if (nla_put_u32(skb, NLA_U32, entry->type) != 0) | ||
484 | goto dump_default_failure; | ||
485 | buf_len -= NETLBL_LEN_U32; | ||
486 | switch (entry->type) { | ||
487 | case NETLBL_NLTYPE_UNLABELED: | ||
488 | break; | ||
489 | case NETLBL_NLTYPE_CIPSOV4: | ||
490 | if (buf_len < 2 * NETLBL_LEN_U32) | ||
491 | goto dump_default_failure; | ||
492 | if (nla_put_u32(skb, | ||
493 | NLA_U32, | ||
494 | entry->type_def.cipsov4->type) != 0) | ||
495 | goto dump_default_failure; | ||
496 | if (nla_put_u32(skb, | ||
497 | NLA_U32, | ||
498 | entry->type_def.cipsov4->doi) != 0) | ||
499 | goto dump_default_failure; | ||
500 | buf_len -= 2 * NETLBL_LEN_U32; | ||
501 | break; | ||
502 | } | ||
503 | } else | ||
504 | nla_put_u32(skb, NLA_U32, NETLBL_NLTYPE_NONE); | ||
505 | rcu_read_unlock(); | ||
506 | |||
507 | return skb; | ||
508 | 398 | ||
509 | dump_default_failure: | 399 | walk_return: |
510 | rcu_read_unlock(); | 400 | rcu_read_unlock(); |
511 | kfree_skb(skb); | 401 | *skip_bkt = iter_bkt; |
512 | return NULL; | 402 | *skip_chain = chain_cnt; |
403 | return ret_val; | ||
513 | } | 404 | } |
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h index 99a2287de246..02af72a7877c 100644 --- a/net/netlabel/netlabel_domainhash.h +++ b/net/netlabel/netlabel_domainhash.h | |||
@@ -61,7 +61,9 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry); | |||
61 | int netlbl_domhsh_add_default(struct netlbl_dom_map *entry); | 61 | int netlbl_domhsh_add_default(struct netlbl_dom_map *entry); |
62 | int netlbl_domhsh_remove_default(void); | 62 | int netlbl_domhsh_remove_default(void); |
63 | struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); | 63 | struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); |
64 | struct sk_buff *netlbl_domhsh_dump(size_t headroom); | 64 | int netlbl_domhsh_walk(u32 *skip_bkt, |
65 | struct sk_buff *netlbl_domhsh_dump_default(size_t headroom); | 65 | u32 *skip_chain, |
66 | int (*callback) (struct netlbl_dom_map *entry, void *arg), | ||
67 | void *cb_arg); | ||
66 | 68 | ||
67 | #endif | 69 | #endif |
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 73cbe66e42ff..eeb7d768d2bb 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -74,85 +74,3 @@ int netlbl_netlink_init(void) | |||
74 | 74 | ||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | |||
78 | /* | ||
79 | * NetLabel Common Protocol Functions | ||
80 | */ | ||
81 | |||
82 | /** | ||
83 | * netlbl_netlink_send_ack - Send an ACK message | ||
84 | * @info: the generic NETLINK information | ||
85 | * @genl_family: the generic NETLINK family ID value | ||
86 | * @ack_cmd: the generic NETLINK family ACK command value | ||
87 | * @ret_code: return code to use | ||
88 | * | ||
89 | * Description: | ||
90 | * This function sends an ACK message to the sender of the NETLINK message | ||
91 | * specified by @info. | ||
92 | * | ||
93 | */ | ||
94 | void netlbl_netlink_send_ack(const struct genl_info *info, | ||
95 | u32 genl_family, | ||
96 | u8 ack_cmd, | ||
97 | u32 ret_code) | ||
98 | { | ||
99 | size_t data_size; | ||
100 | struct sk_buff *skb; | ||
101 | |||
102 | data_size = GENL_HDRLEN + 2 * NETLBL_LEN_U32; | ||
103 | skb = netlbl_netlink_alloc_skb(0, data_size, GFP_KERNEL); | ||
104 | if (skb == NULL) | ||
105 | return; | ||
106 | |||
107 | if (netlbl_netlink_hdr_put(skb, | ||
108 | info->snd_pid, | ||
109 | 0, | ||
110 | genl_family, | ||
111 | ack_cmd) == NULL) | ||
112 | goto send_ack_failure; | ||
113 | |||
114 | if (nla_put_u32(skb, NLA_U32, info->snd_seq) != 0) | ||
115 | goto send_ack_failure; | ||
116 | if (nla_put_u32(skb, NLA_U32, ret_code) != 0) | ||
117 | goto send_ack_failure; | ||
118 | |||
119 | netlbl_netlink_snd(skb, info->snd_pid); | ||
120 | return; | ||
121 | |||
122 | send_ack_failure: | ||
123 | kfree_skb(skb); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * NETLINK I/O Functions | ||
128 | */ | ||
129 | |||
130 | /** | ||
131 | * netlbl_netlink_snd - Send a NetLabel message | ||
132 | * @skb: NetLabel message | ||
133 | * @pid: destination PID | ||
134 | * | ||
135 | * Description: | ||
136 | * Sends a unicast NetLabel message over the NETLINK socket. | ||
137 | * | ||
138 | */ | ||
139 | int netlbl_netlink_snd(struct sk_buff *skb, u32 pid) | ||
140 | { | ||
141 | return genlmsg_unicast(skb, pid); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * netlbl_netlink_snd - Send a NetLabel message | ||
146 | * @skb: NetLabel message | ||
147 | * @pid: sending PID | ||
148 | * @group: multicast group id | ||
149 | * | ||
150 | * Description: | ||
151 | * Sends a multicast NetLabel message over the NETLINK socket to all members | ||
152 | * of @group except @pid. | ||
153 | * | ||
154 | */ | ||
155 | int netlbl_netlink_snd_multicast(struct sk_buff *skb, u32 pid, u32 group) | ||
156 | { | ||
157 | return genlmsg_multicast(skb, pid, group, GFP_KERNEL); | ||
158 | } | ||
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 385a6c7488c6..3f9386b917df 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h | |||
@@ -41,72 +41,6 @@ | |||
41 | /* NetLabel NETLINK helper functions */ | 41 | /* NetLabel NETLINK helper functions */ |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * netlbl_netlink_cap_check - Check the NETLINK msg capabilities | ||
45 | * @skb: the NETLINK buffer | ||
46 | * @req_cap: the required capability | ||
47 | * | ||
48 | * Description: | ||
49 | * Check the NETLINK buffer's capabilities against the required capabilities. | ||
50 | * Returns zero on success, negative values on failure. | ||
51 | * | ||
52 | */ | ||
53 | static inline int netlbl_netlink_cap_check(const struct sk_buff *skb, | ||
54 | kernel_cap_t req_cap) | ||
55 | { | ||
56 | if (cap_raised(NETLINK_CB(skb).eff_cap, req_cap)) | ||
57 | return 0; | ||
58 | return -EPERM; | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * netlbl_getinc_u8 - Read a u8 value from a nlattr stream and move on | ||
63 | * @nla: the attribute | ||
64 | * @rem_len: remaining length | ||
65 | * | ||
66 | * Description: | ||
67 | * Return a u8 value pointed to by @nla and advance it to the next attribute. | ||
68 | * | ||
69 | */ | ||
70 | static inline u8 netlbl_getinc_u8(struct nlattr **nla, int *rem_len) | ||
71 | { | ||
72 | u8 val = nla_get_u8(*nla); | ||
73 | *nla = nla_next(*nla, rem_len); | ||
74 | return val; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * netlbl_getinc_u16 - Read a u16 value from a nlattr stream and move on | ||
79 | * @nla: the attribute | ||
80 | * @rem_len: remaining length | ||
81 | * | ||
82 | * Description: | ||
83 | * Return a u16 value pointed to by @nla and advance it to the next attribute. | ||
84 | * | ||
85 | */ | ||
86 | static inline u16 netlbl_getinc_u16(struct nlattr **nla, int *rem_len) | ||
87 | { | ||
88 | u16 val = nla_get_u16(*nla); | ||
89 | *nla = nla_next(*nla, rem_len); | ||
90 | return val; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * netlbl_getinc_u32 - Read a u32 value from a nlattr stream and move on | ||
95 | * @nla: the attribute | ||
96 | * @rem_len: remaining length | ||
97 | * | ||
98 | * Description: | ||
99 | * Return a u32 value pointed to by @nla and advance it to the next attribute. | ||
100 | * | ||
101 | */ | ||
102 | static inline u32 netlbl_getinc_u32(struct nlattr **nla, int *rem_len) | ||
103 | { | ||
104 | u32 val = nla_get_u32(*nla); | ||
105 | *nla = nla_next(*nla, rem_len); | ||
106 | return val; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * netlbl_netlink_hdr_put - Write the NETLINK buffers into a sk_buff | 44 | * netlbl_netlink_hdr_put - Write the NETLINK buffers into a sk_buff |
111 | * @skb: the packet | 45 | * @skb: the packet |
112 | * @pid: the PID of the receipient | 46 | * @pid: the PID of the receipient |
@@ -124,6 +58,7 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb, | |||
124 | u32 pid, | 58 | u32 pid, |
125 | u32 seq, | 59 | u32 seq, |
126 | int type, | 60 | int type, |
61 | int flags, | ||
127 | u8 cmd) | 62 | u8 cmd) |
128 | { | 63 | { |
129 | return genlmsg_put(skb, | 64 | return genlmsg_put(skb, |
@@ -131,85 +66,13 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb, | |||
131 | seq, | 66 | seq, |
132 | type, | 67 | type, |
133 | 0, | 68 | 0, |
134 | 0, | 69 | flags, |
135 | cmd, | 70 | cmd, |
136 | NETLBL_PROTO_VERSION); | 71 | NETLBL_PROTO_VERSION); |
137 | } | 72 | } |
138 | 73 | ||
139 | /** | ||
140 | * netlbl_netlink_hdr_push - Write the NETLINK buffers into a sk_buff | ||
141 | * @skb: the packet | ||
142 | * @pid: the PID of the receipient | ||
143 | * @seq: the sequence number | ||
144 | * @type: the generic NETLINK message family type | ||
145 | * @cmd: command | ||
146 | * | ||
147 | * Description: | ||
148 | * Write both a NETLINK nlmsghdr structure and a Generic NETLINK genlmsghdr | ||
149 | * struct to the packet. | ||
150 | * | ||
151 | */ | ||
152 | static inline void netlbl_netlink_hdr_push(struct sk_buff *skb, | ||
153 | u32 pid, | ||
154 | u32 seq, | ||
155 | int type, | ||
156 | u8 cmd) | ||
157 | |||
158 | { | ||
159 | struct nlmsghdr *nlh; | ||
160 | struct genlmsghdr *hdr; | ||
161 | |||
162 | nlh = (struct nlmsghdr *)skb_push(skb, NLMSG_SPACE(GENL_HDRLEN)); | ||
163 | nlh->nlmsg_type = type; | ||
164 | nlh->nlmsg_len = skb->len; | ||
165 | nlh->nlmsg_flags = 0; | ||
166 | nlh->nlmsg_pid = pid; | ||
167 | nlh->nlmsg_seq = seq; | ||
168 | |||
169 | hdr = nlmsg_data(nlh); | ||
170 | hdr->cmd = cmd; | ||
171 | hdr->version = NETLBL_PROTO_VERSION; | ||
172 | hdr->reserved = 0; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * netlbl_netlink_payload_len - Return the length of the payload | ||
177 | * @skb: the NETLINK buffer | ||
178 | * | ||
179 | * Description: | ||
180 | * This function returns the length of the NetLabel payload. | ||
181 | * | ||
182 | */ | ||
183 | static inline u32 netlbl_netlink_payload_len(const struct sk_buff *skb) | ||
184 | { | ||
185 | return nlmsg_len((struct nlmsghdr *)skb->data) - GENL_HDRLEN; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * netlbl_netlink_payload_data - Returns a pointer to the start of the payload | ||
190 | * @skb: the NETLINK buffer | ||
191 | * | ||
192 | * Description: | ||
193 | * This function returns a pointer to the start of the NetLabel payload. | ||
194 | * | ||
195 | */ | ||
196 | static inline void *netlbl_netlink_payload_data(const struct sk_buff *skb) | ||
197 | { | ||
198 | return (unsigned char *)nlmsg_data((struct nlmsghdr *)skb->data) + | ||
199 | GENL_HDRLEN; | ||
200 | } | ||
201 | |||
202 | /* NetLabel common protocol functions */ | ||
203 | |||
204 | void netlbl_netlink_send_ack(const struct genl_info *info, | ||
205 | u32 genl_family, | ||
206 | u8 ack_cmd, | ||
207 | u32 ret_code); | ||
208 | |||
209 | /* NetLabel NETLINK I/O functions */ | 74 | /* NetLabel NETLINK I/O functions */ |
210 | 75 | ||
211 | int netlbl_netlink_init(void); | 76 | int netlbl_netlink_init(void); |
212 | int netlbl_netlink_snd(struct sk_buff *skb, u32 pid); | ||
213 | int netlbl_netlink_snd_multicast(struct sk_buff *skb, u32 pid, u32 group); | ||
214 | 77 | ||
215 | #endif | 78 | #endif |