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

Commit cc4fc022 authored by Jan Engelhardt's avatar Jan Engelhardt
Browse files

netfilter: xtables: connlimit revision 1



This adds destination address-based selection. The old "inverse"
member is overloaded (memory-wise) with a new "flags" variable,
similar to how J.Park did it with xt_string rev 1. Since revision 0
userspace only sets flag 0x1, no great changes are made to explicitly
test for different revisions.

Signed-off-by: default avatarJan Engelhardt <jengelh@medozas.de>
parent 93557f53
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -576,3 +576,10 @@ Why: The functions have been superceded by cancel_delayed_work_sync()
Who:	Tejun Heo <tj@kernel.org>
Who:	Tejun Heo <tj@kernel.org>


----------------------------
----------------------------

What:	xt_connlimit rev 0
When:	2012
Who:	Jan Engelhardt <jengelh@medozas.de>
Files:	net/netfilter/xt_connlimit.c

----------------------------
+12 −0
Original line number Original line Diff line number Diff line
@@ -3,6 +3,11 @@


struct xt_connlimit_data;
struct xt_connlimit_data;


enum {
	XT_CONNLIMIT_INVERT = 1 << 0,
	XT_CONNLIMIT_DADDR  = 1 << 1,
};

struct xt_connlimit_info {
struct xt_connlimit_info {
	union {
	union {
		union nf_inet_addr mask;
		union nf_inet_addr mask;
@@ -14,6 +19,13 @@ struct xt_connlimit_info {
#endif
#endif
	};
	};
	unsigned int limit, inverse;
	unsigned int limit, inverse;
	union {
		/* revision 0 */
		unsigned int inverse;

		/* revision 1 */
		__u32 flags;
	};


	/* Used internally by the kernel */
	/* Used internally by the kernel */
	struct xt_connlimit_data *data __attribute__((aligned(8)));
	struct xt_connlimit_data *data __attribute__((aligned(8)));
+30 −14
Original line number Original line Diff line number Diff line
@@ -193,10 +193,12 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)


	if (par->family == NFPROTO_IPV6) {
	if (par->family == NFPROTO_IPV6) {
		const struct ipv6hdr *iph = ipv6_hdr(skb);
		const struct ipv6hdr *iph = ipv6_hdr(skb);
		memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr));
		memcpy(&addr.ip6, (info->flags & XT_CONNLIMIT_DADDR) ?
		       &iph->daddr : &iph->saddr, sizeof(addr.ip6));
	} else {
	} else {
		const struct iphdr *iph = ip_hdr(skb);
		const struct iphdr *iph = ip_hdr(skb);
		addr.ip = iph->saddr;
		addr.ip = (info->flags & XT_CONNLIMIT_DADDR) ?
			  iph->daddr : iph->saddr;
	}
	}


	spin_lock_bh(&info->data->lock);
	spin_lock_bh(&info->data->lock);
@@ -208,7 +210,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
		/* kmalloc failed, drop it entirely */
		/* kmalloc failed, drop it entirely */
		goto hotdrop;
		goto hotdrop;


	return (connections > info->limit) ^ info->inverse;
	return (connections > info->limit) ^
	       !!(info->flags & XT_CONNLIMIT_INVERT);


 hotdrop:
 hotdrop:
	par->hotdrop = true;
	par->hotdrop = true;
@@ -266,7 +269,8 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
	kfree(info->data);
	kfree(info->data);
}
}


static struct xt_match connlimit_mt_reg __read_mostly = {
static struct xt_match connlimit_mt_reg[] __read_mostly = {
	{
		.name       = "connlimit",
		.name       = "connlimit",
		.revision   = 0,
		.revision   = 0,
		.family     = NFPROTO_UNSPEC,
		.family     = NFPROTO_UNSPEC,
@@ -275,16 +279,28 @@ static struct xt_match connlimit_mt_reg __read_mostly = {
		.matchsize  = sizeof(struct xt_connlimit_info),
		.matchsize  = sizeof(struct xt_connlimit_info),
		.destroy    = connlimit_mt_destroy,
		.destroy    = connlimit_mt_destroy,
		.me         = THIS_MODULE,
		.me         = THIS_MODULE,
	},
	{
		.name       = "connlimit",
		.revision   = 1,
		.family     = NFPROTO_UNSPEC,
		.checkentry = connlimit_mt_check,
		.match      = connlimit_mt,
		.matchsize  = sizeof(struct xt_connlimit_info),
		.destroy    = connlimit_mt_destroy,
		.me         = THIS_MODULE,
	},
};
};


static int __init connlimit_mt_init(void)
static int __init connlimit_mt_init(void)
{
{
	return xt_register_match(&connlimit_mt_reg);
	return xt_register_matches(connlimit_mt_reg,
	       ARRAY_SIZE(connlimit_mt_reg));
}
}


static void __exit connlimit_mt_exit(void)
static void __exit connlimit_mt_exit(void)
{
{
	xt_unregister_match(&connlimit_mt_reg);
	xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
}
}


module_init(connlimit_mt_init);
module_init(connlimit_mt_init);