summaryrefslogtreecommitdiffstats
path: root/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/net/netfilter/ipset/ip_set_hash_ipport.c')
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_ipport.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
index 9f179bb..aa91b2c 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -124,6 +124,14 @@ nla_put_failure:
#define HOST_MASK 32
#include <linux/netfilter/ipset/ip_set_ahash.h>
+static inline void
+hash_ipport4_data_next(struct ip_set_hash *h,
+ const struct hash_ipport4_elem *d)
+{
+ h->next.ip = ntohl(d->ip);
+ h->next.port = ntohs(d->port);
+}
+
static int
hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
@@ -143,12 +151,12 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
static int
hash_ipport4_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_ipport4_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;
@@ -220,8 +228,11 @@ hash_ipport4_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);
@@ -231,6 +242,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
else
ret = 0;
}
+ }
return ret;
}
@@ -328,6 +340,13 @@ nla_put_failure:
#define HOST_MASK 128
#include <linux/netfilter/ipset/ip_set_ahash.h>
+static inline void
+hash_ipport6_data_next(struct ip_set_hash *h,
+ const struct hash_ipport6_elem *d)
+{
+ h->next.port = ntohs(d->port);
+}
+
static int
hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
enum ipset_adt adt, const struct ip_set_adt_opt *opt)
@@ -347,7 +366,7 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
static int
hash_ipport6_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];
@@ -405,6 +424,8 @@ hash_ipport6_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);