aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2014-11-30 13:56:55 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-12-03 06:43:36 -0500
commit25a76f3463e0424fdf85773afb4be4972b1c0a29 (patch)
tree3b69aec1108133c61443d7cec0425dc0218d0457 /net
parent59de79cf5706b2ad19598fac6c071a5490cb49d8 (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.h56
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
315static void 319static 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);