History

[NetLabel]: rework the Netlink attribute handling (part 1)

At the suggestion of Thomas Graf, rewrite NetLabel's use of Netlink attributes to better follow the common Netlink attribute usage.

Paul Moore committed 20 years ago

Commit fcd48281 parent 4fe5d5c7 files · +76 −604Browse files

Unified · Split

7 files
  1. include/net/cipso_ipv4.h +7 −9
  2. include/net/netlabel.h +2 −47
  3. net/ipv4/cipso_ipv4.c +24 −179
  4. net/netlabel/netlabel_domainhash.c +37 −146
  5. net/netlabel/netlabel_domainhash.h +4 −2
  6. net/netlabel/netlabel_user.c +0 −82
  7. net/netlabel/netlabel_user.h +2 −139
include/net/cipso_ipv4.h+7−9
@@ -130,8 +130,9 @@ extern int cipso_v4_rbm_strictvalid; · 129 unmodified lines
130int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);130int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
131int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head));131int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head));
132struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);132struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
133struct sk_buff *cipso_v4_doi_dump_all(size_t headroom);133int cipso_v4_doi_walk(u32 *skip_cnt,
134struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom);134 int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
135 void *cb_arg);
135int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);136int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);
136int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,137int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
137 const char *domain);138 const char *domain);
@@ -152,14 +153,11 @@ static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) · 14 unmodified lines
152 return NULL;153 return NULL;
153}154}
154 155
155static inline struct sk_buff *cipso_v4_doi_dump_all(size_t headroom)156static inline int cipso_v4_doi_walk(u32 *skip_cnt,
157 int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
158 void *cb_arg)
156{159{
157 return NULL;160 return 0;
158}
159
160static inline struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom)
161{
162 return NULL;
163}161}
164 162
165static inline int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def,163static inline int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def,
include/net/netlabel.h+2−47
@@ -57,9 +57,8 @@ · 56 unmodified lines
57 * The payload is dependent on the subsystem specified in the57 * The payload is dependent on the subsystem specified in the
58 * 'nlmsghdr->nlmsg_type' and should be defined below, supporting functions58 * 'nlmsghdr->nlmsg_type' and should be defined below, supporting functions
59 * should be defined in the corresponding net/netlabel/netlabel_<subsys>.h|c59 * should be defined in the corresponding net/netlabel/netlabel_<subsys>.h|c
60 * file. All of the fields in the NetLabel payload are NETLINK attributes, the60 * file. All of the fields in the NetLabel payload are NETLINK attributes, see
61 * length of each field is the length of the NETLINK attribute payload, see61 * the include/net/netlink.h file for more information on NETLINK attributes.
62 * include/net/netlink.h for more information on NETLINK attributes.
63 *62 *
64 */63 */
65 64
@@ -82,50 +81,6 @@ · 16 unmodified lines
82#define NETLBL_NLTYPE_UNLABELED 581#define NETLBL_NLTYPE_UNLABELED 5
83#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL"82#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL"
84 83
85/* NetLabel return codes */
86#define NETLBL_E_OK 0
87
88/*
89 * Helper functions
90 */
91
92#define NETLBL_LEN_U8 nla_total_size(sizeof(u8))
93#define NETLBL_LEN_U16 nla_total_size(sizeof(u16))
94#define NETLBL_LEN_U32 nla_total_size(sizeof(u32))
95
96/**
97 * netlbl_netlink_alloc_skb - Allocate a NETLINK message buffer
98 * @head: the amount of headroom in bytes
99 * @body: the desired size (minus headroom) in bytes
100 * @gfp_flags: the alloc flags to pass to alloc_skb()
101 *
102 * Description:
103 * Allocate a NETLINK message buffer based on the sizes given in @head and
104 * @body. If @head is greater than zero skb_reserve() is called to reserve
105 * @head bytes at the start of the buffer. Returns a valid sk_buff pointer on
106 * success, NULL on failure.
107 *
108 */
109static inline struct sk_buff *netlbl_netlink_alloc_skb(size_t head,
110 size_t body,
111 gfp_t gfp_flags)
112{
113 struct sk_buff *skb;
114
115 skb = alloc_skb(NLMSG_ALIGN(head + body), gfp_flags);
116 if (skb == NULL)
117 return NULL;
118 if (head > 0) {
119 skb_reserve(skb, head);
120 if (skb_tailroom(skb) < body) {
121 kfree_skb(skb);
122 return NULL;
123 }
124 }
125
126 return skb;
127}
128
129/*84/*
130 * NetLabel - Kernel API for accessing the network packet label mappings.85 * NetLabel - Kernel API for accessing the network packet label mappings.
131 *86 *
net/ipv4/cipso_ipv4.c+24−179
@@ -530,197 +530,42 @@ struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) · 529 unmodified lines
530}530}
531 531
532/**532/**
533 * cipso_v4_doi_dump_all - Dump all the CIPSO DOI definitions into a sk_buff533 * cipso_v4_doi_walk - Iterate through the DOI definitions
534 * @headroom: the amount of headroom to allocate for the sk_buff534 * @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 returned539 * 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. See540 * For each entry call @callback, if @callback returns a negative value stop
539 * net/netlabel/netlabel_cipso_v4.h for the LISTALL message format. This541 * '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 same542 * 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 */
544struct sk_buff *cipso_v4_doi_dump_all(size_t headroom)545int 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
580doi_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 */
599struct 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
720doi_dump_failure:565doi_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/**
net/netlabel/netlabel_domainhash.c+37−146
@@ -354,160 +354,51 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain) · 353 unmodified lines
354}354}
355 355
356/**356/**
357 * netlbl_domhsh_dump - Dump the domain hash table into a sk_buff357 * 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 an364 * Interate over the domain mapping hash table, skipping the first @skip_bkt
361 * application in response to a NetLabel management DOMAIN message. This365 * 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 same366 * @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 for367 * 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 a368 * return. Returns zero on succcess, negative values on failure.
365 * pointer to a sk_buff on success, NULL on error.
366 *369 *
367 */370 */
368struct sk_buff *netlbl_domhsh_dump(size_t headroom)371int 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
440dump_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 */
458struct 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
509dump_default_failure:399walk_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}
net/netlabel/netlabel_domainhash.h+4−2
@@ -61,7 +61,9 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry); · 60 unmodified lines
61int netlbl_domhsh_add_default(struct netlbl_dom_map *entry);61int netlbl_domhsh_add_default(struct netlbl_dom_map *entry);
62int netlbl_domhsh_remove_default(void);62int netlbl_domhsh_remove_default(void);
63struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);63struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
64struct sk_buff *netlbl_domhsh_dump(size_t headroom);64int netlbl_domhsh_walk(u32 *skip_bkt,
65struct 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#endif69#endif
net/netlabel/netlabel_user.c+0−82
@@ -74,85 +74,3 @@ int netlbl_netlink_init(void) · 73 unmodified lines
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 */
94void 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
122send_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 */
139int 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 */
155int netlbl_netlink_snd_multicast(struct sk_buff *skb, u32 pid, u32 group)
156{
157 return genlmsg_multicast(skb, pid, group, GFP_KERNEL);
158}
net/netlabel/netlabel_user.h+2−139
@@ -40,72 +40,6 @@ · 39 unmodified lines
40 40
41/* NetLabel NETLINK helper functions */41/* NetLabel NETLINK helper functions */
42 42
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 */
53static 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 */
70static 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 */
86static 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 */
102static 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/**43/**
110 * netlbl_netlink_hdr_put - Write the NETLINK buffers into a sk_buff44 * netlbl_netlink_hdr_put - Write the NETLINK buffers into a sk_buff
111 * @skb: the packet45 * @skb: the packet
@@ -124,6 +58,7 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb, · 12 unmodified lines
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, · 1 unmodified line
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 */
152static 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 */
183static 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 */
196static 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
204void 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
211int netlbl_netlink_init(void);76int netlbl_netlink_init(void);
212int netlbl_netlink_snd(struct sk_buff *skb, u32 pid);
213int netlbl_netlink_snd_multicast(struct sk_buff *skb, u32 pid, u32 group);
214 77
215#endif78#endif