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
130130 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
131131 int cipso_v4_doi_remove(u32 doi, void (*callback) (struct rcu_head * head));
132132 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
133−struct sk_buff *cipso_v4_doi_dump_all(size_t headroom);
134−struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom);
133+int cipso_v4_doi_walk(u32 *skip_cnt,
134+ int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
135+ void *cb_arg);
135136 int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);
136137 int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
137138 const char *domain);
@@ -152,14 +153,11 @@ static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) · 14 unmodified lines
152153 return NULL;
153154 }
154155
155−static inline struct sk_buff *cipso_v4_doi_dump_all(size_t headroom)
156+static inline int cipso_v4_doi_walk(u32 *skip_cnt,
157+ int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
158+ void *cb_arg)
156159 {
157− return NULL;
158−}
159−
160−static inline struct sk_buff *cipso_v4_doi_dump(u32 doi, size_t headroom)
161−{
162− return NULL;
160+ return 0;
163161 }
164162
165163 static 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
5757 * The payload is dependent on the subsystem specified in the
5858 * 'nlmsghdr->nlmsg_type' and should be defined below, supporting functions
5959 * 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, the
61− * length of each field is the length of the NETLINK attribute payload, see
62− * include/net/netlink.h for more information on NETLINK attributes.
60+ * file. All of the fields in the NetLabel payload are NETLINK attributes, see
61+ * the include/net/netlink.h file for more information on NETLINK attributes.
6362 *
6463 */
6564
@@ -82,50 +81,6 @@ · 16 unmodified lines
8281 #define NETLBL_NLTYPE_UNLABELED 5
8382 #define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL"
8483
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− */
109−static 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−
12984 /*
13085 * NetLabel - Kernel API for accessing the network packet label mappings.
13186 *
net/ipv4/cipso_ipv4.c+24−179
@@ -530,197 +530,42 @@ struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) · 529 unmodified lines
530530 }
531531
532532 /**
533− * cipso_v4_doi_dump_all - Dump all the CIPSO DOI definitions into a sk_buff
534− * @headroom: the amount of headroom to allocate for the sk_buff
533+ * cipso_v4_doi_walk - Iterate through the DOI definitions
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
535537 *
536538 * Description:
537− * Dump a list of all the configured DOI values into a sk_buff. The returned
538− * sk_buff has room at the front of the sk_buff for @headroom bytes. See
539− * net/netlabel/netlabel_cipso_v4.h for the LISTALL message format. This
540− * function may fail if another process is changing the DOI list at the same
541− * time. Returns a pointer to a sk_buff on success, NULL on error.
539+ * Iterate over the DOI definition list, skipping the first @skip_cnt entries.
540+ * For each entry call @callback, if @callback returns a negative value stop
541+ * 'walking' through the list and return. Updates the value in @skip_cnt upon
542+ * return. Returns zero on success, negative values on failure.
542543 *
543544 */
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)
545548 {
546− struct sk_buff *skb = NULL;
547− struct cipso_v4_doi *iter;
549+ int ret_val = -ENOENT;
548550 u32 doi_cnt = 0;
549− ssize_t buf_len;
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;
551+ struct cipso_v4_doi *iter_doi;
608552
609553 rcu_read_lock();
610− iter = cipso_v4_doi_getdef(doi);
611− if (iter == NULL)
612− goto doi_dump_failure;
613− buf_len = NETLBL_LEN_U32;
614− switch (iter->type) {
615− case CIPSO_V4_MAP_PASS:
616− buf_len += NETLBL_LEN_U32;
617− while(tag_cnt < CIPSO_V4_TAG_MAXCNT &&
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;
554+ list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)
555+ if (iter_doi->valid) {
556+ if (doi_cnt++ < *skip_cnt)
557+ continue;
558+ ret_val = callback(iter_doi, cb_arg);
559+ if (ret_val < 0) {
560+ doi_cnt--;
561+ goto doi_walk_return;
635562 }
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;
668563 }
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;
719564
720−doi_dump_failure:
565+doi_walk_return:
721566 rcu_read_unlock();
722− kfree(skb);
723− return NULL;
567+ *skip_cnt = doi_cnt;
568+ return ret_val;
724569 }
725570
726571 /**
net/netlabel/netlabel_domainhash.c+37−146
@@ -354,160 +354,51 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain) · 353 unmodified lines
354354 }
355355
356356 /**
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
358362 *
359363 * Description:
360− * Dump the domain hash table into a buffer suitable for returning to an
361− * application in response to a NetLabel management DOMAIN message. This
362− * function may fail if another process is growing the hash table at the same
363− * time. The returned sk_buff has room at the front of the sk_buff for
364− * @headroom bytes. See netlabel.h for the DOMAIN message format. Returns a
365− * pointer to a sk_buff on success, NULL on error.
364+ * Interate over the domain mapping hash table, skipping the first @skip_bkt
365+ * buckets and @skip_chain entries. For each entry in the table call
366+ * @callback, if @callback returns a negative value stop 'walking' through the
367+ * table and return. Updates the values in @skip_bkt and @skip_chain on
368+ * return. Returns zero on succcess, negative values on failure.
366369 *
367370 */
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)
369375 {
370− struct sk_buff *skb = NULL;
371− ssize_t buf_len;
372− u32 bkt_iter;
373− u32 dom_cnt = 0;
374− struct netlbl_domhsh_tbl *hsh_tbl;
375− struct netlbl_dom_map *list_iter;
376− ssize_t tmp_len;
376+ int ret_val = -ENOENT;
377+ u32 iter_bkt;
378+ struct netlbl_dom_map *iter_entry;
379+ u32 chain_cnt = 0;
377380
378− buf_len = NETLBL_LEN_U32;
379381 rcu_read_lock();
380− hsh_tbl = rcu_dereference(netlbl_domhsh);
381− for (bkt_iter = 0; bkt_iter < hsh_tbl->size; bkt_iter++)
382− list_for_each_entry_rcu(list_iter,
383− &hsh_tbl->tbl[bkt_iter], list) {
384− buf_len += NETLBL_LEN_U32 +
385− nla_total_size(strlen(list_iter->domain) + 1);
386− switch (list_iter->type) {
387− case NETLBL_NLTYPE_UNLABELED:
388− break;
389− case NETLBL_NLTYPE_CIPSOV4:
390− buf_len += 2 * NETLBL_LEN_U32;
391− break;
392− }
393− dom_cnt++;
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;
382+ for (iter_bkt = *skip_bkt;
383+ iter_bkt < rcu_dereference(netlbl_domhsh)->size;
384+ iter_bkt++, chain_cnt = 0) {
385+ list_for_each_entry_rcu(iter_entry,
386+ &netlbl_domhsh->tbl[iter_bkt],
387+ list)
388+ if (iter_entry->valid) {
389+ if (chain_cnt++ < *skip_chain)
390+ continue;
391+ ret_val = callback(iter_entry, cb_arg);
392+ if (ret_val < 0) {
393+ chain_cnt--;
394+ goto walk_return;
395+ }
434396 }
435− }
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;
397+ }
508398
509−dump_default_failure:
399+walk_return:
510400 rcu_read_unlock();
511− kfree_skb(skb);
512− return NULL;
401+ *skip_bkt = iter_bkt;
402+ *skip_chain = chain_cnt;
403+ return ret_val;
513404 }
net/netlabel/netlabel_domainhash.h+4−2
@@ -61,7 +61,9 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry); · 60 unmodified lines
6161 int netlbl_domhsh_add_default(struct netlbl_dom_map *entry);
6262 int netlbl_domhsh_remove_default(void);
6363 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
64−struct sk_buff *netlbl_domhsh_dump(size_t headroom);
65−struct sk_buff *netlbl_domhsh_dump_default(size_t headroom);
64+int netlbl_domhsh_walk(u32 *skip_bkt,
65+ u32 *skip_chain,
66+ int (*callback) (struct netlbl_dom_map *entry, void *arg),
67+ void *cb_arg);
6668
6769 #endif
net/netlabel/netlabel_user.c+0−82
@@ -74,85 +74,3 @@ int netlbl_netlink_init(void) · 73 unmodified lines
7474
7575 return 0;
7676 }
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−}
net/netlabel/netlabel_user.h+2−139
@@ -40,72 +40,6 @@ · 39 unmodified lines
4040
4141 /* NetLabel NETLINK helper functions */
4242
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−
10943 /**
11044 * netlbl_netlink_hdr_put - Write the NETLINK buffers into a sk_buff
11145 * @skb: the packet
@@ -124,6 +58,7 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb, · 12 unmodified lines
12458 u32 pid,
12559 u32 seq,
12660 int type,
61+ int flags,
12762 u8 cmd)
12863 {
12964 return genlmsg_put(skb,
@@ -131,85 +66,13 @@ static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb, · 1 unmodified line
13166 seq,
13267 type,
13368 0,
134− 0,
69+ flags,
13570 cmd,
13671 NETLBL_PROTO_VERSION);
13772 }
13873
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−
20974 /* NetLabel NETLINK I/O functions */
21075
21176 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);
21477
21578 #endif