Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
netlabel_kapi.c
Go to the documentation of this file.
1 /*
2  * NetLabel Kernel API
3  *
4  * This file defines the kernel API for the NetLabel system. The NetLabel
5  * system manages static and dynamic label mappings for network protocols such
6  * as CIPSO and RIPSO.
7  *
8  * Author: Paul Moore <[email protected]>
9  *
10  */
11 
12 /*
13  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
23  * the GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28  *
29  */
30 
31 #include <linux/init.h>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/audit.h>
35 #include <linux/in.h>
36 #include <linux/in6.h>
37 #include <net/ip.h>
38 #include <net/ipv6.h>
39 #include <net/netlabel.h>
40 #include <net/cipso_ipv4.h>
41 #include <asm/bug.h>
42 #include <linux/atomic.h>
43 
44 #include "netlabel_domainhash.h"
45 #include "netlabel_unlabeled.h"
46 #include "netlabel_cipso_v4.h"
47 #include "netlabel_user.h"
48 #include "netlabel_mgmt.h"
49 #include "netlabel_addrlist.h"
50 
51 /*
52  * Configuration Functions
53  */
54 
69 int netlbl_cfg_map_del(const char *domain,
70  u16 family,
71  const void *addr,
72  const void *mask,
73  struct netlbl_audit *audit_info)
74 {
75  if (addr == NULL && mask == NULL) {
76  return netlbl_domhsh_remove(domain, audit_info);
77  } else if (addr != NULL && mask != NULL) {
78  switch (family) {
79  case AF_INET:
80  return netlbl_domhsh_remove_af4(domain, addr, mask,
81  audit_info);
82  default:
83  return -EPFNOSUPPORT;
84  }
85  } else
86  return -EINVAL;
87 }
88 
103 int netlbl_cfg_unlbl_map_add(const char *domain,
104  u16 family,
105  const void *addr,
106  const void *mask,
107  struct netlbl_audit *audit_info)
108 {
109  int ret_val = -ENOMEM;
110  struct netlbl_dom_map *entry;
111  struct netlbl_domaddr_map *addrmap = NULL;
112  struct netlbl_domaddr4_map *map4 = NULL;
113  struct netlbl_domaddr6_map *map6 = NULL;
114 
115  entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
116  if (entry == NULL)
117  return -ENOMEM;
118  if (domain != NULL) {
119  entry->domain = kstrdup(domain, GFP_ATOMIC);
120  if (entry->domain == NULL)
121  goto cfg_unlbl_map_add_failure;
122  }
123 
124  if (addr == NULL && mask == NULL)
125  entry->type = NETLBL_NLTYPE_UNLABELED;
126  else if (addr != NULL && mask != NULL) {
127  addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
128  if (addrmap == NULL)
129  goto cfg_unlbl_map_add_failure;
130  INIT_LIST_HEAD(&addrmap->list4);
131  INIT_LIST_HEAD(&addrmap->list6);
132 
133  switch (family) {
134  case AF_INET: {
135  const struct in_addr *addr4 = addr;
136  const struct in_addr *mask4 = mask;
137  map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
138  if (map4 == NULL)
139  goto cfg_unlbl_map_add_failure;
141  map4->list.addr = addr4->s_addr & mask4->s_addr;
142  map4->list.mask = mask4->s_addr;
143  map4->list.valid = 1;
144  ret_val = netlbl_af4list_add(&map4->list,
145  &addrmap->list4);
146  if (ret_val != 0)
147  goto cfg_unlbl_map_add_failure;
148  break;
149  }
150 #if IS_ENABLED(CONFIG_IPV6)
151  case AF_INET6: {
152  const struct in6_addr *addr6 = addr;
153  const struct in6_addr *mask6 = mask;
154  map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
155  if (map6 == NULL)
156  goto cfg_unlbl_map_add_failure;
158  map6->list.addr = *addr6;
159  map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
160  map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
161  map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
162  map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
163  map6->list.mask = *mask6;
164  map6->list.valid = 1;
165  ret_val = netlbl_af6list_add(&map6->list,
166  &addrmap->list6);
167  if (ret_val != 0)
168  goto cfg_unlbl_map_add_failure;
169  break;
170  }
171 #endif /* IPv6 */
172  default:
173  goto cfg_unlbl_map_add_failure;
174  break;
175  }
176 
177  entry->type_def.addrsel = addrmap;
179  } else {
180  ret_val = -EINVAL;
181  goto cfg_unlbl_map_add_failure;
182  }
183 
184  ret_val = netlbl_domhsh_add(entry, audit_info);
185  if (ret_val != 0)
186  goto cfg_unlbl_map_add_failure;
187 
188  return 0;
189 
190 cfg_unlbl_map_add_failure:
191  kfree(entry->domain);
192  kfree(entry);
193  kfree(addrmap);
194  kfree(map4);
195  kfree(map6);
196  return ret_val;
197 }
198 
199 
217  const char *dev_name,
218  const void *addr,
219  const void *mask,
220  u16 family,
221  u32 secid,
222  struct netlbl_audit *audit_info)
223 {
224  u32 addr_len;
225 
226  switch (family) {
227  case AF_INET:
228  addr_len = sizeof(struct in_addr);
229  break;
230 #if IS_ENABLED(CONFIG_IPV6)
231  case AF_INET6:
232  addr_len = sizeof(struct in6_addr);
233  break;
234 #endif /* IPv6 */
235  default:
236  return -EPFNOSUPPORT;
237  }
238 
239  return netlbl_unlhsh_add(net,
240  dev_name, addr, mask, addr_len,
241  secid, audit_info);
242 }
243 
261  const char *dev_name,
262  const void *addr,
263  const void *mask,
264  u16 family,
265  struct netlbl_audit *audit_info)
266 {
267  u32 addr_len;
268 
269  switch (family) {
270  case AF_INET:
271  addr_len = sizeof(struct in_addr);
272  break;
273 #if IS_ENABLED(CONFIG_IPV6)
274  case AF_INET6:
275  addr_len = sizeof(struct in6_addr);
276  break;
277 #endif /* IPv6 */
278  default:
279  return -EPFNOSUPPORT;
280  }
281 
282  return netlbl_unlhsh_remove(net,
283  dev_name, addr, mask, addr_len,
284  audit_info);
285 }
286 
298  struct netlbl_audit *audit_info)
299 {
300  return cipso_v4_doi_add(doi_def, audit_info);
301 }
302 
313 void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
314 {
315  cipso_v4_doi_remove(doi, audit_info);
316 }
317 
333  const char *domain,
334  const struct in_addr *addr,
335  const struct in_addr *mask,
336  struct netlbl_audit *audit_info)
337 {
338  int ret_val = -ENOMEM;
339  struct cipso_v4_doi *doi_def;
340  struct netlbl_dom_map *entry;
341  struct netlbl_domaddr_map *addrmap = NULL;
342  struct netlbl_domaddr4_map *addrinfo = NULL;
343 
344  doi_def = cipso_v4_doi_getdef(doi);
345  if (doi_def == NULL)
346  return -ENOENT;
347 
348  entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
349  if (entry == NULL)
350  goto out_entry;
351  if (domain != NULL) {
352  entry->domain = kstrdup(domain, GFP_ATOMIC);
353  if (entry->domain == NULL)
354  goto out_domain;
355  }
356 
357  if (addr == NULL && mask == NULL) {
358  entry->type_def.cipsov4 = doi_def;
359  entry->type = NETLBL_NLTYPE_CIPSOV4;
360  } else if (addr != NULL && mask != NULL) {
361  addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
362  if (addrmap == NULL)
363  goto out_addrmap;
364  INIT_LIST_HEAD(&addrmap->list4);
365  INIT_LIST_HEAD(&addrmap->list6);
366 
367  addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
368  if (addrinfo == NULL)
369  goto out_addrinfo;
370  addrinfo->type_def.cipsov4 = doi_def;
371  addrinfo->type = NETLBL_NLTYPE_CIPSOV4;
372  addrinfo->list.addr = addr->s_addr & mask->s_addr;
373  addrinfo->list.mask = mask->s_addr;
374  addrinfo->list.valid = 1;
375  ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
376  if (ret_val != 0)
377  goto cfg_cipsov4_map_add_failure;
378 
379  entry->type_def.addrsel = addrmap;
381  } else {
382  ret_val = -EINVAL;
383  goto out_addrmap;
384  }
385 
386  ret_val = netlbl_domhsh_add(entry, audit_info);
387  if (ret_val != 0)
388  goto cfg_cipsov4_map_add_failure;
389 
390  return 0;
391 
392 cfg_cipsov4_map_add_failure:
393  kfree(addrinfo);
394 out_addrinfo:
395  kfree(addrmap);
396 out_addrmap:
397  kfree(entry->domain);
398 out_domain:
399  kfree(entry);
400 out_entry:
401  cipso_v4_doi_putdef(doi_def);
402  return ret_val;
403 }
404 
405 /*
406  * Security Attribute Functions
407  */
408 
420  u32 offset)
421 {
422  struct netlbl_lsm_secattr_catmap *iter = catmap;
423  u32 node_idx;
424  u32 node_bit;
426 
427  if (offset > iter->startbit) {
428  while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
429  iter = iter->next;
430  if (iter == NULL)
431  return -ENOENT;
432  }
433  node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
434  node_bit = offset - iter->startbit -
435  (NETLBL_CATMAP_MAPSIZE * node_idx);
436  } else {
437  node_idx = 0;
438  node_bit = 0;
439  }
440  bitmap = iter->bitmap[node_idx] >> node_bit;
441 
442  for (;;) {
443  if (bitmap != 0) {
444  while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
445  bitmap >>= 1;
446  node_bit++;
447  }
448  return iter->startbit +
449  (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit;
450  }
451  if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
452  if (iter->next != NULL) {
453  iter = iter->next;
454  node_idx = 0;
455  } else
456  return -ENOENT;
457  }
458  bitmap = iter->bitmap[node_idx];
459  node_bit = 0;
460  }
461 
462  return -ENOENT;
463 }
464 
477  u32 offset)
478 {
479  struct netlbl_lsm_secattr_catmap *iter = catmap;
480  u32 node_idx;
481  u32 node_bit;
484 
485  if (offset > iter->startbit) {
486  while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
487  iter = iter->next;
488  if (iter == NULL)
489  return -ENOENT;
490  }
491  node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
492  node_bit = offset - iter->startbit -
493  (NETLBL_CATMAP_MAPSIZE * node_idx);
494  } else {
495  node_idx = 0;
496  node_bit = 0;
497  }
498  bitmask = NETLBL_CATMAP_BIT << node_bit;
499 
500  for (;;) {
501  bitmap = iter->bitmap[node_idx];
502  while (bitmask != 0 && (bitmap & bitmask) != 0) {
503  bitmask <<= 1;
504  node_bit++;
505  }
506 
507  if (bitmask != 0)
508  return iter->startbit +
509  (NETLBL_CATMAP_MAPSIZE * node_idx) +
510  node_bit - 1;
511  else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
512  if (iter->next == NULL)
513  return iter->startbit + NETLBL_CATMAP_SIZE - 1;
514  iter = iter->next;
515  node_idx = 0;
516  }
517  bitmask = NETLBL_CATMAP_BIT;
518  node_bit = 0;
519  }
520 
521  return -ENOENT;
522 }
523 
536  u32 bit,
537  gfp_t flags)
538 {
539  struct netlbl_lsm_secattr_catmap *iter = catmap;
540  u32 node_bit;
541  u32 node_idx;
542 
543  while (iter->next != NULL &&
544  bit >= (iter->startbit + NETLBL_CATMAP_SIZE))
545  iter = iter->next;
546  if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
547  iter->next = netlbl_secattr_catmap_alloc(flags);
548  if (iter->next == NULL)
549  return -ENOMEM;
550  iter = iter->next;
551  iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
552  }
553 
554  /* gcc always rounds to zero when doing integer division */
555  node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
556  node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx);
557  iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
558 
559  return 0;
560 }
561 
575  u32 start,
576  u32 end,
577  gfp_t flags)
578 {
579  int ret_val = 0;
580  struct netlbl_lsm_secattr_catmap *iter = catmap;
581  u32 iter_max_spot;
582  u32 spot;
583 
584  /* XXX - This could probably be made a bit faster by combining writes
585  * to the catmap instead of setting a single bit each time, but for
586  * right now skipping to the start of the range in the catmap should
587  * be a nice improvement over calling the individual setbit function
588  * repeatedly from a loop. */
589 
590  while (iter->next != NULL &&
591  start >= (iter->startbit + NETLBL_CATMAP_SIZE))
592  iter = iter->next;
593  iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
594 
595  for (spot = start; spot <= end && ret_val == 0; spot++) {
596  if (spot >= iter_max_spot && iter->next != NULL) {
597  iter = iter->next;
598  iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
599  }
600  ret_val = netlbl_secattr_catmap_setbit(iter, spot, flags);
601  }
602 
603  return ret_val;
604 }
605 
606 /*
607  * LSM Functions
608  */
609 
622 int netlbl_enabled(void)
623 {
624  /* At some point we probably want to expose this mechanism to the user
625  * as well so that admins can toggle NetLabel regardless of the
626  * configuration */
627  return (atomic_read(&netlabel_mgmt_protocount) > 0);
628 }
629 
646  u16 family,
647  const struct netlbl_lsm_secattr *secattr)
648 {
649  int ret_val;
650  struct netlbl_dom_map *dom_entry;
651 
652  rcu_read_lock();
653  dom_entry = netlbl_domhsh_getentry(secattr->domain);
654  if (dom_entry == NULL) {
655  ret_val = -ENOENT;
656  goto socket_setattr_return;
657  }
658  switch (family) {
659  case AF_INET:
660  switch (dom_entry->type) {
662  ret_val = -EDESTADDRREQ;
663  break;
665  ret_val = cipso_v4_sock_setattr(sk,
666  dom_entry->type_def.cipsov4,
667  secattr);
668  break;
670  ret_val = 0;
671  break;
672  default:
673  ret_val = -ENOENT;
674  }
675  break;
676 #if IS_ENABLED(CONFIG_IPV6)
677  case AF_INET6:
678  /* since we don't support any IPv6 labeling protocols right
679  * now we can optimize everything away until we do */
680  ret_val = 0;
681  break;
682 #endif /* IPv6 */
683  default:
684  ret_val = -EPROTONOSUPPORT;
685  }
686 
687 socket_setattr_return:
688  rcu_read_unlock();
689  return ret_val;
690 }
691 
702 {
704 }
705 
719  struct netlbl_lsm_secattr *secattr)
720 {
721  int ret_val;
722 
723  switch (sk->sk_family) {
724  case AF_INET:
725  ret_val = cipso_v4_sock_getattr(sk, secattr);
726  break;
727 #if IS_ENABLED(CONFIG_IPV6)
728  case AF_INET6:
729  ret_val = -ENOMSG;
730  break;
731 #endif /* IPv6 */
732  default:
733  ret_val = -EPROTONOSUPPORT;
734  }
735 
736  return ret_val;
737 }
738 
752  struct sockaddr *addr,
753  const struct netlbl_lsm_secattr *secattr)
754 {
755  int ret_val;
756  struct sockaddr_in *addr4;
757  struct netlbl_domaddr4_map *af4_entry;
758 
759  rcu_read_lock();
760  switch (addr->sa_family) {
761  case AF_INET:
762  addr4 = (struct sockaddr_in *)addr;
763  af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
764  addr4->sin_addr.s_addr);
765  if (af4_entry == NULL) {
766  ret_val = -ENOENT;
767  goto conn_setattr_return;
768  }
769  switch (af4_entry->type) {
771  ret_val = cipso_v4_sock_setattr(sk,
772  af4_entry->type_def.cipsov4,
773  secattr);
774  break;
776  /* just delete the protocols we support for right now
777  * but we could remove other protocols if needed */
779  ret_val = 0;
780  break;
781  default:
782  ret_val = -ENOENT;
783  }
784  break;
785 #if IS_ENABLED(CONFIG_IPV6)
786  case AF_INET6:
787  /* since we don't support any IPv6 labeling protocols right
788  * now we can optimize everything away until we do */
789  ret_val = 0;
790  break;
791 #endif /* IPv6 */
792  default:
793  ret_val = -EPROTONOSUPPORT;
794  }
795 
796 conn_setattr_return:
797  rcu_read_unlock();
798  return ret_val;
799 }
800 
812  const struct netlbl_lsm_secattr *secattr)
813 {
814  int ret_val;
815  struct netlbl_dom_map *dom_entry;
816  struct netlbl_domaddr4_map *af4_entry;
817  u32 proto_type;
818  struct cipso_v4_doi *proto_cv4;
819 
820  rcu_read_lock();
821  dom_entry = netlbl_domhsh_getentry(secattr->domain);
822  if (dom_entry == NULL) {
823  ret_val = -ENOENT;
824  goto req_setattr_return;
825  }
826  switch (req->rsk_ops->family) {
827  case AF_INET:
828  if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) {
829  struct inet_request_sock *req_inet = inet_rsk(req);
830  af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
831  req_inet->rmt_addr);
832  if (af4_entry == NULL) {
833  ret_val = -ENOENT;
834  goto req_setattr_return;
835  }
836  proto_type = af4_entry->type;
837  proto_cv4 = af4_entry->type_def.cipsov4;
838  } else {
839  proto_type = dom_entry->type;
840  proto_cv4 = dom_entry->type_def.cipsov4;
841  }
842  switch (proto_type) {
844  ret_val = cipso_v4_req_setattr(req, proto_cv4, secattr);
845  break;
847  /* just delete the protocols we support for right now
848  * but we could remove other protocols if needed */
850  ret_val = 0;
851  break;
852  default:
853  ret_val = -ENOENT;
854  }
855  break;
856 #if IS_ENABLED(CONFIG_IPV6)
857  case AF_INET6:
858  /* since we don't support any IPv6 labeling protocols right
859  * now we can optimize everything away until we do */
860  ret_val = 0;
861  break;
862 #endif /* IPv6 */
863  default:
864  ret_val = -EPROTONOSUPPORT;
865  }
866 
867 req_setattr_return:
868  rcu_read_unlock();
869  return ret_val;
870 }
871 
881 {
883 }
884 
897  u16 family,
898  const struct netlbl_lsm_secattr *secattr)
899 {
900  int ret_val;
901  struct iphdr *hdr4;
902  struct netlbl_domaddr4_map *af4_entry;
903 
904  rcu_read_lock();
905  switch (family) {
906  case AF_INET:
907  hdr4 = ip_hdr(skb);
908  af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
909  hdr4->daddr);
910  if (af4_entry == NULL) {
911  ret_val = -ENOENT;
912  goto skbuff_setattr_return;
913  }
914  switch (af4_entry->type) {
916  ret_val = cipso_v4_skbuff_setattr(skb,
917  af4_entry->type_def.cipsov4,
918  secattr);
919  break;
921  /* just delete the protocols we support for right now
922  * but we could remove other protocols if needed */
923  ret_val = cipso_v4_skbuff_delattr(skb);
924  break;
925  default:
926  ret_val = -ENOENT;
927  }
928  break;
929 #if IS_ENABLED(CONFIG_IPV6)
930  case AF_INET6:
931  /* since we don't support any IPv6 labeling protocols right
932  * now we can optimize everything away until we do */
933  ret_val = 0;
934  break;
935 #endif /* IPv6 */
936  default:
937  ret_val = -EPROTONOSUPPORT;
938  }
939 
940 skbuff_setattr_return:
941  rcu_read_unlock();
942  return ret_val;
943 }
944 
959  u16 family,
960  struct netlbl_lsm_secattr *secattr)
961 {
962  switch (family) {
963  case AF_INET:
964  if (CIPSO_V4_OPTEXIST(skb) &&
965  cipso_v4_skbuff_getattr(skb, secattr) == 0)
966  return 0;
967  break;
968 #if IS_ENABLED(CONFIG_IPV6)
969  case AF_INET6:
970  break;
971 #endif /* IPv6 */
972  }
973 
974  return netlbl_unlabel_getattr(skb, family, secattr);
975 }
976 
989 void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
990 {
991  if (CIPSO_V4_OPTEXIST(skb))
992  cipso_v4_error(skb, error, gateway);
993 }
994 
1005 {
1007 }
1008 
1020 int netlbl_cache_add(const struct sk_buff *skb,
1021  const struct netlbl_lsm_secattr *secattr)
1022 {
1023  if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
1024  return -ENOMSG;
1025 
1026  if (CIPSO_V4_OPTEXIST(skb))
1027  return cipso_v4_cache_add(skb, secattr);
1028 
1029  return -ENOMSG;
1030 }
1031 
1032 /*
1033  * Protocol Engine Functions
1034  */
1035 
1049  struct netlbl_audit *audit_info)
1050 {
1051  return netlbl_audit_start_common(type, audit_info);
1052 }
1053 
1054 /*
1055  * Setup Functions
1056  */
1057 
1065 static int __init netlbl_init(void)
1066 {
1067  int ret_val;
1068 
1069  printk(KERN_INFO "NetLabel: Initializing\n");
1070  printk(KERN_INFO "NetLabel: domain hash size = %u\n",
1071  (1 << NETLBL_DOMHSH_BITSIZE));
1072  printk(KERN_INFO "NetLabel: protocols ="
1073  " UNLABELED"
1074  " CIPSOv4"
1075  "\n");
1076 
1078  if (ret_val != 0)
1079  goto init_failure;
1080 
1082  if (ret_val != 0)
1083  goto init_failure;
1084 
1085  ret_val = netlbl_netlink_init();
1086  if (ret_val != 0)
1087  goto init_failure;
1088 
1089  ret_val = netlbl_unlabel_defconf();
1090  if (ret_val != 0)
1091  goto init_failure;
1092  printk(KERN_INFO "NetLabel: unlabeled traffic allowed by default\n");
1093 
1094  return 0;
1095 
1096 init_failure:
1097  panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
1098 }
1099 
1100 subsys_initcall(netlbl_init);