summaryrefslogtreecommitdiffstats
path: root/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/net/netfilter/ipset/ip_set_hash_ipportip.c')
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_ipportip.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
index 7cfa52b..b88e74e 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -127,6 +127,14 @@ nla_put_failure:
#define HOST_MASK 32
#include <linux/netfilter/ipset/ip_set_ahash.h>
+static inline void
+hash_ipportip4_data_next(struct ip_set_hash *h,
+ const struct hash_ipportip4_elem *d)
+{
+ h->next.ip = ntohl(d->ip);
+ h->next.port = ntohs(d->port);
+}
+
static int
hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
@@ -147,12 +155,12 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
static int
hash_ipportip4_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 ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip4_elem data = { };
- u32 ip, ip_to, p, port, port_to;
+ u32 ip, ip_to, p = 0, port, port_to;
u32 timeout = h->timeout;
bool with_ports = false;
int ret;
@@ -228,8 +236,11 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
swap(port, port_to);
}
- for (; !before(ip_to, ip); ip++)
- for (p = port; p <= port_to; p++) {
+ if (retried)
+ ip = h->next.ip;
+ for (; !before(ip_to, ip); ip++) {
+ p = retried && ip == h->next.ip ? h->next.port : port;
+ for (; p <= port_to; p++) {
data.ip = htonl(ip);
data.port = htons(p);
ret = adtfn(set, &data, timeout, flags);
@@ -239,6 +250,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
else
ret = 0;
}
+ }
return ret;
}
@@ -341,6 +353,13 @@ nla_put_failure:
#define HOST_MASK 128
#include <linux/netfilter/ipset/ip_set_ahash.h>
+static inline void
+hash_ipportip6_data_next(struct ip_set_hash *h,
+ const struct hash_ipportip6_elem *d)
+{
+ h->next.port = ntohs(d->port);
+}
+
static int
hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
@@ -361,7 +380,7 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
static int
hash_ipportip6_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 ip_set_hash *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
@@ -423,6 +442,8 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
if (port > port_to)
swap(port, port_to);
+ if (retried)
+ port = h->next.port;
for (; port <= port_to; port++) {
data.port = htons(port);
ret = adtfn(set, &data, timeout, flags);