diff options
author | melifaro <melifaro@FreeBSD.org> | 2013-10-16 12:18:44 +0000 |
---|---|---|
committer | melifaro <melifaro@FreeBSD.org> | 2013-10-16 12:18:44 +0000 |
commit | da935edd8d135bfcace4cf1cad624a344774d6bf (patch) | |
tree | 8699180684f902eb68c9989ded1ac7b9209f6df0 /sys/net/radix.h | |
parent | 1adf8620134b63b0819febb2c1a930ba1736c6ab (diff) | |
download | FreeBSD-src-da935edd8d135bfcace4cf1cad624a344774d6bf.zip FreeBSD-src-da935edd8d135bfcace4cf1cad624a344774d6bf.tar.gz |
Fix long-standing issue with incorrect radix mask calculation.
Usual symptoms are messages like
rn_delete: inconsistent annotation
rn_addmask: mask impossibly already in tree
or inability to flush/delete particular prefix in ipfw table.
Changes:
* Assume 32 bytes as maximum radix key length
* Remove rn_init()
* Statically allocate rn_ones/rn_zeroes
* Make separate mask tree for each "normal" tree instead of system global one
* Remove "optimization" on masks reusage and key zeroying
* Change rn_addmask() arguments to accept tree pointer (no users in base)
PR: kern/182851, kern/169206, kern/135476, kern/134531
Found by: Slawa Olhovchenkov <slw@zxy.spb.ru>
MFC after: 2 weeks
Reviewed by: glebius
Sponsored by: Yandex LLC
Diffstat (limited to 'sys/net/radix.h')
-rw-r--r-- | sys/net/radix.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/net/radix.h b/sys/net/radix.h index f11c7d8..06cd37b 100644 --- a/sys/net/radix.h +++ b/sys/net/radix.h @@ -124,6 +124,7 @@ struct radix_node_head { void (*rnh_close) /* do something when the last ref drops */ (struct radix_node *rn, struct radix_node_head *head); struct radix_node rnh_nodes[3]; /* empty tree for common case */ + struct radix_node_head *rnh_masks; /* Storage for our masks */ #ifdef _KERNEL struct rwlock rnh_lock; /* locks entire radix tree */ #endif @@ -152,12 +153,11 @@ struct radix_node_head { #define RADIX_NODE_HEAD_WLOCK_ASSERT(rnh) rw_assert(&(rnh)->rnh_lock, RA_WLOCKED) #endif /* _KERNEL */ -void rn_init(int); int rn_inithead(void **, int); int rn_detachhead(void **); int rn_refines(void *, void *); struct radix_node - *rn_addmask(void *, int, int), + *rn_addmask(void *, struct radix_node_head *, int, int), *rn_addroute (void *, void *, struct radix_node_head *, struct radix_node [2]), *rn_delete(void *, void *, struct radix_node_head *), |