aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/ipset/ip_set_bitmap_ipmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter/ipset/ip_set_bitmap_ipmac.c')
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ipmac.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index a274300b6a56..56096f544978 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -99,7 +99,7 @@ bitmap_ipmac_exist(const struct ipmac_telem *elem)
/* Base variant */
static int
-bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout)
+bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
{
const struct bitmap_ipmac *map = set->data;
const struct ipmac *data = value;
@@ -117,7 +117,7 @@ bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout)
}
static int
-bitmap_ipmac_add(struct ip_set *set, void *value, u32 timeout)
+bitmap_ipmac_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
{
struct bitmap_ipmac *map = set->data;
const struct ipmac *data = value;
@@ -146,7 +146,7 @@ bitmap_ipmac_add(struct ip_set *set, void *value, u32 timeout)
}
static int
-bitmap_ipmac_del(struct ip_set *set, void *value, u32 timeout)
+bitmap_ipmac_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
{
struct bitmap_ipmac *map = set->data;
const struct ipmac *data = value;
@@ -212,7 +212,7 @@ nla_put_failure:
/* Timeout variant */
static int
-bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout)
+bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
{
const struct bitmap_ipmac *map = set->data;
const struct ipmac *data = value;
@@ -231,15 +231,16 @@ bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout)
}
static int
-bitmap_ipmac_tadd(struct ip_set *set, void *value, u32 timeout)
+bitmap_ipmac_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
{
struct bitmap_ipmac *map = set->data;
const struct ipmac *data = value;
struct ipmac_telem *elem = bitmap_ipmac_elem(map, data->id);
+ bool flag_exist = flags & IPSET_FLAG_EXIST;
switch (elem->match) {
case MAC_UNSET:
- if (!data->ether)
+ if (!(data->ether || flag_exist))
/* Already added without ethernet address */
return -IPSET_ERR_EXIST;
/* Fill the MAC address and activate the timer */
@@ -251,7 +252,7 @@ bitmap_ipmac_tadd(struct ip_set *set, void *value, u32 timeout)
elem->timeout = ip_set_timeout_set(timeout);
break;
case MAC_FILLED:
- if (!bitmap_expired(map, data->id))
+ if (!(bitmap_expired(map, data->id) || flag_exist))
return -IPSET_ERR_EXIST;
/* Fall through */
case MAC_EMPTY:
@@ -273,7 +274,7 @@ bitmap_ipmac_tadd(struct ip_set *set, void *value, u32 timeout)
}
static int
-bitmap_ipmac_tdel(struct ip_set *set, void *value, u32 timeout)
+bitmap_ipmac_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
{
struct bitmap_ipmac *map = set->data;
const struct ipmac *data = value;
@@ -337,17 +338,18 @@ nla_put_failure:
static int
bitmap_ipmac_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_ipmac *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct ipmac data;
/* MAC can be src only */
- if (!(flags & IPSET_DIM_TWO_SRC))
+ if (!(opt->flags & IPSET_DIM_TWO_SRC))
return 0;
- data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
+ data.id = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
if (data.id < map->first_ip || data.id > map->last_ip)
return -IPSET_ERR_BITMAP_RANGE;
@@ -359,12 +361,12 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
data.id -= map->first_ip;
data.ether = eth_hdr(skb)->h_source;
- return adtfn(set, &data, map->timeout);
+ return adtfn(set, &data, opt_timeout(opt, map), opt->cmdflags);
}
static int
bitmap_ipmac_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)
{
const struct bitmap_ipmac *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
@@ -399,7 +401,7 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
data.id -= map->first_ip;
- ret = adtfn(set, &data, timeout);
+ ret = adtfn(set, &data, timeout, flags);
return ip_set_eexist(ret, flags) ? 0 : ret;
}
@@ -577,7 +579,7 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
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;
@@ -622,7 +624,8 @@ static struct ip_set_type bitmap_ipmac_type = {
.features = IPSET_TYPE_IP | IPSET_TYPE_MAC,
.dimension = IPSET_DIM_TWO,
.family = AF_INET,
- .revision = 0,
+ .revision_min = 0,
+ .revision_max = 0,
.create = bitmap_ipmac_create,
.create_policy = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -632,7 +635,8 @@ static struct ip_set_type bitmap_ipmac_type = {
},
.adt_policy = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED },
- [IPSET_ATTR_ETHER] = { .type = NLA_BINARY, .len = ETH_ALEN },
+ [IPSET_ATTR_ETHER] = { .type = NLA_BINARY,
+ .len = ETH_ALEN },
[IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
[IPSET_ATTR_LINENO] = { .type = NLA_U32 },
},