Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b5b8c29 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf into netfilter



Pablo Neira Ayuso says:

====================
The following patchset contains late netfilter fixes for your net
tree, they are:

* Don't drop segmented TCP packets in the SIP helper, we've got reports
  from users that this was breaking communications when the SIP phone
  messages are larger than the MTU, from Patrick McHardy.

* Fix refcount leak in the ipset list set, from Jozsef Kadlecsik.

* On hash set resizing, the nomatch flag was lost, thus entirely inverting
  the logic of the set matching, from Jozsef Kadlecsik.

* Fix crash on NAT modules removal. Timer expiration may race with the
  module cleanup exit path while deleting conntracks, from Florian
  Westphal.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 50bceae9 c2d421e1
Loading
Loading
Loading
Loading
+23 −7
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ ip_set_hash_destroy(struct ip_set *set)
#define type_pf_data_tlist	TOKEN(TYPE, PF, _data_tlist)
#define type_pf_data_next	TOKEN(TYPE, PF, _data_next)
#define type_pf_data_flags	TOKEN(TYPE, PF, _data_flags)
#define type_pf_data_reset_flags TOKEN(TYPE, PF, _data_reset_flags)
#ifdef IP_SET_HASH_WITH_NETS
#define type_pf_data_match	TOKEN(TYPE, PF, _data_match)
#else
@@ -385,9 +386,9 @@ type_pf_resize(struct ip_set *set, bool retried)
	struct ip_set_hash *h = set->data;
	struct htable *t, *orig = h->table;
	u8 htable_bits = orig->htable_bits;
	const struct type_pf_elem *data;
	struct type_pf_elem *data;
	struct hbucket *n, *m;
	u32 i, j;
	u32 i, j, flags = 0;
	int ret;

retry:
@@ -412,9 +413,16 @@ retry:
		n = hbucket(orig, i);
		for (j = 0; j < n->pos; j++) {
			data = ahash_data(n, j);
#ifdef IP_SET_HASH_WITH_NETS
			flags = 0;
			type_pf_data_reset_flags(data, &flags);
#endif
			m = hbucket(t, HKEY(data, h->initval, htable_bits));
			ret = type_pf_elem_add(m, data, AHASH_MAX(h), 0);
			ret = type_pf_elem_add(m, data, AHASH_MAX(h), flags);
			if (ret < 0) {
#ifdef IP_SET_HASH_WITH_NETS
				type_pf_data_flags(data, flags);
#endif
				read_unlock_bh(&set->lock);
				ahash_destroy(t);
				if (ret == -EAGAIN)
@@ -836,9 +844,9 @@ type_pf_tresize(struct ip_set *set, bool retried)
	struct ip_set_hash *h = set->data;
	struct htable *t, *orig = h->table;
	u8 htable_bits = orig->htable_bits;
	const struct type_pf_elem *data;
	struct type_pf_elem *data;
	struct hbucket *n, *m;
	u32 i, j;
	u32 i, j, flags = 0;
	int ret;

	/* Try to cleanup once */
@@ -873,10 +881,17 @@ retry:
		n = hbucket(orig, i);
		for (j = 0; j < n->pos; j++) {
			data = ahash_tdata(n, j);
#ifdef IP_SET_HASH_WITH_NETS
			flags = 0;
			type_pf_data_reset_flags(data, &flags);
#endif
			m = hbucket(t, HKEY(data, h->initval, htable_bits));
			ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0,
			ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), flags,
				ip_set_timeout_get(type_pf_data_timeout(data)));
			if (ret < 0) {
#ifdef IP_SET_HASH_WITH_NETS
				type_pf_data_flags(data, flags);
#endif
				read_unlock_bh(&set->lock);
				ahash_destroy(t);
				if (ret == -EAGAIN)
@@ -1187,6 +1202,7 @@ type_pf_gc_init(struct ip_set *set)
#undef type_pf_data_tlist
#undef type_pf_data_next
#undef type_pf_data_flags
#undef type_pf_data_reset_flags
#undef type_pf_data_match

#undef type_pf_elem
+18 −0
Original line number Diff line number Diff line
@@ -104,6 +104,15 @@ hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags)
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem)
{
@@ -414,6 +423,15 @@ hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags)
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem)
{
+20 −2
Original line number Diff line number Diff line
@@ -87,7 +87,16 @@ hash_net4_data_copy(struct hash_net4_elem *dst,
static inline void
hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags)
{
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_net4_data_reset_flags(struct hash_net4_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
@@ -308,7 +317,16 @@ hash_net6_data_copy(struct hash_net6_elem *dst,
static inline void
hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags)
{
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_net6_data_reset_flags(struct hash_net6_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
+20 −2
Original line number Diff line number Diff line
@@ -198,7 +198,16 @@ hash_netiface4_data_copy(struct hash_netiface4_elem *dst,
static inline void
hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags)
{
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_netiface4_data_reset_flags(struct hash_netiface4_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
@@ -494,7 +503,7 @@ hash_netiface6_data_copy(struct hash_netiface6_elem *dst,
static inline void
hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags)
{
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline int
@@ -503,6 +512,15 @@ hash_netiface6_data_match(const struct hash_netiface6_elem *elem)
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
hash_netiface6_data_reset_flags(struct hash_netiface6_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline void
hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem)
{
+18 −0
Original line number Diff line number Diff line
@@ -104,6 +104,15 @@ hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags)
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
hash_netport4_data_match(const struct hash_netport4_elem *elem)
{
@@ -375,6 +384,15 @@ hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags)
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline void
hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags)
{
	if (dst->nomatch) {
		*flags = IPSET_FLAG_NOMATCH;
		dst->nomatch = 0;
	}
}

static inline int
hash_netport6_data_match(const struct hash_netport6_elem *elem)
{
Loading