Blame view

net/netfilter/xt_connlimit.c 3.73 KB
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
1
2
3
4
5
6
  /*
   * netfilter module to limit the number of parallel tcp
   * connections per IP address.
   *   (c) 2000 Gerd Knorr <kraxel@bytesex.org>
   *   Nov 2002: Martin Bene <martin.bene@icomedias.com>:
   *		only ignore TIME_WAIT or gone connections
ba5dc2756   Jan Engelhardt   [NETFILTER]: Copy...
7
   *   (C) CC Computer Consultants GmbH, 2007
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
8
9
10
11
12
13
   *
   * based on ...
   *
   * Kernel module to match connection tracking information.
   * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
   */
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
14
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
625c55611   Florian Westphal   netfilter: connli...
15

40d102cde   Jeremy Sowden   netfilter: update...
16
17
  #include <linux/ip.h>
  #include <linux/ipv6.h>
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
18
  #include <linux/module.h>
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
19
  #include <linux/skbuff.h>
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
20
21
  #include <linux/netfilter/x_tables.h>
  #include <linux/netfilter/xt_connlimit.h>
625c55611   Florian Westphal   netfilter: connli...
22

370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
23
24
25
  #include <net/netfilter/nf_conntrack.h>
  #include <net/netfilter/nf_conntrack_core.h>
  #include <net/netfilter/nf_conntrack_tuple.h>
5d0aa2ccd   Patrick McHardy   netfilter: nf_con...
26
  #include <net/netfilter/nf_conntrack_zones.h>
625c55611   Florian Westphal   netfilter: connli...
27
  #include <net/netfilter/nf_conntrack_count.h>
15cfd5289   Florian Westphal   netfilter: connli...
28

d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
29
  static bool
62fc80510   Jan Engelhardt   netfilter: xtable...
30
  connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
31
  {
613dbd957   Pablo Neira Ayuso   netfilter: x_tabl...
32
  	struct net *net = xt_net(par);
f7108a20d   Jan Engelhardt   netfilter: xtable...
33
  	const struct xt_connlimit_info *info = par->matchinfo;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
34
35
  	struct nf_conntrack_tuple tuple;
  	const struct nf_conntrack_tuple *tuple_ptr = &tuple;
308ac9143   Daniel Borkmann   netfilter: nf_con...
36
  	const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
37
38
  	enum ip_conntrack_info ctinfo;
  	const struct nf_conn *ct;
7d0848777   Florian Westphal   netfilter: connli...
39
  	unsigned int connections;
625c55611   Florian Westphal   netfilter: connli...
40
  	u32 key[5];
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
41
42
  
  	ct = nf_ct_get(skb, &ctinfo);
e59ea3df3   Florian Westphal   netfilter: xt_con...
43
  	if (ct != NULL) {
8183e3a88   Changli Gao   netfilter: xt_con...
44
  		tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
e59ea3df3   Florian Westphal   netfilter: xt_con...
45
46
  		zone = nf_ct_zone(ct);
  	} else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
613dbd957   Pablo Neira Ayuso   netfilter: x_tabl...
47
  				      xt_family(par), net, &tuple)) {
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
48
  		goto hotdrop;
e59ea3df3   Florian Westphal   netfilter: xt_con...
49
  	}
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
50

613dbd957   Pablo Neira Ayuso   netfilter: x_tabl...
51
  	if (xt_family(par) == NFPROTO_IPV6) {
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
52
  		const struct ipv6hdr *iph = ipv6_hdr(skb);
625c55611   Florian Westphal   netfilter: connli...
53
  		union nf_inet_addr addr;
b1fc1372c   Florian Westphal   netfilter: xt_con...
54
  		unsigned int i;
cc4fc0225   Jan Engelhardt   netfilter: xtable...
55
56
  		memcpy(&addr.ip6, (info->flags & XT_CONNLIMIT_DADDR) ?
  		       &iph->daddr : &iph->saddr, sizeof(addr.ip6));
b1fc1372c   Florian Westphal   netfilter: xt_con...
57
58
59
  
  		for (i = 0; i < ARRAY_SIZE(addr.ip6); ++i)
  			addr.ip6[i] &= info->mask.ip6[i];
625c55611   Florian Westphal   netfilter: connli...
60
61
  		memcpy(key, &addr, sizeof(addr.ip6));
  		key[4] = zone->id;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
62
63
  	} else {
  		const struct iphdr *iph = ip_hdr(skb);
625c55611   Florian Westphal   netfilter: connli...
64
  		key[0] = (info->flags & XT_CONNLIMIT_DADDR) ?
cc4fc0225   Jan Engelhardt   netfilter: xtable...
65
  			  iph->daddr : iph->saddr;
b1fc1372c   Florian Westphal   netfilter: xt_con...
66

625c55611   Florian Westphal   netfilter: connli...
67
68
  		key[0] &= info->mask.ip;
  		key[1] = zone->id;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
69
  	}
6aec20878   Yi-Hung Wei   netfilter: Refact...
70
71
  	connections = nf_conncount_count(net, info->data, key, tuple_ptr,
  					 zone);
7d0848777   Florian Westphal   netfilter: connli...
72
  	if (connections == 0)
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
73
  		/* kmalloc failed, drop it entirely */
1cc34c30b   Richard Weinberger   netfilter: xt_con...
74
  		goto hotdrop;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
75

625c55611   Florian Westphal   netfilter: connli...
76
  	return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
77
78
  
   hotdrop:
b4ba26119   Jan Engelhardt   netfilter: xtable...
79
  	par->hotdrop = true;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
80
81
  	return false;
  }
b0f38452f   Jan Engelhardt   netfilter: xtable...
82
  static int connlimit_mt_check(const struct xt_mtchk_param *par)
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
83
  {
9b4fce7a3   Jan Engelhardt   netfilter: xtable...
84
  	struct xt_connlimit_info *info = par->matchinfo;
625c55611   Florian Westphal   netfilter: connli...
85
  	unsigned int keylen;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
86

625c55611   Florian Westphal   netfilter: connli...
87
88
89
90
91
  	keylen = sizeof(u32);
  	if (par->family == NFPROTO_IPV6)
  		keylen += sizeof(struct in6_addr);
  	else
  		keylen += sizeof(struct in_addr);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
92
93
  
  	/* init private data */
625c55611   Florian Westphal   netfilter: connli...
94
  	info->data = nf_conncount_init(par->net, par->family, keylen);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
95

33b78aaa4   YueHaibing   netfilter: use PT...
96
  	return PTR_ERR_OR_ZERO(info->data);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
97
  }
7d0848777   Florian Westphal   netfilter: connli...
98
99
100
  static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
  {
  	const struct xt_connlimit_info *info = par->matchinfo;
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
101

625c55611   Florian Westphal   netfilter: connli...
102
  	nf_conncount_destroy(par->net, par->family, info->data);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
103
  }
68c07cb6d   Cong Wang   netfilter: xt_con...
104
105
106
107
108
109
110
  static struct xt_match connlimit_mt_reg __read_mostly = {
  	.name       = "connlimit",
  	.revision   = 1,
  	.family     = NFPROTO_UNSPEC,
  	.checkentry = connlimit_mt_check,
  	.match      = connlimit_mt,
  	.matchsize  = sizeof(struct xt_connlimit_info),
ec2318904   Willem de Bruijn   xtables: extend m...
111
  	.usersize   = offsetof(struct xt_connlimit_info, data),
68c07cb6d   Cong Wang   netfilter: xt_con...
112
113
  	.destroy    = connlimit_mt_destroy,
  	.me         = THIS_MODULE,
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
114
  };
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
115
  static int __init connlimit_mt_init(void)
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
116
  {
625c55611   Florian Westphal   netfilter: connli...
117
  	return xt_register_match(&connlimit_mt_reg);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
118
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
119
  static void __exit connlimit_mt_exit(void)
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
120
  {
68c07cb6d   Cong Wang   netfilter: xt_con...
121
  	xt_unregister_match(&connlimit_mt_reg);
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
122
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
123
124
  module_init(connlimit_mt_init);
  module_exit(connlimit_mt_exit);
92f3b2b1b   Jan Engelhardt   netfilter: xtable...
125
  MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
2ae15b64e   Jan Engelhardt   [NETFILTER]: Upda...
126
  MODULE_DESCRIPTION("Xtables: Number of connections matching");
370786f9c   Jan Engelhardt   [NETFILTER]: x_ta...
127
128
129
  MODULE_LICENSE("GPL");
  MODULE_ALIAS("ipt_connlimit");
  MODULE_ALIAS("ip6t_connlimit");