Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jozsef Kadlecsik and committed by
Pablo Neira Ayuso
25a76f34 59de79cf

+28 -28
+28 -28
net/netfilter/ipset/ip_set_hash_gen.h
··· 147 147 #else 148 148 #define __CIDR(cidr, i) (cidr) 149 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 154 #ifdef IP_SET_HASH_WITH_NETS_PACKED 151 - /* When cidr is packed with nomatch, cidr - 1 is stored in the entry */ 152 - #define CIDR(cidr, i) (__CIDR(cidr, i) + 1) 155 + /* When cidr is packed with nomatch, cidr - 1 is stored in the data entry */ 156 + #define GCIDR(cidr, i) (__CIDR(cidr, i) + 1) 157 + #define NCIDR(cidr) (cidr) 153 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 161 #endif 156 162 157 163 #define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) ··· 298 292 int i, j; 299 293 300 294 /* Add in increasing prefix order, so larger cidr first */ 301 - for (i = 0, j = -1; i < nets_length && h->nets[i].nets[n]; i++) { 295 + for (i = 0, j = -1; i < nets_length && h->nets[i].cidr[n]; i++) { 302 296 if (j != -1) 303 297 continue; 304 298 else if (h->nets[i].cidr[n] < cidr) 305 299 j = i; 306 300 else if (h->nets[i].cidr[n] == cidr) { 307 - h->nets[i].nets[n]++; 301 + h->nets[cidr - 1].nets[n]++; 308 302 return; 309 303 } 310 304 } 311 305 if (j != -1) { 312 - for (; i > j; i--) { 306 + for (; i > j; i--) 313 307 h->nets[i].cidr[n] = h->nets[i - 1].cidr[n]; 314 - h->nets[i].nets[n] = h->nets[i - 1].nets[n]; 315 - } 316 308 } 317 309 h->nets[i].cidr[n] = cidr; 318 - h->nets[i].nets[n] = 1; 310 + h->nets[cidr - 1].nets[n] = 1; 319 311 } 320 312 321 313 static void ··· 324 320 for (i = 0; i < nets_length; i++) { 325 321 if (h->nets[i].cidr[n] != cidr) 326 322 continue; 327 - if (h->nets[i].nets[n] > 1 || i == net_end || 328 - h->nets[i + 1].nets[n] == 0) { 329 - h->nets[i].nets[n]--; 323 + h->nets[cidr -1].nets[n]--; 324 + if (h->nets[cidr -1].nets[n] > 0) 330 325 return; 331 - } 332 - for (j = i; j < net_end && h->nets[j].nets[n]; j++) { 326 + for (j = i; j < net_end && h->nets[j].cidr[n]; j++) 333 327 h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; 334 - h->nets[j].nets[n] = h->nets[j + 1].nets[n]; 335 - } 336 - h->nets[j].nets[n] = 0; 328 + h->nets[j].cidr[n] = 0; 337 329 return; 338 330 } 339 331 } ··· 486 486 pr_debug("expired %u/%u\n", i, j); 487 487 #ifdef IP_SET_HASH_WITH_NETS 488 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 490 nets_length, k); 491 491 #endif 492 492 ip_set_ext_destroy(set, data); ··· 680 680 data = ahash_data(n, j, set->dsize); 681 681 #ifdef IP_SET_HASH_WITH_NETS 682 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 684 NLEN(set->family), i); 685 - mtype_add_cidr(h, CIDR(d->cidr, i), 685 + mtype_add_cidr(h, SCIDR(d->cidr, i), 686 686 NLEN(set->family), i); 687 687 } 688 688 #endif ··· 699 699 data = ahash_data(n, n->pos++, set->dsize); 700 700 #ifdef IP_SET_HASH_WITH_NETS 701 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 703 i); 704 704 #endif 705 705 h->elements++; ··· 760 760 h->elements--; 761 761 #ifdef IP_SET_HASH_WITH_NETS 762 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 764 j); 765 765 #endif 766 766 ip_set_ext_destroy(set, data); ··· 821 821 u8 nets_length = NLEN(set->family); 822 822 823 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 825 #if IPSET_NET_COUNT == 2 826 826 mtype_data_reset_elem(d, &orig); 827 - mtype_data_netmask(d, h->nets[j].cidr[0], false); 828 - for (k = 0; k < nets_length && h->nets[k].nets[1] && !multi; 827 + mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0]), false); 828 + for (k = 0; k < nets_length && h->nets[k].cidr[1] && !multi; 829 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 831 #else 832 - mtype_data_netmask(d, h->nets[j].cidr[0]); 832 + mtype_data_netmask(d, NCIDR(h->nets[j].cidr[0])); 833 833 #endif 834 834 key = HKEY(d, h->initval, t->htable_bits); 835 835 n = hbucket(t, key); ··· 877 877 /* If we test an IP address and not a network address, 878 878 * try all possible network sizes */ 879 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 881 break; 882 882 if (i == IPSET_NET_COUNT) { 883 883 ret = mtype_test_cidrs(set, d, ext, mext, flags);