diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2014-11-30 13:56:55 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-12-03 06:43:36 -0500 |
commit | 25a76f3463e0424fdf85773afb4be4972b1c0a29 (patch) | |
tree | 3b69aec1108133c61443d7cec0425dc0218d0457 /net | |
parent | 59de79cf5706b2ad19598fac6c071a5490cb49d8 (diff) |
netfilter: ipset: Simplify cidr handling for hash:*net* types
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_gen.h | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index 9428fa5ae7c2..8ef9135d8bb5 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h | |||
@@ -147,11 +147,17 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize) | |||
147 | #else | 147 | #else |
148 | #define __CIDR(cidr, i) (cidr) | 148 | #define __CIDR(cidr, i) (cidr) |
149 | #endif | 149 | #endif |
150 | |||
151 | /* cidr + 1 is stored in net_prefixes to support /0 */ | ||
152 | #define SCIDR(cidr, i) (__CIDR(cidr, i) + 1) | ||
153 | |||
150 | #ifdef IP_SET_HASH_WITH_NETS_PACKED | 154 | #ifdef IP_SET_HASH_WITH_NETS_PACKED |
151 | /* When cidr is packed with nomatch, cidr - 1 is stored in the entry */ | 155 | /* When cidr is packed with nomatch, cidr - 1 is stored in the data entry */ |
152 | #define CIDR(cidr, i) (__CIDR(cidr, i) + 1) | 156 | #define GCIDR(cidr, i) (__CIDR(cidr, i) + 1) |
157 | #define NCIDR(cidr) (cidr) | ||
153 | #else | 158 | #else |
154 | #define CIDR(cidr, i) (__CIDR(cidr, i)) | 159 | #define GCIDR(cidr, i) (__CIDR(cidr, i)) |
160 | #define NCIDR(cidr) (cidr - 1) | ||
155 | #endif | 161 | #endif |
156 | 162 | ||
157 | #define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) | 163 | #define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) |
@@ -292,24 +298,22 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n) | |||
292 | int i, j; | 298 | int i, j; |
293 | 299 | ||
294 | /* Add in increasing prefix order, so larger cidr first */ | 300 | /* Add in increasing prefix order, so larger cidr first */ |
295 | for (i = 0, j = -1; i < nets_length && h->nets[i].nets[n]; i++) { | 301 | for (i = 0, j = -1; i < nets_length && h->nets[i].cidr[n]; i++) { |
296 | if (j != -1) | 302 | if (j != -1) |
297 | continue; | 303 | continue; |
298 | else if (h->nets[i].cidr[n] < cidr) | 304 | else if (h->nets[i].cidr[n] < cidr) |
299 | j = i; | 305 | j = i; |
300 | else if (h->nets[i].cidr[n] == cidr) { | 306 | else if (h->nets[i].cidr[n] == cidr) { |
301 | h->nets[i].nets[n]++; | 307 | h->nets[cidr - 1].nets[n]++; |
302 | return; | 308 | return; |
303 | } | 309 | } |
304 | } | 310 | } |
305 | if (j != -1) { | 311 | if (j != -1) { |
306 | for (; i > j; i--) { | 312 | for (; i > j; i--) |
307 | h->nets[i].cidr[n] = h->nets[i - 1].cidr[n]; | 313 | h->nets[i].cidr[n] = h->nets[i - 1].cidr[n]; |
308 | h->nets[i].nets[n] = h->nets[i - 1].nets[n]; | ||
309 | } | ||
310 | } | 314 | } |
311 | h->nets[i].cidr[n] = cidr; | 315 | h->nets[i].cidr[n] = cidr; |
312 | h->nets[i].nets[n] = 1; | 316 | h->nets[cidr - 1].nets[n] = 1; |
313 | } | 317 | } |
314 | 318 | ||
315 | static void | 319 | static void |
@@ -320,16 +324,12 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n) | |||
320 | for (i = 0; i < nets_length; i++) { | 324 | for (i = 0; i < nets_length; i++) { |
321 | if (h->nets[i].cidr[n] != cidr) | 325 | if (h->nets[i].cidr[n] != cidr) |
322 | continue; | 326 | continue; |
323 | if (h->nets[i].nets[n] > 1 || i == net_end || | 327 | h->nets[cidr -1].nets[n]--; |
324 | h->nets[i + 1].nets[n] == 0) { | 328 | if (h->nets[cidr -1].nets[n] > 0) |
325 | h->nets[i].nets[n]--; | ||
326 | return; | 329 | return; |
327 | } | 330 | for (j = i; j < net_end && h->nets[j].cidr[n]; j++) |
328 | for (j = i; j < net_end && h->nets[j].nets[n]; j++) { | ||
329 | h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; | 331 | h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; |
330 | h->nets[j].nets[n] = h->nets[j + 1].nets[n]; | 332 | h->nets[j].cidr[n] = 0; |
331 | } | ||
332 | h->nets[j].nets[n] = 0; | ||
333 | return; | 333 | return; |
334 | } | 334 | } |
335 | } | 335 | } |
@@ -486,7 +486,7 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize) | |||
486 | pr_debug("expired %u/%u\n", i, j); | 486 | pr_debug("expired %u/%u\n", i, j); |
487 | #ifdef IP_SET_HASH_WITH_NETS | 487 | #ifdef IP_SET_HASH_WITH_NETS |
488 | for (k = 0; k < IPSET_NET_COUNT; k++) | 488 | for (k = 0; k < IPSET_NET_COUNT; k++) |
489 | mtype_del_cidr(h, CIDR(data->cidr, k), | 489 | mtype_del_cidr(h, SCIDR(data->cidr, k), |
490 | nets_length, k); | 490 | nets_length, k); |
491 | #endif | 491 | #endif |
492 | ip_set_ext_destroy(set, data); | 492 | ip_set_ext_destroy(set, data); |
@@ -680,9 +680,9 @@ reuse_slot: | |||
680 | data = ahash_data(n, j, set->dsize); | 680 | data = ahash_data(n, j, set->dsize); |
681 | #ifdef IP_SET_HASH_WITH_NETS | 681 | #ifdef IP_SET_HASH_WITH_NETS |
682 | for (i = 0; i < IPSET_NET_COUNT; i++) { | 682 | for (i = 0; i < IPSET_NET_COUNT; i++) { |
683 | mtype_del_cidr(h, CIDR(data->cidr, i), | 683 | mtype_del_cidr(h, SCIDR(data->cidr, i), |
684 | NLEN(set->family), i); | 684 | NLEN(set->family), i); |
685 | mtype_add_cidr(h, CIDR(d->cidr, i), | 685 | mtype_add_cidr(h, SCIDR(d->cidr, i), |
686 | NLEN(set->family), i); | 686 | NLEN(set->family), i); |
687 | } | 687 | } |
688 | #endif | 688 | #endif |
@@ -699,7 +699,7 @@ reuse_slot: | |||
699 | data = ahash_data(n, n->pos++, set->dsize); | 699 | data = ahash_data(n, n->pos++, set->dsize); |
700 | #ifdef IP_SET_HASH_WITH_NETS | 700 | #ifdef IP_SET_HASH_WITH_NETS |
701 | for (i = 0; i < IPSET_NET_COUNT; i++) | 701 | for (i = 0; i < IPSET_NET_COUNT; i++) |
702 | mtype_add_cidr(h, CIDR(d->cidr, i), NLEN(set->family), | 702 | mtype_add_cidr(h, SCIDR(d->cidr, i), NLEN(set->family), |
703 | i); | 703 | i); |
704 | #endif | 704 | #endif |
705 | h->elements++; | 705 | h->elements++; |
@@ -760,7 +760,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, | |||
760 | h->elements--; | 760 | h->elements--; |
761 | #ifdef IP_SET_HASH_WITH_NETS | 761 | #ifdef IP_SET_HASH_WITH_NETS |
762 | for (j = 0; j < IPSET_NET_COUNT; j++) | 762 | for (j = 0; j < IPSET_NET_COUNT; j++) |
763 | mtype_del_cidr(h, CIDR(d->cidr, j), NLEN(set->family), | 763 | mtype_del_cidr(h, SCIDR(d->cidr, j), NLEN(set->family), |
764 | j); | 764 | j); |
765 | #endif | 765 | #endif |
766 | ip_set_ext_destroy(set, data); | 766 | ip_set_ext_destroy(set, data); |
@@ -821,15 +821,15 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d, | |||
821 | u8 nets_length = NLEN(set->family); | 821 | u8 nets_length = NLEN(set->family); |
822 | 822 | ||
823 | pr_debug("test by nets\n"); | 823 | pr_debug("test by nets\n"); |
824 | for (; j < nets_length && h->nets[j].nets[0] && !multi; j++) { | 824 | for (; j < nets_length && h->nets[j].cidr[0] && !multi; j++) { |
825 | #if IPSET_NET_COUNT == 2 | 825 | #if IPSET_NET_COUNT == 2 |
826 | mtype_data_reset_elem(d, &orig); | 826 | mtype_data_reset_elem(d, &orig); |
827 | mtype_data_netmask(d, h->nets[j].cidr[0], false); | 827 | mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0]), false); |
828 | for (k = 0; k < nets_length && h->nets[k].nets[1] && !multi; | 828 | for (k = 0; k < nets_length && h->nets[k].cidr[1] && !multi; |
829 | k++) { | 829 | k++) { |
830 | mtype_data_netmask(d, h->nets[k].cidr[1], true); | 830 | mtype_data_netmask(d, NCIDR(h->nets[k].cidr[1]), true); |
831 | #else | 831 | #else |
832 | mtype_data_netmask(d, h->nets[j].cidr[0]); | 832 | mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0])); |
833 | #endif | 833 | #endif |
834 | key = HKEY(d, h->initval, t->htable_bits); | 834 | key = HKEY(d, h->initval, t->htable_bits); |
835 | n = hbucket(t, key); | 835 | n = hbucket(t, key); |
@@ -877,7 +877,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, | |||
877 | /* If we test an IP address and not a network address, | 877 | /* If we test an IP address and not a network address, |
878 | * try all possible network sizes */ | 878 | * try all possible network sizes */ |
879 | for (i = 0; i < IPSET_NET_COUNT; i++) | 879 | for (i = 0; i < IPSET_NET_COUNT; i++) |
880 | if (CIDR(d->cidr, i) != SET_HOST_MASK(set->family)) | 880 | if (GCIDR(d->cidr, i) != SET_HOST_MASK(set->family)) |
881 | break; | 881 | break; |
882 | if (i == IPSET_NET_COUNT) { | 882 | if (i == IPSET_NET_COUNT) { |
883 | ret = mtype_test_cidrs(set, d, ext, mext, flags); | 883 | ret = mtype_test_cidrs(set, d, ext, mext, flags); |