summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_gen.h24
1 files changed, 14 insertions, 10 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h
index 7a5b776..3add0bf 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h
@@ -307,18 +307,22 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
static void
mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
{
- u8 i, j;
+ u8 i, j, net_end = nets_length - 1;
- for (i = 0; i < nets_length - 1 && h->nets[i].cidr[n] != cidr; i++)
- ;
- h->nets[i].nets[n]--;
-
- if (h->nets[i].nets[n] != 0)
+ for (i = 0; i < nets_length; i++) {
+ if (h->nets[i].cidr[n] != cidr)
+ continue;
+ if (h->nets[i].nets[n] > 1 || i == net_end ||
+ h->nets[i + 1].nets[n] == 0) {
+ h->nets[i].nets[n]--;
+ return;
+ }
+ for (j = i; j < net_end && h->nets[j].nets[n]; j++) {
+ h->nets[j].cidr[n] = h->nets[j + 1].cidr[n];
+ h->nets[j].nets[n] = h->nets[j + 1].nets[n];
+ }
+ h->nets[j].nets[n] = 0;
return;
-
- for (j = i; j < nets_length - 1 && h->nets[j].nets[n]; j++) {
- h->nets[j].cidr[n] = h->nets[j + 1].cidr[n];
- h->nets[j].nets[n] = h->nets[j + 1].nets[n];
}
}
#endif