[PATCH 02/22] netfilter: ipset: Headers file cleanup

2016-10-23 Thread Jozsef Kadlecsik
Remove extra whitespace, group counter helper together. Mark some of
the helpers arguments as const.

Ported from a patch proposed by Sergey Popovich .

Suggested-by: Sergey Popovich 
Signed-off-by: Jozsef Kadlecsik 
---
 include/linux/netfilter/ipset/ip_set.h | 57 +-
 include/linux/netfilter/ipset/ip_set_comment.h |  2 +-
 include/linux/netfilter/ipset/ip_set_timeout.h |  4 +-
 3 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/include/linux/netfilter/ipset/ip_set.h 
b/include/linux/netfilter/ipset/ip_set.h
index 83b9a2e..1ea28e3 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -334,18 +334,40 @@ struct ip_set {
}
 }
 
+static inline bool
+ip_set_put_counter(struct sk_buff *skb, const struct ip_set_counter *counter)
+{
+   return nla_put_net64(skb, IPSET_ATTR_BYTES,
+cpu_to_be64(ip_set_get_bytes(counter)),
+IPSET_ATTR_PAD) ||
+  nla_put_net64(skb, IPSET_ATTR_PACKETS,
+cpu_to_be64(ip_set_get_packets(counter)),
+IPSET_ATTR_PAD);
+}
+
+static inline void
+ip_set_init_counter(struct ip_set_counter *counter,
+   const struct ip_set_ext *ext)
+{
+   if (ext->bytes != ULLONG_MAX)
+   atomic64_set(&(counter)->bytes, (long long)(ext->bytes));
+   if (ext->packets != ULLONG_MAX)
+   atomic64_set(&(counter)->packets, (long long)(ext->packets));
+}
+
 static inline void
 ip_set_get_skbinfo(struct ip_set_skbinfo *skbinfo,
- const struct ip_set_ext *ext,
- struct ip_set_ext *mext, u32 flags)
+  const struct ip_set_ext *ext,
+  struct ip_set_ext *mext, u32 flags)
 {
-   mext->skbmark = skbinfo->skbmark;
-   mext->skbmarkmask = skbinfo->skbmarkmask;
-   mext->skbprio = skbinfo->skbprio;
-   mext->skbqueue = skbinfo->skbqueue;
+   mext->skbmark = skbinfo->skbmark;
+   mext->skbmarkmask = skbinfo->skbmarkmask;
+   mext->skbprio = skbinfo->skbprio;
+   mext->skbqueue = skbinfo->skbqueue;
 }
+
 static inline bool
-ip_set_put_skbinfo(struct sk_buff *skb, struct ip_set_skbinfo *skbinfo)
+ip_set_put_skbinfo(struct sk_buff *skb, const struct ip_set_skbinfo *skbinfo)
 {
/* Send nonzero parameters only */
return ((skbinfo->skbmark || skbinfo->skbmarkmask) &&
@@ -371,27 +393,6 @@ struct ip_set {
skbinfo->skbqueue = ext->skbqueue;
 }
 
-static inline bool
-ip_set_put_counter(struct sk_buff *skb, struct ip_set_counter *counter)
-{
-   return nla_put_net64(skb, IPSET_ATTR_BYTES,
-cpu_to_be64(ip_set_get_bytes(counter)),
-IPSET_ATTR_PAD) ||
-  nla_put_net64(skb, IPSET_ATTR_PACKETS,
-cpu_to_be64(ip_set_get_packets(counter)),
-IPSET_ATTR_PAD);
-}
-
-static inline void
-ip_set_init_counter(struct ip_set_counter *counter,
-   const struct ip_set_ext *ext)
-{
-   if (ext->bytes != ULLONG_MAX)
-   atomic64_set(&(counter)->bytes, (long long)(ext->bytes));
-   if (ext->packets != ULLONG_MAX)
-   atomic64_set(&(counter)->packets, (long long)(ext->packets));
-}
-
 /* Netlink CB args */
 enum {
IPSET_CB_NET = 0,   /* net namespace */
diff --git a/include/linux/netfilter/ipset/ip_set_comment.h 
b/include/linux/netfilter/ipset/ip_set_comment.h
index 8d02485..bae5c76 100644
--- a/include/linux/netfilter/ipset/ip_set_comment.h
+++ b/include/linux/netfilter/ipset/ip_set_comment.h
@@ -43,7 +43,7 @@
 
 /* Used only when dumping a set, protected by rcu_read_lock_bh() */
 static inline int
-ip_set_put_comment(struct sk_buff *skb, struct ip_set_comment *comment)
+ip_set_put_comment(struct sk_buff *skb, const struct ip_set_comment *comment)
 {
struct ip_set_comment_rcu *c = rcu_dereference_bh(comment->c);
 
diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h 
b/include/linux/netfilter/ipset/ip_set_timeout.h
index 1d6a935..bfb3531 100644
--- a/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -40,7 +40,7 @@
 }
 
 static inline bool
-ip_set_timeout_expired(unsigned long *t)
+ip_set_timeout_expired(const unsigned long *t)
 {
return *t != IPSET_ELEM_PERMANENT && time_is_before_jiffies(*t);
 }
@@ -63,7 +63,7 @@
 }
 
 static inline u32
-ip_set_timeout_get(unsigned long *timeout)
+ip_set_timeout_get(const unsigned long *timeout)
 {
return *timeout == IPSET_ELEM_PERMANENT ? 0 :
jiffies_to_msecs(*timeout - jiffies)/MSEC_PER_SEC;
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More 

[PATCH 17/22] netfilter: ipset: Fix reported memory size for hash:* types

2016-10-23 Thread Jozsef Kadlecsik
The calculation of the full allocated memory did not take
into account the size of the base hash bucket structure at some
places.

Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index f4b30b6..295ad84 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -87,6 +87,8 @@ struct htable {
 };
 
 #define hbucket(h, i)  ((h)->bucket[i])
+#define ext_size(n, dsize) \
+   (sizeof(struct hbucket) + (n) * (dsize))
 
 #ifndef IPSET_NET_COUNT
 #define IPSET_NET_COUNT1
@@ -521,7 +523,7 @@ struct htype {
d++;
}
tmp->pos = d;
-   set->ext_size -= AHASH_INIT_SIZE * dsize;
+   set->ext_size -= ext_size(AHASH_INIT_SIZE, dsize);
rcu_assign_pointer(hbucket(t, i), tmp);
kfree_rcu(n, rcu);
}
@@ -627,7 +629,7 @@ struct htype {
goto cleanup;
}
m->size = AHASH_INIT_SIZE;
-   extsize = sizeof(*m) + AHASH_INIT_SIZE * dsize;
+   extsize = ext_size(AHASH_INIT_SIZE, dsize);
RCU_INIT_POINTER(hbucket(t, key), m);
} else if (m->pos >= m->size) {
struct hbucket *ht;
@@ -647,7 +649,7 @@ struct htype {
memcpy(ht, m, sizeof(struct hbucket) +
  m->size * dsize);
ht->size = m->size + AHASH_INIT_SIZE;
-   extsize += AHASH_INIT_SIZE * dsize;
+   extsize += ext_size(AHASH_INIT_SIZE, dsize);
kfree(m);
m = ht;
RCU_INIT_POINTER(hbucket(t, key), ht);
@@ -729,7 +731,7 @@ struct htype {
if (!n)
return -ENOMEM;
n->size = AHASH_INIT_SIZE;
-   set->ext_size += sizeof(*n) + AHASH_INIT_SIZE * set->dsize;
+   set->ext_size += ext_size(AHASH_INIT_SIZE, set->dsize);
goto copy_elem;
}
for (i = 0; i < n->pos; i++) {
@@ -793,7 +795,7 @@ struct htype {
memcpy(n, old, sizeof(struct hbucket) +
   old->size * set->dsize);
n->size = old->size + AHASH_INIT_SIZE;
-   set->ext_size += AHASH_INIT_SIZE * set->dsize;
+   set->ext_size += ext_size(AHASH_INIT_SIZE, set->dsize);
}
 
 copy_elem:
@@ -885,7 +887,7 @@ struct htype {
k++;
}
if (n->pos == 0 && k == 0) {
-   set->ext_size -= sizeof(*n) + n->size * dsize;
+   set->ext_size -= ext_size(n->size, dsize);
rcu_assign_pointer(hbucket(t, key), NULL);
kfree_rcu(n, rcu);
} else if (k >= AHASH_INIT_SIZE) {
@@ -904,7 +906,7 @@ struct htype {
k++;
}
tmp->pos = k;
-   set->ext_size -= AHASH_INIT_SIZE * dsize;
+   set->ext_size -= ext_size(AHASH_INIT_SIZE, dsize);
rcu_assign_pointer(hbucket(t, key), tmp);
kfree_rcu(n, rcu);
}
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 20/22] netfilter: ipset: use setup_timer() and mod_timer().

2016-10-23 Thread Jozsef Kadlecsik
From: Muhammad Falak R Wani 

Use setup_timer() and instead of init_timer(), being the preferred way
of setting up a timer.

Also, quoting the mod_timer() function comment:
-> mod_timer() is a more efficient way to update the expire field of an
   active timer (if the timer is inactive it will be activated).

Use setup_timer() and mod_timer() to setup and arm a timer, making the
code compact and easier to read.

Signed-off-by: Muhammad Falak R Wani 
Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index 295ad84..0d5f83e 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -435,11 +435,8 @@ struct htype {
 {
struct htype *h = set->data;
 
-   init_timer(>gc);
-   h->gc.data = (unsigned long)set;
-   h->gc.function = gc;
-   h->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
-   add_timer(>gc);
+   setup_timer(>gc, gc, (unsigned long)set);
+   mod_timer(>gc, jiffies + IPSET_GC_PERIOD(set->timeout) * HZ);
pr_debug("gc initialized, run in every %u\n",
 IPSET_GC_PERIOD(set->timeout));
 }
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 14/22] netfilter: ipset: Optimize hash creation routine

2016-10-23 Thread Jozsef Kadlecsik
Exit as easly as possible on error and use RCU_INIT_POINTER()
as set is not seen at creation time.

Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 63 ---
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index e2f4925..cc9208b 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -1243,41 +1243,35 @@ struct htype {
struct htype *h;
struct htable *t;
 
+   pr_debug("Create set %s with family %s\n",
+set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6");
+
 #ifndef IP_SET_PROTO_UNDEF
if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
return -IPSET_ERR_INVALID_FAMILY;
 #endif
 
-#ifdef IP_SET_HASH_WITH_MARKMASK
-   markmask = 0x;
-#endif
-#ifdef IP_SET_HASH_WITH_NETMASK
-   netmask = set->family == NFPROTO_IPV4 ? 32 : 128;
-   pr_debug("Create set %s with family %s\n",
-set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6");
-#endif
-
if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
return -IPSET_ERR_PROTOCOL;
+
 #ifdef IP_SET_HASH_WITH_MARKMASK
/* Separated condition in order to avoid directive in argument list */
if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_MARKMASK)))
return -IPSET_ERR_PROTOCOL;
-#endif
 
-   if (tb[IPSET_ATTR_HASHSIZE]) {
-   hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
-   if (hashsize < IPSET_MIMINAL_HASHSIZE)
-   hashsize = IPSET_MIMINAL_HASHSIZE;
+   markmask = 0x;
+   if (tb[IPSET_ATTR_MARKMASK]) {
+   markmask = ntohl(nla_get_be32(tb[IPSET_ATTR_MARKMASK]));
+   if (markmask == 0)
+   return -IPSET_ERR_INVALID_MARKMASK;
}
-
-   if (tb[IPSET_ATTR_MAXELEM])
-   maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
+#endif
 
 #ifdef IP_SET_HASH_WITH_NETMASK
+   netmask = set->family == NFPROTO_IPV4 ? 32 : 128;
if (tb[IPSET_ATTR_NETMASK]) {
netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
 
@@ -1287,14 +1281,15 @@ struct htype {
return -IPSET_ERR_INVALID_NETMASK;
}
 #endif
-#ifdef IP_SET_HASH_WITH_MARKMASK
-   if (tb[IPSET_ATTR_MARKMASK]) {
-   markmask = ntohl(nla_get_be32(tb[IPSET_ATTR_MARKMASK]));
 
-   if (markmask == 0)
-   return -IPSET_ERR_INVALID_MARKMASK;
+   if (tb[IPSET_ATTR_HASHSIZE]) {
+   hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
+   if (hashsize < IPSET_MIMINAL_HASHSIZE)
+   hashsize = IPSET_MIMINAL_HASHSIZE;
}
-#endif
+
+   if (tb[IPSET_ATTR_MAXELEM])
+   maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
 
hsize = sizeof(*h);
 #ifdef IP_SET_HASH_WITH_NETS
@@ -1304,16 +1299,6 @@ struct htype {
if (!h)
return -ENOMEM;
 
-   h->maxelem = maxelem;
-#ifdef IP_SET_HASH_WITH_NETMASK
-   h->netmask = netmask;
-#endif
-#ifdef IP_SET_HASH_WITH_MARKMASK
-   h->markmask = markmask;
-#endif
-   get_random_bytes(>initval, sizeof(h->initval));
-   set->timeout = IPSET_NO_TIMEOUT;
-
hbits = htable_bits(hashsize);
hsize = htable_size(hbits);
if (hsize == 0) {
@@ -1325,8 +1310,17 @@ struct htype {
kfree(h);
return -ENOMEM;
}
+   h->maxelem = maxelem;
+#ifdef IP_SET_HASH_WITH_NETMASK
+   h->netmask = netmask;
+#endif
+#ifdef IP_SET_HASH_WITH_MARKMASK
+   h->markmask = markmask;
+#endif
+   get_random_bytes(>initval, sizeof(h->initval));
+
t->htable_bits = hbits;
-   rcu_assign_pointer(h->table, t);
+   RCU_INIT_POINTER(h->table, t);
 
set->data = h;
 #ifndef IP_SET_PROTO_UNDEF
@@ -1344,6 +1338,7 @@ struct htype {
__alignof__(struct IPSET_TOKEN(HTYPE, 6_elem)));
}
 #endif
+   set->timeout = IPSET_NO_TIMEOUT;
if (tb[IPSET_ATTR_TIMEOUT]) {
set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
 #ifndef IP_SET_PROTO_UNDEF
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/22] netfilter: ipset: Separate memsize calculation code into dedicated function

2016-10-23 Thread Jozsef Kadlecsik
Hash types already has it's memsize calculation code in separate
functions. Do the same for *bitmap* and *list* sets.

Ported from a patch proposed by Sergey Popovich .

Suggested-by: Sergey Popovich 
Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_bitmap_gen.h | 13 -
 net/netfilter/ipset/ip_set_list_set.c   | 23 +--
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h 
b/net/netfilter/ipset/ip_set_bitmap_gen.h
index 2e8e7e5..c22cdde 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -22,6 +22,7 @@
 #define mtype_kadt IPSET_TOKEN(MTYPE, _kadt)
 #define mtype_uadt IPSET_TOKEN(MTYPE, _uadt)
 #define mtype_destroy  IPSET_TOKEN(MTYPE, _destroy)
+#define mtype_memsize  IPSET_TOKEN(MTYPE, _memsize)
 #define mtype_flushIPSET_TOKEN(MTYPE, _flush)
 #define mtype_head IPSET_TOKEN(MTYPE, _head)
 #define mtype_same_set IPSET_TOKEN(MTYPE, _same_set)
@@ -84,12 +85,22 @@
memset(map->members, 0, map->memsize);
 }
 
+/* Calculate the actual memory size of the set data */
+static size_t
+mtype_memsize(const struct mtype *map, size_t dsize)
+{
+   size_t memsize = sizeof(*map) +
+map->memsize +
+map->elements * dsize;
+   return memsize;
+}
+
 static int
 mtype_head(struct ip_set *set, struct sk_buff *skb)
 {
const struct mtype *map = set->data;
struct nlattr *nested;
-   size_t memsize = sizeof(*map) + map->memsize;
+   size_t memsize = mtype_memsize(map, set->dsize);
 
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
diff --git a/net/netfilter/ipset/ip_set_list_set.c 
b/net/netfilter/ipset/ip_set_list_set.c
index a2a89e4..462b0b1 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -441,12 +441,12 @@ struct list_set {
set->data = NULL;
 }
 
-static int
-list_set_head(struct ip_set *set, struct sk_buff *skb)
+/* Calculate the actual memory size of the set data */
+static size_t
+list_set_memsize(const struct list_set *map, size_t dsize)
 {
-   const struct list_set *map = set->data;
-   struct nlattr *nested;
struct set_elem *e;
+   size_t memsize;
u32 n = 0;
 
rcu_read_lock();
@@ -454,13 +454,24 @@ struct list_set {
n++;
rcu_read_unlock();
 
+   memsize = sizeof(*map) + n * dsize;
+
+   return memsize;
+}
+
+static int
+list_set_head(struct ip_set *set, struct sk_buff *skb)
+{
+   const struct list_set *map = set->data;
+   struct nlattr *nested;
+   size_t memsize = list_set_memsize(map, set->dsize);
+
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
goto nla_put_failure;
if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) ||
-   nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
- htonl(sizeof(*map) + n * set->dsize)))
+   nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
goto nla_put_failure;
if (unlikely(ip_set_put_flags(skb, set)))
goto nla_put_failure;
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 19/22] netfilter: ipset: use setup_timer() and mod_timer().

2016-10-23 Thread Jozsef Kadlecsik
From: Muhammad Falak R Wani 

Use setup_timer() and instead of init_timer(), being the preferred way
of setting up a timer.

Also, quoting the mod_timer() function comment:
-> mod_timer() is a more efficient way to update the expire field of an
   active timer (if the timer is inactive it will be activated).

Use setup_timer() and mod_timer() to setup and arm a timer, making the
code compact and easier to read.

Signed-off-by: Muhammad Falak R Wani 
Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_bitmap_gen.h | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h 
b/net/netfilter/ipset/ip_set_bitmap_gen.h
index 5a9fa61..77dd415 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -41,11 +41,8 @@
 {
struct mtype *map = set->data;
 
-   init_timer(>gc);
-   map->gc.data = (unsigned long)set;
-   map->gc.function = gc;
-   map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
-   add_timer(>gc);
+   setup_timer(>gc, gc, (unsigned long)set);
+   mod_timer(>gc, jiffies + IPSET_GC_PERIOD(set->timeout) * HZ);
 }
 
 static void
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/22] netfilter: ipset: Add element count to all set types header

2016-10-23 Thread Jozsef Kadlecsik
It is better to list the set elements for all set types, thus the
header information is uniform. Element counts are therefore added
to the bitmap and list types.

Signed-off-by: Jozsef Kadlecsik 
---
 include/linux/netfilter/ipset/ip_set.h|  2 ++
 include/linux/netfilter/ipset/ip_set_bitmap.h |  2 +-
 net/netfilter/ipset/ip_set_bitmap_gen.h   | 10 +-
 net/netfilter/ipset/ip_set_hash_gen.h | 21 ++---
 net/netfilter/ipset/ip_set_list_set.c |  6 +-
 5 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/include/linux/netfilter/ipset/ip_set.h 
b/include/linux/netfilter/ipset/ip_set.h
index 7a218eb..4671d74 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -250,6 +250,8 @@ struct ip_set {
u8 flags;
/* Default timeout value, if enabled */
u32 timeout;
+   /* Number of elements (vs timeout) */
+   u32 elements;
/* Element data size */
size_t dsize;
/* Offsets to extensions in elements */
diff --git a/include/linux/netfilter/ipset/ip_set_bitmap.h 
b/include/linux/netfilter/ipset/ip_set_bitmap.h
index 5e4662a..366d6c0 100644
--- a/include/linux/netfilter/ipset/ip_set_bitmap.h
+++ b/include/linux/netfilter/ipset/ip_set_bitmap.h
@@ -6,8 +6,8 @@
 #define IPSET_BITMAP_MAX_RANGE 0x
 
 enum {
+   IPSET_ADD_STORE_PLAIN_TIMEOUT = -1,
IPSET_ADD_FAILED = 1,
-   IPSET_ADD_STORE_PLAIN_TIMEOUT,
IPSET_ADD_START_STORED_TIMEOUT,
 };
 
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h 
b/net/netfilter/ipset/ip_set_bitmap_gen.h
index c22cdde..13a7021 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -83,6 +83,7 @@
if (set->extensions & IPSET_EXT_DESTROY)
mtype_ext_cleanup(set);
memset(map->members, 0, map->memsize);
+   set->elements = 0;
 }
 
 /* Calculate the actual memory size of the set data */
@@ -107,7 +108,8 @@
goto nla_put_failure;
if (mtype_do_head(skb, map) ||
nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) ||
-   nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
+   nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
+   nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(set->elements)))
goto nla_put_failure;
if (unlikely(ip_set_put_flags(skb, set)))
goto nla_put_failure;
@@ -151,6 +153,7 @@
if (ret == IPSET_ADD_FAILED) {
if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, set))) {
+   set->elements--;
ret = 0;
} else if (!(flags & IPSET_FLAG_EXIST)) {
set_bit(e->id, map->members);
@@ -159,6 +162,8 @@
/* Element is re-added, cleanup extensions */
ip_set_ext_destroy(set, x);
}
+   if (ret > 0)
+   set->elements--;
 
if (SET_WITH_TIMEOUT(set))
 #ifdef IP_SET_BITMAP_STORED_TIMEOUT
@@ -176,6 +181,7 @@
 
/* Activate element */
set_bit(e->id, map->members);
+   set->elements++;
 
return 0;
 }
@@ -192,6 +198,7 @@
return -IPSET_ERR_EXIST;
 
ip_set_ext_destroy(set, x);
+   set->elements--;
if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, set)))
return -IPSET_ERR_EXIST;
@@ -287,6 +294,7 @@
if (ip_set_timeout_expired(ext_timeout(x, set))) {
clear_bit(id, map->members);
ip_set_ext_destroy(set, x);
+   set->elements--;
}
}
spin_unlock_bh(>lock);
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index 66a55a5..09465d1 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -277,7 +277,6 @@ struct net_prefixes {
 struct htype {
struct htable __rcu *table; /* the hash table */
u32 maxelem;/* max elements in the hash */
-   u32 elements;   /* current element (vs timeout) */
u32 initval;/* random jhash init value */
 #ifdef IP_SET_HASH_WITH_MARKMASK
u32 markmask;   /* markmask value for mark mask to store */
@@ -402,7 +401,7 @@ struct htype {
 #ifdef IP_SET_HASH_WITH_NETS
memset(h->nets, 0, sizeof(struct net_prefixes) * NLEN(set->family));
 #endif
-   h->elements = 0;
+   set->elements = 0;
 }
 
 /* Destroy the hashtable part of the set */
@@ -508,7 +507,7 @@ struct htype {
nets_length, k);
 #endif
ip_set_ext_destroy(set, data);
-   h->elements--;
+  

[PATCH 07/22] netfilter: ipset: Regroup ip_set_put_extensions and add extern

2016-10-23 Thread Jozsef Kadlecsik
Signed-off-by: Jozsef Kadlecsik 
---
 include/linux/netfilter/ipset/ip_set.h | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter/ipset/ip_set.h 
b/include/linux/netfilter/ipset/ip_set.h
index b5bd0fb3..7a218eb 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -331,6 +331,8 @@ extern size_t ip_set_elem_len(struct ip_set *set, struct 
nlattr *tb[],
  size_t len, size_t align);
 extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
 struct ip_set_ext *ext);
+extern int ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
+const void *e, bool active);
 
 static inline int
 ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
@@ -449,10 +451,6 @@ static inline int nla_put_ipaddr6(struct sk_buff *skb, int 
type,
 #include 
 #include 
 
-int
-ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
- const void *e, bool active);
-
 #define IP_SET_INIT_KEXT(skb, opt, set)\
{ .bytes = (skb)->len, .packets = 1,\
  .timeout = ip_set_adt_opt_timeout(opt, set) }
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/22] netfilter: ipset: Count non-static extension memory for userspace

2016-10-23 Thread Jozsef Kadlecsik
Non-static (i.e. comment) extension was not counted into the memory
size. A new internal counter is introduced for this. In the case of
the hash types the sizes of the arrays are counted there as well so
that we can avoid to scan the whole set when just the header data
is requested.

Signed-off-by: Jozsef Kadlecsik 
---
 include/linux/netfilter/ipset/ip_set.h |  8 ++--
 include/linux/netfilter/ipset/ip_set_comment.h |  7 +--
 net/netfilter/ipset/ip_set_bitmap_gen.h|  5 +++--
 net/netfilter/ipset/ip_set_core.c  |  2 +-
 net/netfilter/ipset/ip_set_hash_gen.h  | 26 ++
 net/netfilter/ipset/ip_set_list_set.c  |  5 +++--
 6 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/include/linux/netfilter/ipset/ip_set.h 
b/include/linux/netfilter/ipset/ip_set.h
index 4671d74..8e42253 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -79,10 +79,12 @@ enum ip_set_ext_id {
IPSET_EXT_ID_MAX,
 };
 
+struct ip_set;
+
 /* Extension type */
 struct ip_set_ext_type {
/* Destroy extension private data (can be NULL) */
-   void (*destroy)(void *ext);
+   void (*destroy)(struct ip_set *set, void *ext);
enum ip_set_extension type;
enum ipset_cadt_flags flag;
/* Size and minimal alignment */
@@ -252,6 +254,8 @@ struct ip_set {
u32 timeout;
/* Number of elements (vs timeout) */
u32 elements;
+   /* Size of the dynamic extensions (vs timeout) */
+   size_t ext_size;
/* Element data size */
size_t dsize;
/* Offsets to extensions in elements */
@@ -268,7 +272,7 @@ struct ip_set {
 */
if (SET_WITH_COMMENT(set))
ip_set_extensions[IPSET_EXT_ID_COMMENT].destroy(
-   ext_comment(data, set));
+   set, ext_comment(data, set));
 }
 
 static inline int
diff --git a/include/linux/netfilter/ipset/ip_set_comment.h 
b/include/linux/netfilter/ipset/ip_set_comment.h
index 5444b1b..8e2bab1 100644
--- a/include/linux/netfilter/ipset/ip_set_comment.h
+++ b/include/linux/netfilter/ipset/ip_set_comment.h
@@ -20,13 +20,14 @@
  * The kadt functions don't use the comment extensions in any way.
  */
 static inline void
-ip_set_init_comment(struct ip_set_comment *comment,
+ip_set_init_comment(struct ip_set *set, struct ip_set_comment *comment,
const struct ip_set_ext *ext)
 {
struct ip_set_comment_rcu *c = rcu_dereference_protected(comment->c, 1);
size_t len = ext->comment ? strlen(ext->comment) : 0;
 
if (unlikely(c)) {
+   set->ext_size -= sizeof(*c) + strlen(c->str) + 1;
kfree_rcu(c, rcu);
rcu_assign_pointer(comment->c, NULL);
}
@@ -38,6 +39,7 @@
if (unlikely(!c))
return;
strlcpy(c->str, ext->comment, len + 1);
+   set->ext_size += sizeof(*c) + strlen(c->str) + 1;
rcu_assign_pointer(comment->c, c);
 }
 
@@ -58,13 +60,14 @@
  * of the set data anymore.
  */
 static inline void
-ip_set_comment_free(struct ip_set_comment *comment)
+ip_set_comment_free(struct ip_set *set, struct ip_set_comment *comment)
 {
struct ip_set_comment_rcu *c;
 
c = rcu_dereference_protected(comment->c, 1);
if (unlikely(!c))
return;
+   set->ext_size -= sizeof(*c) + strlen(c->str) + 1;
kfree_rcu(c, rcu);
rcu_assign_pointer(comment->c, NULL);
 }
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h 
b/net/netfilter/ipset/ip_set_bitmap_gen.h
index 13a7021..5a9fa61 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -84,6 +84,7 @@
mtype_ext_cleanup(set);
memset(map->members, 0, map->memsize);
set->elements = 0;
+   set->ext_size = 0;
 }
 
 /* Calculate the actual memory size of the set data */
@@ -101,7 +102,7 @@
 {
const struct mtype *map = set->data;
struct nlattr *nested;
-   size_t memsize = mtype_memsize(map, set->dsize);
+   size_t memsize = mtype_memsize(map, set->dsize) + set->ext_size;
 
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
@@ -175,7 +176,7 @@
if (SET_WITH_COUNTER(set))
ip_set_init_counter(ext_counter(x, set), ext);
if (SET_WITH_COMMENT(set))
-   ip_set_init_comment(ext_comment(x, set), ext);
+   ip_set_init_comment(set, ext_comment(x, set), ext);
if (SET_WITH_SKBINFO(set))
ip_set_init_skbinfo(ext_skbinfo(x, set), ext);
 
diff --git a/net/netfilter/ipset/ip_set_core.c 
b/net/netfilter/ipset/ip_set_core.c
index 3bca341..cd8961e 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -324,7 +324,7 @@ static inline struct ip_set_net *ip_set_pernet(struct net 
*net)
 }
 

[PATCH 22/22] netfilter: ipset: hash: fix boolreturn.cocci warnings

2016-10-23 Thread Jozsef Kadlecsik
From: kbuild test robot 

net/netfilter/ipset/ip_set_hash_ipmac.c:70:8-9: WARNING: return of 0/1 in 
function 'hash_ipmac4_data_list' with return type bool
net/netfilter/ipset/ip_set_hash_ipmac.c:178:8-9: WARNING: return of 0/1 in 
function 'hash_ipmac6_data_list' with return type bool

 Return statements in functions returning bool should use
 true/false instead of 1/0.
Generated by: scripts/coccinelle/misc/boolreturn.cocci

CC: Tomasz Chilinski 
Signed-off-by: Fengguang Wu 
Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_ipmac.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c 
b/net/netfilter/ipset/ip_set_hash_ipmac.c
index d9eb144..1ab5ed2 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
@@ -67,10 +67,10 @@ struct hash_ipmac4_elem {
if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, e->ip) ||
nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, e->ether))
goto nla_put_failure;
-   return 0;
+   return false;
 
 nla_put_failure:
-   return 1;
+   return true;
 }
 
 static inline void
@@ -175,10 +175,10 @@ struct hash_ipmac6_elem {
if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, >ip.in6) ||
nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, e->ether))
goto nla_put_failure;
-   return 0;
+   return false;
 
 nla_put_failure:
-   return 1;
+   return true;
 }
 
 static inline void
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/22] netfilter: ipset: Make NLEN compile time constant for hash types

2016-10-23 Thread Jozsef Kadlecsik
Hash types define HOST_MASK before inclusion of ip_set_hash_gen.h
and the only place where NLEN needed to be calculated at runtime
is *_create() method.

Ported from a patch proposed by Sergey Popovich .

Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 51 ---
 1 file changed, 23 insertions(+), 28 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index 79e158d..ab5b57c 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -152,20 +152,18 @@ struct net_prefixes {
 #define INIT_CIDR(cidr, host_mask) \
DCIDR_PUT(((cidr) ? NCIDR_GET(cidr) : host_mask))
 
-#define SET_HOST_MASK(family)  (family == AF_INET ? 32 : 128)
-
 #ifdef IP_SET_HASH_WITH_NET0
-/* cidr from 0 to SET_HOST_MASK() value and c = cidr + 1 */
-#define NLEN(family)   (SET_HOST_MASK(family) + 1)
+/* cidr from 0 to HOST_MASK value and c = cidr + 1 */
+#define NLEN   (HOST_MASK + 1)
 #define CIDR_POS(c)((c) - 1)
 #else
-/* cidr from 1 to SET_HOST_MASK() value and c = cidr + 1 */
-#define NLEN(family)   SET_HOST_MASK(family)
+/* cidr from 1 to HOST_MASK value and c = cidr + 1 */
+#define NLEN   HOST_MASK
 #define CIDR_POS(c)((c) - 2)
 #endif
 
 #else
-#define NLEN(family)   0
+#define NLEN   0
 #endif /* IP_SET_HASH_WITH_NETS */
 
 #endif /* _IP_SET_HASH_GEN_H */
@@ -300,12 +298,12 @@ struct htype {
  * sized networks. cidr == real cidr + 1 to support /0.
  */
 static void
-mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
+mtype_add_cidr(struct htype *h, u8 cidr, u8 n)
 {
int i, j;
 
/* Add in increasing prefix order, so larger cidr first */
-   for (i = 0, j = -1; i < nets_length && h->nets[i].cidr[n]; i++) {
+   for (i = 0, j = -1; i < NLEN && h->nets[i].cidr[n]; i++) {
if (j != -1) {
continue;
} else if (h->nets[i].cidr[n] < cidr) {
@@ -324,11 +322,11 @@ struct htype {
 }
 
 static void
-mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
+mtype_del_cidr(struct htype *h, u8 cidr, u8 n)
 {
-   u8 i, j, net_end = nets_length - 1;
+   u8 i, j, net_end = NLEN - 1;
 
-   for (i = 0; i < nets_length; i++) {
+   for (i = 0; i < NLEN; i++) {
if (h->nets[i].cidr[n] != cidr)
continue;
h->nets[CIDR_POS(cidr)].nets[n]--;
@@ -344,13 +342,12 @@ struct htype {
 
 /* Calculate the actual memory size of the set data */
 static size_t
-mtype_ahash_memsize(const struct htype *h, const struct htable *t,
-   u8 nets_length)
+mtype_ahash_memsize(const struct htype *h, const struct htable *t)
 {
size_t memsize = sizeof(*h) + sizeof(*t);
 
 #ifdef IP_SET_HASH_WITH_NETS
-   memsize += sizeof(struct net_prefixes) * nets_length;
+   memsize += sizeof(struct net_prefixes) * NLEN;
 #endif
 
return memsize;
@@ -391,7 +388,7 @@ struct htype {
kfree_rcu(n, rcu);
}
 #ifdef IP_SET_HASH_WITH_NETS
-   memset(h->nets, 0, sizeof(struct net_prefixes) * NLEN(set->family));
+   memset(h->nets, 0, sizeof(struct net_prefixes) * NLEN);
 #endif
set->elements = 0;
set->ext_size = 0;
@@ -475,7 +472,7 @@ struct htype {
u32 i, j, d;
size_t dsize = set->dsize;
 #ifdef IP_SET_HASH_WITH_NETS
-   u8 k, nets_length = NLEN(set->family);
+   u8 k;
 #endif
 
t = ipset_dereference_protected(h->table, set);
@@ -498,7 +495,7 @@ struct htype {
for (k = 0; k < IPSET_NET_COUNT; k++)
mtype_del_cidr(h,
NCIDR_PUT(DCIDR_GET(data->cidr, k)),
-   nets_length, k);
+   k);
 #endif
ip_set_ext_destroy(set, data);
set->elements--;
@@ -778,7 +775,7 @@ struct htype {
for (i = 0; i < IPSET_NET_COUNT; i++)
mtype_del_cidr(h,
NCIDR_PUT(DCIDR_GET(data->cidr, i)),
-   NLEN(set->family), i);
+   i);
 #endif
ip_set_ext_destroy(set, data);
set->elements--;
@@ -814,8 +811,7 @@ struct htype {
set->elements++;
 #ifdef IP_SET_HASH_WITH_NETS
for (i = 0; i < IPSET_NET_COUNT; i++)
-   mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)),
-  NLEN(set->family), i);
+   mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)), i);
 #endif
memcpy(data, d, sizeof(struct mtype_elem));
 overwrite_extensions:
@@ -888,7 +884,7 @@ struct htype {
 

[PATCH 13/22] netfilter: ipset: Make sure element data size is a multiple of u32

2016-10-23 Thread Jozsef Kadlecsik
Data for hashing required to be array of u32. Make sure that
element data always multiple of u32.

Ported from a patch proposed by Sergey Popovich .

Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index ab5b57c..e2f4925 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -262,8 +262,14 @@ struct net_prefixes {
 #endif
 
 #define HKEY(data, initval, htable_bits)   \
-(jhash2((u32 *)(data), HKEY_DATALEN / sizeof(u32), initval)\
-   & jhash_mask(htable_bits))
+({ \
+   const u32 *__k = (const u32 *)data; \
+   u32 __l = HKEY_DATALEN / sizeof(u32);   \
+   \
+   BUILD_BUG_ON(HKEY_DATALEN % sizeof(u32) != 0);  \
+   \
+   jhash2(__k, __l, initval) & jhash_mask(htable_bits);\
+})
 
 #ifndef htype
 #ifndef HTYPE
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/22] netfilter: ipset: Improve skbinfo get/init helpers

2016-10-23 Thread Jozsef Kadlecsik
Use struct ip_set_skbinfo in struct ip_set_ext instead of open
coded fields and assign structure members in get/init helpers
instead of copying members one by one.

Ported from a patch proposed by Sergey Popovich .

Suggested-by: Sergey Popovich 
Signed-off-by: Jozsef Kadlecsik 
---
 include/linux/netfilter/ipset/ip_set.h | 30 +++---
 net/netfilter/ipset/ip_set_core.c  | 12 ++--
 net/netfilter/xt_set.c | 12 +++-
 3 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/include/linux/netfilter/ipset/ip_set.h 
b/include/linux/netfilter/ipset/ip_set.h
index 1ea28e3..7802621 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -92,17 +92,6 @@ struct ip_set_ext_type {
 
 extern const struct ip_set_ext_type ip_set_extensions[];
 
-struct ip_set_ext {
-   u64 packets;
-   u64 bytes;
-   u32 timeout;
-   u32 skbmark;
-   u32 skbmarkmask;
-   u32 skbprio;
-   u16 skbqueue;
-   char *comment;
-};
-
 struct ip_set_counter {
atomic64_t bytes;
atomic64_t packets;
@@ -122,6 +111,15 @@ struct ip_set_skbinfo {
u32 skbmarkmask;
u32 skbprio;
u16 skbqueue;
+   u16 __pad;
+};
+
+struct ip_set_ext {
+   struct ip_set_skbinfo skbinfo;
+   u64 packets;
+   u64 bytes;
+   char *comment;
+   u32 timeout;
 };
 
 struct ip_set;
@@ -360,10 +358,7 @@ struct ip_set {
   const struct ip_set_ext *ext,
   struct ip_set_ext *mext, u32 flags)
 {
-   mext->skbmark = skbinfo->skbmark;
-   mext->skbmarkmask = skbinfo->skbmarkmask;
-   mext->skbprio = skbinfo->skbprio;
-   mext->skbqueue = skbinfo->skbqueue;
+   mext->skbinfo = *skbinfo;
 }
 
 static inline bool
@@ -387,10 +382,7 @@ struct ip_set {
 ip_set_init_skbinfo(struct ip_set_skbinfo *skbinfo,
const struct ip_set_ext *ext)
 {
-   skbinfo->skbmark = ext->skbmark;
-   skbinfo->skbmarkmask = ext->skbmarkmask;
-   skbinfo->skbprio = ext->skbprio;
-   skbinfo->skbqueue = ext->skbqueue;
+   *skbinfo = ext->skbinfo;
 }
 
 /* Netlink CB args */
diff --git a/net/netfilter/ipset/ip_set_core.c 
b/net/netfilter/ipset/ip_set_core.c
index a748b0c..3bca341 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -426,20 +426,20 @@ static inline struct ip_set_net *ip_set_pernet(struct net 
*net)
if (!SET_WITH_SKBINFO(set))
return -IPSET_ERR_SKBINFO;
fullmark = be64_to_cpu(nla_get_be64(tb[IPSET_ATTR_SKBMARK]));
-   ext->skbmark = fullmark >> 32;
-   ext->skbmarkmask = fullmark & 0x;
+   ext->skbinfo.skbmark = fullmark >> 32;
+   ext->skbinfo.skbmarkmask = fullmark & 0x;
}
if (tb[IPSET_ATTR_SKBPRIO]) {
if (!SET_WITH_SKBINFO(set))
return -IPSET_ERR_SKBINFO;
-   ext->skbprio = be32_to_cpu(nla_get_be32(
-   tb[IPSET_ATTR_SKBPRIO]));
+   ext->skbinfo.skbprio =
+   be32_to_cpu(nla_get_be32(tb[IPSET_ATTR_SKBPRIO]));
}
if (tb[IPSET_ATTR_SKBQUEUE]) {
if (!SET_WITH_SKBINFO(set))
return -IPSET_ERR_SKBINFO;
-   ext->skbqueue = be16_to_cpu(nla_get_be16(
-   tb[IPSET_ATTR_SKBQUEUE]));
+   ext->skbinfo.skbqueue =
+   be16_to_cpu(nla_get_be16(tb[IPSET_ATTR_SKBQUEUE]));
}
return 0;
 }
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c
index 5669e5b..e6a8232 100644
--- a/net/netfilter/xt_set.c
+++ b/net/netfilter/xt_set.c
@@ -423,6 +423,8 @@ struct ip_set_adt_opt n = { \
 
 /* Revision 3 target */
 
+#define MOPT(opt, member)  ((opt).ext.skbinfo.member)
+
 static unsigned int
 set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
 {
@@ -453,14 +455,14 @@ struct ip_set_adt_opt n = {   \
if (!ret)
return XT_CONTINUE;
if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBMARK)
-   skb->mark = (skb->mark & ~(map_opt.ext.skbmarkmask))
-   ^ (map_opt.ext.skbmark);
+   skb->mark = (skb->mark & ~MOPT(map_opt,skbmarkmask))
+   ^ MOPT(map_opt, skbmark);
if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBPRIO)
-   skb->priority = map_opt.ext.skbprio;
+   skb->priority = MOPT(map_opt, skbprio);
if ((map_opt.cmdflags & IPSET_FLAG_MAP_SKBQUEUE) &&
skb->dev &&
-   skb->dev->real_num_tx_queues > map_opt.ext.skbqueue)
-  

[PATCH 01/22] netfilter: ipset: Correct rcu_dereference_bh_nfnl() usage

2016-10-23 Thread Jozsef Kadlecsik
When rcu_dereference_bh_nfnl() macro would be defined on the target
system it will accept pointer and subsystem id.

Check if rcu_dereference_bh_nfnl() is defined and make it accepting two
arguments.

Ported from a patch proposed by Sergey Popovich .

Suggested-by: Sergey Popovich 
Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index d32fd6b..bc54be4 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -17,7 +17,9 @@
 #define ipset_dereference_protected(p, set) \
__ipset_dereference_protected(p, spin_is_locked(&(set)->lock))
 
-#define rcu_dereference_bh_nfnl(p) rcu_dereference_bh_check(p, 1)
+#ifndef rcu_dereference_bh_nfnl
+#define rcu_dereference_bh_nfnl(p, ss) rcu_dereference_bh_check(p, 1)
+#endif
 
 /* Hashing which uses arrays to resolve clashing. The hash table is resized
  * (doubled) when searching becomes too long.
@@ -580,7 +582,7 @@ struct htype {
return -ENOMEM;
 #endif
rcu_read_lock_bh();
-   orig = rcu_dereference_bh_nfnl(h->table);
+   orig = rcu_dereference_bh_nfnl(h->table, NFNL_SUBSYS_IPSET);
htable_bits = orig->htable_bits;
rcu_read_unlock_bh();
 
@@ -1061,7 +1063,7 @@ struct htype {
u8 htable_bits;
 
rcu_read_lock_bh();
-   t = rcu_dereference_bh_nfnl(h->table);
+   t = rcu_dereference_bh_nfnl(h->table, NFNL_SUBSYS_IPSET);
memsize = mtype_ahash_memsize(h, t, NLEN(set->family), set->dsize);
htable_bits = t->htable_bits;
rcu_read_unlock_bh();
@@ -1103,7 +1105,7 @@ struct htype {
 
if (start) {
rcu_read_lock_bh();
-   t = rcu_dereference_bh_nfnl(h->table);
+   t = rcu_dereference_bh_nfnl(h->table, NFNL_SUBSYS_IPSET);
atomic_inc(>uref);
cb->args[IPSET_CB_PRIVATE] = (unsigned long)t;
rcu_read_unlock_bh();
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/22] netfilter: ipset: Add element count to hash headers

2016-10-23 Thread Jozsef Kadlecsik
From: Eric B Munson 

It would be useful for userspace to query the size of an ipset hash,
however, this data is not exposed to userspace outside of counting the
number of member entries.  This patch uses the attribute
IPSET_ATTR_ELEMENTS to indicate the size in the the header that is
exported to userspace.  This field is then printed by the userspace
tool for hashes.

Signed-off-by: Eric B Munson 
Cc: Pablo Neira Ayuso 
Cc: Josh Hunt 
Cc: netfilter-devel@vger.kernel.org
Signed-off-by: Jozsef Kadlecsik 
---
 net/netfilter/ipset/ip_set_hash_gen.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/ipset/ip_set_hash_gen.h 
b/net/netfilter/ipset/ip_set_hash_gen.h
index bc54be4..66a55a5 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -1085,7 +1085,8 @@ struct htype {
goto nla_put_failure;
 #endif
if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) ||
-   nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
+   nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
+   nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(h->elements)))
goto nla_put_failure;
if (unlikely(ip_set_put_flags(skb, set)))
goto nla_put_failure;
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html