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

Commit 3e0304a5 authored by Jozsef Kadlecsik's avatar Jozsef Kadlecsik
Browse files

netfilter: ipset: Support to match elements marked with "nomatch"



Exceptions can now be matched and we can branch according to the
possible cases:

a. match in the set if the element is not flagged as "nomatch"
b. match in the set if the element is flagged with "nomatch"
c. no match

i.e.

iptables ... -m set --match-set ... -j ...
iptables ... -m set --match-set ... --nomatch-entries -j ...
...

Signed-off-by: default avatarJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
parent 3ace95c0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ enum ip_set_dim {
	 * If changed, new revision of iptables match/target is required.
	 */
	IPSET_DIM_MAX = 6,
	IPSET_BIT_RETURN_NOMATCH = 7,
};

/* Option flags for kernel operations */
@@ -198,6 +199,7 @@ enum ip_set_kopt {
	IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
	IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
	IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
	IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
};

#ifdef __KERNEL__
@@ -229,6 +231,8 @@ enum ip_set_feature {
	IPSET_TYPE_NAME = (1 << IPSET_TYPE_NAME_FLAG),
	IPSET_TYPE_IFACE_FLAG = 5,
	IPSET_TYPE_IFACE = (1 << IPSET_TYPE_IFACE_FLAG),
	IPSET_TYPE_NOMATCH_FLAG = 6,
	IPSET_TYPE_NOMATCH = (1 << IPSET_TYPE_NOMATCH_FLAG),
	/* Strictly speaking not a feature, but a flag for dumping:
	 * this settype must be dumped last */
	IPSET_DUMP_LAST_FLAG = 7,
+6 −0
Original line number Diff line number Diff line
@@ -370,6 +370,12 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
		set->variant->kadt(set, skb, par, IPSET_ADD, opt);
		write_unlock_bh(&set->lock);
		ret = 1;
	} else {
		/* --return-nomatch: invert matched element */
		if ((opt->flags & IPSET_RETURN_NOMATCH) &&
		    (set->type->features & IPSET_TYPE_NOMATCH) &&
		    (ret > 0 || ret == -ENOTEMPTY))
			ret = -ret;
	}

	/* Convert error codes to nomatch */
+6 −5
Original line number Diff line number Diff line
@@ -104,10 +104,10 @@ hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags)
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline bool
static inline int
hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem)
{
	return !elem->nomatch;
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
@@ -411,10 +411,10 @@ hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags)
	dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
}

static inline bool
static inline int
hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem)
{
	return !elem->nomatch;
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
@@ -697,7 +697,8 @@ hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
static struct ip_set_type hash_ipportnet_type __read_mostly = {
	.name		= "hash:ip,port,net",
	.protocol	= IPSET_PROTOCOL,
	.features	= IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
	.features	= IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2 |
			  IPSET_TYPE_NOMATCH,
	.dimension	= IPSET_DIM_THREE,
	.family		= NFPROTO_UNSPEC,
	.revision_min	= REVISION_MIN,
+5 −5
Original line number Diff line number Diff line
@@ -90,10 +90,10 @@ hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags)
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
}

static inline bool
static inline int
hash_net4_data_match(const struct hash_net4_elem *elem)
{
	return !elem->nomatch;
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
@@ -311,10 +311,10 @@ hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags)
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
}

static inline bool
static inline int
hash_net6_data_match(const struct hash_net6_elem *elem)
{
	return !elem->nomatch;
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
@@ -536,7 +536,7 @@ hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
static struct ip_set_type hash_net_type __read_mostly = {
	.name		= "hash:net",
	.protocol	= IPSET_PROTOCOL,
	.features	= IPSET_TYPE_IP,
	.features	= IPSET_TYPE_IP | IPSET_TYPE_NOMATCH,
	.dimension	= IPSET_DIM_ONE,
	.family		= NFPROTO_UNSPEC,
	.revision_min	= REVISION_MIN,
+6 −5
Original line number Diff line number Diff line
@@ -201,10 +201,10 @@ hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags)
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
}

static inline bool
static inline int
hash_netiface4_data_match(const struct hash_netiface4_elem *elem)
{
	return !elem->nomatch;
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
@@ -497,10 +497,10 @@ hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags)
	dst->nomatch = flags & IPSET_FLAG_NOMATCH;
}

static inline bool
static inline int
hash_netiface6_data_match(const struct hash_netiface6_elem *elem)
{
	return !elem->nomatch;
	return elem->nomatch ? -ENOTEMPTY : 1;
}

static inline void
@@ -774,7 +774,8 @@ hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
static struct ip_set_type hash_netiface_type __read_mostly = {
	.name		= "hash:net,iface",
	.protocol	= IPSET_PROTOCOL,
	.features	= IPSET_TYPE_IP | IPSET_TYPE_IFACE,
	.features	= IPSET_TYPE_IP | IPSET_TYPE_IFACE |
			  IPSET_TYPE_NOMATCH,
	.dimension	= IPSET_DIM_TWO,
	.family		= NFPROTO_UNSPEC,
	.revision_min	= REVISION_MIN,
Loading