aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlabel/netlabel_unlabeled.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlabel/netlabel_unlabeled.c')
-rw-r--r--net/netlabel/netlabel_unlabeled.c350
1 files changed, 135 insertions, 215 deletions
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index cc105a10e3f8..ab8131a8e489 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 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 16 * it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@
54#include <asm/atomic.h> 54#include <asm/atomic.h>
55 55
56#include "netlabel_user.h" 56#include "netlabel_user.h"
57#include "netlabel_addrlist.h"
57#include "netlabel_domainhash.h" 58#include "netlabel_domainhash.h"
58#include "netlabel_unlabeled.h" 59#include "netlabel_unlabeled.h"
59#include "netlabel_mgmt.h" 60#include "netlabel_mgmt.h"
@@ -76,22 +77,20 @@ struct netlbl_unlhsh_tbl {
76 struct list_head *tbl; 77 struct list_head *tbl;
77 u32 size; 78 u32 size;
78}; 79};
80#define netlbl_unlhsh_addr4_entry(iter) \
81 container_of(iter, struct netlbl_unlhsh_addr4, list)
79struct netlbl_unlhsh_addr4 { 82struct netlbl_unlhsh_addr4 {
80 __be32 addr;
81 __be32 mask;
82 u32 secid; 83 u32 secid;
83 84
84 u32 valid; 85 struct netlbl_af4list list;
85 struct list_head list;
86 struct rcu_head rcu; 86 struct rcu_head rcu;
87}; 87};
88#define netlbl_unlhsh_addr6_entry(iter) \
89 container_of(iter, struct netlbl_unlhsh_addr6, list)
88struct netlbl_unlhsh_addr6 { 90struct netlbl_unlhsh_addr6 {
89 struct in6_addr addr;
90 struct in6_addr mask;
91 u32 secid; 91 u32 secid;
92 92
93 u32 valid; 93 struct netlbl_af6list list;
94 struct list_head list;
95 struct rcu_head rcu; 94 struct rcu_head rcu;
96}; 95};
97struct netlbl_unlhsh_iface { 96struct netlbl_unlhsh_iface {
@@ -274,26 +273,28 @@ static void netlbl_unlhsh_free_addr6(struct rcu_head *entry)
274static void netlbl_unlhsh_free_iface(struct rcu_head *entry) 273static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
275{ 274{
276 struct netlbl_unlhsh_iface *iface; 275 struct netlbl_unlhsh_iface *iface;
277 struct netlbl_unlhsh_addr4 *iter4; 276 struct netlbl_af4list *iter4;
278 struct netlbl_unlhsh_addr4 *tmp4; 277 struct netlbl_af4list *tmp4;
279 struct netlbl_unlhsh_addr6 *iter6; 278#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
280 struct netlbl_unlhsh_addr6 *tmp6; 279 struct netlbl_af6list *iter6;
280 struct netlbl_af6list *tmp6;
281#endif /* IPv6 */
281 282
282 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu); 283 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu);
283 284
284 /* no need for locks here since we are the only one with access to this 285 /* no need for locks here since we are the only one with access to this
285 * structure */ 286 * structure */
286 287
287 list_for_each_entry_safe(iter4, tmp4, &iface->addr4_list, list) 288 netlbl_af4list_foreach_safe(iter4, tmp4, &iface->addr4_list) {
288 if (iter4->valid) { 289 netlbl_af4list_remove_entry(iter4);
289 list_del_rcu(&iter4->list); 290 kfree(netlbl_unlhsh_addr4_entry(iter4));
290 kfree(iter4); 291 }
291 } 292#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
292 list_for_each_entry_safe(iter6, tmp6, &iface->addr6_list, list) 293 netlbl_af6list_foreach_safe(iter6, tmp6, &iface->addr6_list) {
293 if (iter6->valid) { 294 netlbl_af6list_remove_entry(iter6);
294 list_del_rcu(&iter6->list); 295 kfree(netlbl_unlhsh_addr6_entry(iter6));
295 kfree(iter6); 296 }
296 } 297#endif /* IPv6 */
297 kfree(iface); 298 kfree(iface);
298} 299}
299 300
@@ -316,59 +317,6 @@ static u32 netlbl_unlhsh_hash(int ifindex)
316} 317}
317 318
318/** 319/**
319 * netlbl_unlhsh_search_addr4 - Search for a matching IPv4 address entry
320 * @addr: IPv4 address
321 * @iface: the network interface entry
322 *
323 * Description:
324 * Searches the IPv4 address list of the network interface specified by @iface.
325 * If a matching address entry is found it is returned, otherwise NULL is
326 * returned. The caller is responsible for calling the rcu_read_[un]lock()
327 * functions.
328 *
329 */
330static struct netlbl_unlhsh_addr4 *netlbl_unlhsh_search_addr4(
331 __be32 addr,
332 const struct netlbl_unlhsh_iface *iface)
333{
334 struct netlbl_unlhsh_addr4 *iter;
335
336 list_for_each_entry_rcu(iter, &iface->addr4_list, list)
337 if (iter->valid && (addr & iter->mask) == iter->addr)
338 return iter;
339
340 return NULL;
341}
342
343#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
344/**
345 * netlbl_unlhsh_search_addr6 - Search for a matching IPv6 address entry
346 * @addr: IPv6 address
347 * @iface: the network interface entry
348 *
349 * Description:
350 * Searches the IPv6 address list of the network interface specified by @iface.
351 * If a matching address entry is found it is returned, otherwise NULL is
352 * returned. The caller is responsible for calling the rcu_read_[un]lock()
353 * functions.
354 *
355 */
356static struct netlbl_unlhsh_addr6 *netlbl_unlhsh_search_addr6(
357 const struct in6_addr *addr,
358 const struct netlbl_unlhsh_iface *iface)
359{
360 struct netlbl_unlhsh_addr6 *iter;
361
362 list_for_each_entry_rcu(iter, &iface->addr6_list, list)
363 if (iter->valid &&
364 ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
365 return iter;
366
367 return NULL;
368}
369#endif /* IPv6 */
370
371/**
372 * netlbl_unlhsh_search_iface - Search for a matching interface entry 320 * netlbl_unlhsh_search_iface - Search for a matching interface entry
373 * @ifindex: the network interface 321 * @ifindex: the network interface
374 * 322 *
@@ -439,43 +387,26 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
439 const struct in_addr *mask, 387 const struct in_addr *mask,
440 u32 secid) 388 u32 secid)
441{ 389{
390 int ret_val;
442 struct netlbl_unlhsh_addr4 *entry; 391 struct netlbl_unlhsh_addr4 *entry;
443 struct netlbl_unlhsh_addr4 *iter;
444 392
445 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 393 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
446 if (entry == NULL) 394 if (entry == NULL)
447 return -ENOMEM; 395 return -ENOMEM;
448 396
449 entry->addr = addr->s_addr & mask->s_addr; 397 entry->list.addr = addr->s_addr & mask->s_addr;
450 entry->mask = mask->s_addr; 398 entry->list.mask = mask->s_addr;
451 entry->secid = secid; 399 entry->list.valid = 1;
452 entry->valid = 1;
453 INIT_RCU_HEAD(&entry->rcu); 400 INIT_RCU_HEAD(&entry->rcu);
401 entry->secid = secid;
454 402
455 spin_lock(&netlbl_unlhsh_lock); 403 spin_lock(&netlbl_unlhsh_lock);
456 iter = netlbl_unlhsh_search_addr4(entry->addr, iface); 404 ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list);
457 if (iter != NULL &&
458 iter->addr == addr->s_addr && iter->mask == mask->s_addr) {
459 spin_unlock(&netlbl_unlhsh_lock);
460 kfree(entry);
461 return -EEXIST;
462 }
463 /* in order to speed up address searches through the list (the common
464 * case) we need to keep the list in order based on the size of the
465 * address mask such that the entry with the widest mask (smallest
466 * numerical value) appears first in the list */
467 list_for_each_entry_rcu(iter, &iface->addr4_list, list)
468 if (iter->valid &&
469 ntohl(entry->mask) > ntohl(iter->mask)) {
470 __list_add_rcu(&entry->list,
471 iter->list.prev,
472 &iter->list);
473 spin_unlock(&netlbl_unlhsh_lock);
474 return 0;
475 }
476 list_add_tail_rcu(&entry->list, &iface->addr4_list);
477 spin_unlock(&netlbl_unlhsh_lock); 405 spin_unlock(&netlbl_unlhsh_lock);
478 return 0; 406
407 if (ret_val != 0)
408 kfree(entry);
409 return ret_val;
479} 410}
480 411
481#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 412#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -498,47 +429,29 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
498 const struct in6_addr *mask, 429 const struct in6_addr *mask,
499 u32 secid) 430 u32 secid)
500{ 431{
432 int ret_val;
501 struct netlbl_unlhsh_addr6 *entry; 433 struct netlbl_unlhsh_addr6 *entry;
502 struct netlbl_unlhsh_addr6 *iter;
503 434
504 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 435 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
505 if (entry == NULL) 436 if (entry == NULL)
506 return -ENOMEM; 437 return -ENOMEM;
507 438
508 ipv6_addr_copy(&entry->addr, addr); 439 ipv6_addr_copy(&entry->list.addr, addr);
509 entry->addr.s6_addr32[0] &= mask->s6_addr32[0]; 440 entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
510 entry->addr.s6_addr32[1] &= mask->s6_addr32[1]; 441 entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
511 entry->addr.s6_addr32[2] &= mask->s6_addr32[2]; 442 entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
512 entry->addr.s6_addr32[3] &= mask->s6_addr32[3]; 443 entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
513 ipv6_addr_copy(&entry->mask, mask); 444 ipv6_addr_copy(&entry->list.mask, mask);
514 entry->secid = secid; 445 entry->list.valid = 1;
515 entry->valid = 1;
516 INIT_RCU_HEAD(&entry->rcu); 446 INIT_RCU_HEAD(&entry->rcu);
447 entry->secid = secid;
517 448
518 spin_lock(&netlbl_unlhsh_lock); 449 spin_lock(&netlbl_unlhsh_lock);
519 iter = netlbl_unlhsh_search_addr6(&entry->addr, iface); 450 ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list);
520 if (iter != NULL &&
521 (ipv6_addr_equal(&iter->addr, addr) &&
522 ipv6_addr_equal(&iter->mask, mask))) {
523 spin_unlock(&netlbl_unlhsh_lock);
524 kfree(entry);
525 return -EEXIST;
526 }
527 /* in order to speed up address searches through the list (the common
528 * case) we need to keep the list in order based on the size of the
529 * address mask such that the entry with the widest mask (smallest
530 * numerical value) appears first in the list */
531 list_for_each_entry_rcu(iter, &iface->addr6_list, list)
532 if (iter->valid &&
533 ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
534 __list_add_rcu(&entry->list,
535 iter->list.prev,
536 &iter->list);
537 spin_unlock(&netlbl_unlhsh_lock);
538 return 0;
539 }
540 list_add_tail_rcu(&entry->list, &iface->addr6_list);
541 spin_unlock(&netlbl_unlhsh_lock); 451 spin_unlock(&netlbl_unlhsh_lock);
452
453 if (ret_val != 0)
454 kfree(entry);
542 return 0; 455 return 0;
543} 456}
544#endif /* IPv6 */ 457#endif /* IPv6 */
@@ -719,22 +632,21 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
719 const struct in_addr *mask, 632 const struct in_addr *mask,
720 struct netlbl_audit *audit_info) 633 struct netlbl_audit *audit_info)
721{ 634{
722 int ret_val = -ENOENT; 635 int ret_val = 0;
636 struct netlbl_af4list *list_entry;
723 struct netlbl_unlhsh_addr4 *entry; 637 struct netlbl_unlhsh_addr4 *entry;
724 struct audit_buffer *audit_buf = NULL; 638 struct audit_buffer *audit_buf;
725 struct net_device *dev; 639 struct net_device *dev;
726 char *secctx = NULL; 640 char *secctx;
727 u32 secctx_len; 641 u32 secctx_len;
728 642
729 spin_lock(&netlbl_unlhsh_lock); 643 spin_lock(&netlbl_unlhsh_lock);
730 entry = netlbl_unlhsh_search_addr4(addr->s_addr, iface); 644 list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
731 if (entry != NULL && 645 &iface->addr4_list);
732 entry->addr == addr->s_addr && entry->mask == mask->s_addr) {
733 entry->valid = 0;
734 list_del_rcu(&entry->list);
735 ret_val = 0;
736 }
737 spin_unlock(&netlbl_unlhsh_lock); 646 spin_unlock(&netlbl_unlhsh_lock);
647 if (list_entry == NULL)
648 ret_val = -ENOENT;
649 entry = netlbl_unlhsh_addr4_entry(list_entry);
738 650
739 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 651 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
740 audit_info); 652 audit_info);
@@ -742,12 +654,12 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
742 dev = dev_get_by_index(net, iface->ifindex); 654 dev = dev_get_by_index(net, iface->ifindex);
743 netlbl_unlabel_audit_addr4(audit_buf, 655 netlbl_unlabel_audit_addr4(audit_buf,
744 (dev != NULL ? dev->name : NULL), 656 (dev != NULL ? dev->name : NULL),
745 entry->addr, entry->mask); 657 addr->s_addr, mask->s_addr);
746 if (dev != NULL) 658 if (dev != NULL)
747 dev_put(dev); 659 dev_put(dev);
748 if (security_secid_to_secctx(entry->secid, 660 if (entry && security_secid_to_secctx(entry->secid,
749 &secctx, 661 &secctx,
750 &secctx_len) == 0) { 662 &secctx_len) == 0) {
751 audit_log_format(audit_buf, " sec_obj=%s", secctx); 663 audit_log_format(audit_buf, " sec_obj=%s", secctx);
752 security_release_secctx(secctx, secctx_len); 664 security_release_secctx(secctx, secctx_len);
753 } 665 }
@@ -781,23 +693,20 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
781 const struct in6_addr *mask, 693 const struct in6_addr *mask,
782 struct netlbl_audit *audit_info) 694 struct netlbl_audit *audit_info)
783{ 695{
784 int ret_val = -ENOENT; 696 int ret_val = 0;
697 struct netlbl_af6list *list_entry;
785 struct netlbl_unlhsh_addr6 *entry; 698 struct netlbl_unlhsh_addr6 *entry;
786 struct audit_buffer *audit_buf = NULL; 699 struct audit_buffer *audit_buf;
787 struct net_device *dev; 700 struct net_device *dev;
788 char *secctx = NULL; 701 char *secctx;
789 u32 secctx_len; 702 u32 secctx_len;
790 703
791 spin_lock(&netlbl_unlhsh_lock); 704 spin_lock(&netlbl_unlhsh_lock);
792 entry = netlbl_unlhsh_search_addr6(addr, iface); 705 list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list);
793 if (entry != NULL &&
794 (ipv6_addr_equal(&entry->addr, addr) &&
795 ipv6_addr_equal(&entry->mask, mask))) {
796 entry->valid = 0;
797 list_del_rcu(&entry->list);
798 ret_val = 0;
799 }
800 spin_unlock(&netlbl_unlhsh_lock); 706 spin_unlock(&netlbl_unlhsh_lock);
707 if (list_entry == NULL)
708 ret_val = -ENOENT;
709 entry = netlbl_unlhsh_addr6_entry(list_entry);
801 710
802 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 711 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
803 audit_info); 712 audit_info);
@@ -808,9 +717,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
808 addr, mask); 717 addr, mask);
809 if (dev != NULL) 718 if (dev != NULL)
810 dev_put(dev); 719 dev_put(dev);
811 if (security_secid_to_secctx(entry->secid, 720 if (entry && security_secid_to_secctx(entry->secid,
812 &secctx, 721 &secctx,
813 &secctx_len) == 0) { 722 &secctx_len) == 0) {
814 audit_log_format(audit_buf, " sec_obj=%s", secctx); 723 audit_log_format(audit_buf, " sec_obj=%s", secctx);
815 security_release_secctx(secctx, secctx_len); 724 security_release_secctx(secctx, secctx_len);
816 } 725 }
@@ -836,16 +745,18 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
836 */ 745 */
837static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 746static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface)
838{ 747{
839 struct netlbl_unlhsh_addr4 *iter4; 748 struct netlbl_af4list *iter4;
840 struct netlbl_unlhsh_addr6 *iter6; 749#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
750 struct netlbl_af6list *iter6;
751#endif /* IPv6 */
841 752
842 spin_lock(&netlbl_unlhsh_lock); 753 spin_lock(&netlbl_unlhsh_lock);
843 list_for_each_entry_rcu(iter4, &iface->addr4_list, list) 754 netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list)
844 if (iter4->valid) 755 goto unlhsh_condremove_failure;
845 goto unlhsh_condremove_failure; 756#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
846 list_for_each_entry_rcu(iter6, &iface->addr6_list, list) 757 netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list)
847 if (iter6->valid) 758 goto unlhsh_condremove_failure;
848 goto unlhsh_condremove_failure; 759#endif /* IPv6 */
849 iface->valid = 0; 760 iface->valid = 0;
850 if (iface->ifindex > 0) 761 if (iface->ifindex > 0)
851 list_del_rcu(&iface->list); 762 list_del_rcu(&iface->list);
@@ -1349,7 +1260,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1349 if (addr4) { 1260 if (addr4) {
1350 struct in_addr addr_struct; 1261 struct in_addr addr_struct;
1351 1262
1352 addr_struct.s_addr = addr4->addr; 1263 addr_struct.s_addr = addr4->list.addr;
1353 ret_val = nla_put(cb_arg->skb, 1264 ret_val = nla_put(cb_arg->skb,
1354 NLBL_UNLABEL_A_IPV4ADDR, 1265 NLBL_UNLABEL_A_IPV4ADDR,
1355 sizeof(struct in_addr), 1266 sizeof(struct in_addr),
@@ -1357,7 +1268,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1357 if (ret_val != 0) 1268 if (ret_val != 0)
1358 goto list_cb_failure; 1269 goto list_cb_failure;
1359 1270
1360 addr_struct.s_addr = addr4->mask; 1271 addr_struct.s_addr = addr4->list.mask;
1361 ret_val = nla_put(cb_arg->skb, 1272 ret_val = nla_put(cb_arg->skb,
1362 NLBL_UNLABEL_A_IPV4MASK, 1273 NLBL_UNLABEL_A_IPV4MASK,
1363 sizeof(struct in_addr), 1274 sizeof(struct in_addr),
@@ -1370,14 +1281,14 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1370 ret_val = nla_put(cb_arg->skb, 1281 ret_val = nla_put(cb_arg->skb,
1371 NLBL_UNLABEL_A_IPV6ADDR, 1282 NLBL_UNLABEL_A_IPV6ADDR,
1372 sizeof(struct in6_addr), 1283 sizeof(struct in6_addr),
1373 &addr6->addr); 1284 &addr6->list.addr);
1374 if (ret_val != 0) 1285 if (ret_val != 0)
1375 goto list_cb_failure; 1286 goto list_cb_failure;
1376 1287
1377 ret_val = nla_put(cb_arg->skb, 1288 ret_val = nla_put(cb_arg->skb,
1378 NLBL_UNLABEL_A_IPV6MASK, 1289 NLBL_UNLABEL_A_IPV6MASK,
1379 sizeof(struct in6_addr), 1290 sizeof(struct in6_addr),
1380 &addr6->mask); 1291 &addr6->list.mask);
1381 if (ret_val != 0) 1292 if (ret_val != 0)
1382 goto list_cb_failure; 1293 goto list_cb_failure;
1383 1294
@@ -1425,9 +1336,11 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1425 u32 iter_bkt; 1336 u32 iter_bkt;
1426 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1337 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
1427 struct netlbl_unlhsh_iface *iface; 1338 struct netlbl_unlhsh_iface *iface;
1428 struct netlbl_unlhsh_addr4 *addr4;
1429 struct netlbl_unlhsh_addr6 *addr6;
1430 struct list_head *iter_list; 1339 struct list_head *iter_list;
1340 struct netlbl_af4list *addr4;
1341#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1342 struct netlbl_af6list *addr6;
1343#endif
1431 1344
1432 cb_arg.nl_cb = cb; 1345 cb_arg.nl_cb = cb;
1433 cb_arg.skb = skb; 1346 cb_arg.skb = skb;
@@ -1442,38 +1355,38 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1442 if (!iface->valid || 1355 if (!iface->valid ||
1443 iter_chain++ < skip_chain) 1356 iter_chain++ < skip_chain)
1444 continue; 1357 continue;
1445 list_for_each_entry_rcu(addr4, 1358 netlbl_af4list_foreach_rcu(addr4,
1446 &iface->addr4_list, 1359 &iface->addr4_list) {
1447 list) { 1360 if (iter_addr4++ < skip_addr4)
1448 if (!addr4->valid || iter_addr4++ < skip_addr4)
1449 continue; 1361 continue;
1450 if (netlbl_unlabel_staticlist_gen( 1362 if (netlbl_unlabel_staticlist_gen(
1451 NLBL_UNLABEL_C_STATICLIST, 1363 NLBL_UNLABEL_C_STATICLIST,
1452 iface, 1364 iface,
1453 addr4, 1365 netlbl_unlhsh_addr4_entry(addr4),
1454 NULL, 1366 NULL,
1455 &cb_arg) < 0) { 1367 &cb_arg) < 0) {
1456 iter_addr4--; 1368 iter_addr4--;
1457 iter_chain--; 1369 iter_chain--;
1458 goto unlabel_staticlist_return; 1370 goto unlabel_staticlist_return;
1459 } 1371 }
1460 } 1372 }
1461 list_for_each_entry_rcu(addr6, 1373#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1462 &iface->addr6_list, 1374 netlbl_af6list_foreach_rcu(addr6,
1463 list) { 1375 &iface->addr6_list) {
1464 if (!addr6->valid || iter_addr6++ < skip_addr6) 1376 if (iter_addr6++ < skip_addr6)
1465 continue; 1377 continue;
1466 if (netlbl_unlabel_staticlist_gen( 1378 if (netlbl_unlabel_staticlist_gen(
1467 NLBL_UNLABEL_C_STATICLIST, 1379 NLBL_UNLABEL_C_STATICLIST,
1468 iface, 1380 iface,
1469 NULL, 1381 NULL,
1470 addr6, 1382 netlbl_unlhsh_addr6_entry(addr6),
1471 &cb_arg) < 0) { 1383 &cb_arg) < 0) {
1472 iter_addr6--; 1384 iter_addr6--;
1473 iter_chain--; 1385 iter_chain--;
1474 goto unlabel_staticlist_return; 1386 goto unlabel_staticlist_return;
1475 } 1387 }
1476 } 1388 }
1389#endif /* IPv6 */
1477 } 1390 }
1478 } 1391 }
1479 1392
@@ -1504,9 +1417,12 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1504 struct netlbl_unlhsh_iface *iface; 1417 struct netlbl_unlhsh_iface *iface;
1505 u32 skip_addr4 = cb->args[0]; 1418 u32 skip_addr4 = cb->args[0];
1506 u32 skip_addr6 = cb->args[1]; 1419 u32 skip_addr6 = cb->args[1];
1507 u32 iter_addr4 = 0, iter_addr6 = 0; 1420 u32 iter_addr4 = 0;
1508 struct netlbl_unlhsh_addr4 *addr4; 1421 struct netlbl_af4list *addr4;
1509 struct netlbl_unlhsh_addr6 *addr6; 1422#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1423 u32 iter_addr6 = 0;
1424 struct netlbl_af6list *addr6;
1425#endif
1510 1426
1511 cb_arg.nl_cb = cb; 1427 cb_arg.nl_cb = cb;
1512 cb_arg.skb = skb; 1428 cb_arg.skb = skb;
@@ -1517,30 +1433,32 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1517 if (iface == NULL || !iface->valid) 1433 if (iface == NULL || !iface->valid)
1518 goto unlabel_staticlistdef_return; 1434 goto unlabel_staticlistdef_return;
1519 1435
1520 list_for_each_entry_rcu(addr4, &iface->addr4_list, list) { 1436 netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
1521 if (!addr4->valid || iter_addr4++ < skip_addr4) 1437 if (iter_addr4++ < skip_addr4)
1522 continue; 1438 continue;
1523 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1439 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1524 iface, 1440 iface,
1525 addr4, 1441 netlbl_unlhsh_addr4_entry(addr4),
1526 NULL, 1442 NULL,
1527 &cb_arg) < 0) { 1443 &cb_arg) < 0) {
1528 iter_addr4--; 1444 iter_addr4--;
1529 goto unlabel_staticlistdef_return; 1445 goto unlabel_staticlistdef_return;
1530 } 1446 }
1531 } 1447 }
1532 list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { 1448#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1533 if (!addr6->valid || iter_addr6++ < skip_addr6) 1449 netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
1450 if (iter_addr6++ < skip_addr6)
1534 continue; 1451 continue;
1535 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1452 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1536 iface, 1453 iface,
1537 NULL, 1454 NULL,
1538 addr6, 1455 netlbl_unlhsh_addr6_entry(addr6),
1539 &cb_arg) < 0) { 1456 &cb_arg) < 0) {
1540 iter_addr6--; 1457 iter_addr6--;
1541 goto unlabel_staticlistdef_return; 1458 goto unlabel_staticlistdef_return;
1542 } 1459 }
1543 } 1460 }
1461#endif /* IPv6 */
1544 1462
1545unlabel_staticlistdef_return: 1463unlabel_staticlistdef_return:
1546 rcu_read_unlock(); 1464 rcu_read_unlock();
@@ -1718,25 +1636,27 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
1718 switch (family) { 1636 switch (family) {
1719 case PF_INET: { 1637 case PF_INET: {
1720 struct iphdr *hdr4; 1638 struct iphdr *hdr4;
1721 struct netlbl_unlhsh_addr4 *addr4; 1639 struct netlbl_af4list *addr4;
1722 1640
1723 hdr4 = ip_hdr(skb); 1641 hdr4 = ip_hdr(skb);
1724 addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); 1642 addr4 = netlbl_af4list_search(hdr4->saddr,
1643 &iface->addr4_list);
1725 if (addr4 == NULL) 1644 if (addr4 == NULL)
1726 goto unlabel_getattr_nolabel; 1645 goto unlabel_getattr_nolabel;
1727 secattr->attr.secid = addr4->secid; 1646 secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid;
1728 break; 1647 break;
1729 } 1648 }
1730#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1649#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1731 case PF_INET6: { 1650 case PF_INET6: {
1732 struct ipv6hdr *hdr6; 1651 struct ipv6hdr *hdr6;
1733 struct netlbl_unlhsh_addr6 *addr6; 1652 struct netlbl_af6list *addr6;
1734 1653
1735 hdr6 = ipv6_hdr(skb); 1654 hdr6 = ipv6_hdr(skb);
1736 addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); 1655 addr6 = netlbl_af6list_search(&hdr6->saddr,
1656 &iface->addr6_list);
1737 if (addr6 == NULL) 1657 if (addr6 == NULL)
1738 goto unlabel_getattr_nolabel; 1658 goto unlabel_getattr_nolabel;
1739 secattr->attr.secid = addr6->secid; 1659 secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid;
1740 break; 1660 break;
1741 } 1661 }
1742#endif /* IPv6 */ 1662#endif /* IPv6 */