netfilter: ipset: add xt_action_param to the variant level kadt functions, ipset...
[linux-2.6.git] / net / netfilter / ipset / ip_set_bitmap_ip.c
index bca9699..e3e7399 100644 (file)
@@ -54,7 +54,7 @@ ip_to_id(const struct bitmap_ip *m, u32 ip)
 }
 
 static int
-bitmap_ip_test(struct ip_set *set, void *value, u32 timeout)
+bitmap_ip_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
 {
        const struct bitmap_ip *map = set->data;
        u16 id = *(u16 *)value;
@@ -63,7 +63,7 @@ bitmap_ip_test(struct ip_set *set, void *value, u32 timeout)
 }
 
 static int
-bitmap_ip_add(struct ip_set *set, void *value, u32 timeout)
+bitmap_ip_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
 {
        struct bitmap_ip *map = set->data;
        u16 id = *(u16 *)value;
@@ -75,7 +75,7 @@ bitmap_ip_add(struct ip_set *set, void *value, u32 timeout)
 }
 
 static int
-bitmap_ip_del(struct ip_set *set, void *value, u32 timeout)
+bitmap_ip_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
 {
        struct bitmap_ip *map = set->data;
        u16 id = *(u16 *)value;
@@ -131,7 +131,7 @@ nla_put_failure:
 /* Timeout variant */
 
 static int
-bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout)
+bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
 {
        const struct bitmap_ip *map = set->data;
        const unsigned long *members = map->members;
@@ -141,13 +141,13 @@ bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout)
 }
 
 static int
-bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout)
+bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
 {
        struct bitmap_ip *map = set->data;
        unsigned long *members = map->members;
        u16 id = *(u16 *)value;
 
-       if (ip_set_timeout_test(members[id]))
+       if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST))
                return -IPSET_ERR_EXIST;
 
        members[id] = ip_set_timeout_set(timeout);
@@ -156,7 +156,7 @@ bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout)
 }
 
 static int
-bitmap_ip_tdel(struct ip_set *set, void *value, u32 timeout)
+bitmap_ip_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
 {
        struct bitmap_ip *map = set->data;
        unsigned long *members = map->members;
@@ -219,24 +219,25 @@ nla_put_failure:
 
 static int
 bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
-              enum ipset_adt adt, u8 pf, u8 dim, u8 flags)
+              const struct xt_action_param *par,
+              enum ipset_adt adt, const struct ip_set_adt_opt *opt)
 {
        struct bitmap_ip *map = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
        u32 ip;
 
-       ip = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
+       ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
        if (ip < map->first_ip || ip > map->last_ip)
                return -IPSET_ERR_BITMAP_RANGE;
 
        ip = ip_to_id(map, ip);
 
-       return adtfn(set, &ip, map->timeout);
+       return adtfn(set, &ip, opt_timeout(opt, map), opt->cmdflags);
 }
 
 static int
 bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
-              enum ipset_adt adt, u32 *lineno, u32 flags)
+              enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
 {
        struct bitmap_ip *map = set->data;
        ipset_adtfn adtfn = set->variant->adt[adt];
@@ -266,7 +267,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
 
        if (adt == IPSET_TEST) {
                id = ip_to_id(map, ip);
-               return adtfn(set, &id, timeout);
+               return adtfn(set, &id, timeout, flags);
        }
 
        if (tb[IPSET_ATTR_IP_TO]) {
@@ -283,8 +284,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
 
                if (cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               ip &= ip_set_hostmask(cidr);
-               ip_to = ip | ~ip_set_hostmask(cidr);
+               ip_set_mask_from_to(ip, ip_to, cidr);
        } else
                ip_to = ip;
 
@@ -293,7 +293,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
 
        for (; !before(ip_to, ip); ip += map->hosts) {
                id = ip_to_id(map, ip);
-               ret = adtfn(set, &id, timeout);;
+               ret = adtfn(set, &id, timeout, flags);
 
                if (ret && !ip_set_eexist(ret, flags))
                        return ret;
@@ -338,8 +338,7 @@ bitmap_ip_head(struct ip_set *set, struct sk_buff *skb)
        NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
        if (map->netmask != 32)
                NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask);
-       NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
-                     htonl(atomic_read(&set->ref) - 1));
+       NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
        NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
                      htonl(sizeof(*map) + map->memsize));
        if (with_timeout(map->timeout))
@@ -479,7 +478,7 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 
                if (cidr >= 32)
                        return -IPSET_ERR_INVALID_CIDR;
-               last_ip = first_ip | ~ip_set_hostmask(cidr);
+               ip_set_mask_from_to(first_ip, last_ip, cidr);
        } else
                return -IPSET_ERR_PROTOCOL;
 
@@ -552,7 +551,8 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
        .features       = IPSET_TYPE_IP,
        .dimension      = IPSET_DIM_ONE,
        .family         = AF_INET,
-       .revision       = 0,
+       .revision_min   = 0,
+       .revision_max   = 0,
        .create         = bitmap_ip_create,
        .create_policy  = {
                [IPSET_ATTR_IP]         = { .type = NLA_NESTED },