Blame view

net/netfilter/xt_connbytes.c 4.47 KB
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
1
2
  /* Kernel module to match connection tracking byte counter.
   * GPL (C) 2002 Martin Devera (devik@cdi.cz).
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
3
   */
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
4
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
5
  #include <linux/module.h>
1977f0327   Jiri Slaby   remove asm/bitops...
6
  #include <linux/bitops.h>
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
7
  #include <linux/skbuff.h>
6f6d6a1a6   Roman Zippel   rename div64_64 t...
8
  #include <linux/math64.h>
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
9
10
  #include <linux/netfilter/x_tables.h>
  #include <linux/netfilter/xt_connbytes.h>
587aa6416   Patrick McHardy   [NETFILTER]: Remo...
11
  #include <net/netfilter/nf_conntrack.h>
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
12
  #include <net/netfilter/nf_conntrack_acct.h>
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
13

9d810fd2d   Harald Welte   [NETFILTER]: Add ...
14
15
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
2ae15b64e   Jan Engelhardt   [NETFILTER]: Upda...
16
  MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching");
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
17
  MODULE_ALIAS("ipt_connbytes");
73aaf9355   Jan Engelhardt   [NETFILTER]: x_ta...
18
  MODULE_ALIAS("ip6t_connbytes");
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
19

1d93a9cba   Jan Engelhardt   [NETFILTER]: x_ta...
20
  static bool
62fc80510   Jan Engelhardt   netfilter: xtable...
21
  connbytes_mt(const struct sk_buff *skb, struct xt_action_param *par)
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
22
  {
f7108a20d   Jan Engelhardt   netfilter: xtable...
23
  	const struct xt_connbytes_info *sinfo = par->matchinfo;
a47362a22   Jan Engelhardt   [NETFILTER]: add ...
24
  	const struct nf_conn *ct;
587aa6416   Patrick McHardy   [NETFILTER]: Remo...
25
  	enum ip_conntrack_info ctinfo;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
26
  	u_int64_t what = 0;	/* initialize to make gcc happy */
fb74a8416   Patrick McHardy   [NETFILTER]: xt_c...
27
28
  	u_int64_t bytes = 0;
  	u_int64_t pkts = 0;
f7b13e433   Holger Eitzenberger   netfilter: introd...
29
  	const struct nf_conn_acct *acct;
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
30
  	const struct nf_conn_counter *counters;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
31

587aa6416   Patrick McHardy   [NETFILTER]: Remo...
32
33
  	ct = nf_ct_get(skb, &ctinfo);
  	if (!ct)
1d93a9cba   Jan Engelhardt   [NETFILTER]: x_ta...
34
  		return false;
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
35

f7b13e433   Holger Eitzenberger   netfilter: introd...
36
37
  	acct = nf_conn_acct_find(ct);
  	if (!acct)
584015727   Krzysztof Piotr Oledzki   netfilter: accoun...
38
  		return false;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
39

f7b13e433   Holger Eitzenberger   netfilter: introd...
40
  	counters = acct->counter;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
41
  	switch (sinfo->what) {
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
42
  	case XT_CONNBYTES_PKTS:
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
43
  		switch (sinfo->direction) {
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
44
  		case XT_CONNBYTES_DIR_ORIGINAL:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
45
  			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
46
  			break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
47
  		case XT_CONNBYTES_DIR_REPLY:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
48
  			what = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
49
  			break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
50
  		case XT_CONNBYTES_DIR_BOTH:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
51
52
  			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
  			what += atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
53
54
55
  			break;
  		}
  		break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
56
  	case XT_CONNBYTES_BYTES:
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
57
  		switch (sinfo->direction) {
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
58
  		case XT_CONNBYTES_DIR_ORIGINAL:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
59
  			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
60
  			break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
61
  		case XT_CONNBYTES_DIR_REPLY:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
62
  			what = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
63
  			break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
64
  		case XT_CONNBYTES_DIR_BOTH:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
65
66
  			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
  			what += atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
67
68
69
  			break;
  		}
  		break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
70
  	case XT_CONNBYTES_AVGPKT:
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
71
  		switch (sinfo->direction) {
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
72
  		case XT_CONNBYTES_DIR_ORIGINAL:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
73
74
  			bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);
  			pkts  = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
75
  			break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
76
  		case XT_CONNBYTES_DIR_REPLY:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
77
78
  			bytes = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
  			pkts  = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
79
  			break;
2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
80
  		case XT_CONNBYTES_DIR_BOTH:
b3e0bfa71   Eric Dumazet   netfilter: nf_con...
81
82
83
84
  			bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes) +
  				atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);
  			pkts  = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets) +
  				atomic64_read(&counters[IP_CT_DIR_REPLY].packets);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
85
86
  			break;
  		}
fb74a8416   Patrick McHardy   [NETFILTER]: xt_c...
87
  		if (pkts != 0)
6f6d6a1a6   Roman Zippel   rename div64_64 t...
88
  			what = div64_u64(bytes, pkts);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
89
90
  		break;
  	}
0354b48f6   Florian Westphal   netfilter: xt_con...
91
  	if (sinfo->count.to >= sinfo->count.from)
7c4e36bc1   Jan Engelhardt   [NETFILTER]: Remo...
92
  		return what <= sinfo->count.to && what >= sinfo->count.from;
0354b48f6   Florian Westphal   netfilter: xt_con...
93
94
  	else /* inverted */
  		return what < sinfo->count.to || what > sinfo->count.from;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
95
  }
b0f38452f   Jan Engelhardt   netfilter: xtable...
96
  static int connbytes_mt_check(const struct xt_mtchk_param *par)
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
97
  {
9b4fce7a3   Jan Engelhardt   netfilter: xtable...
98
  	const struct xt_connbytes_info *sinfo = par->matchinfo;
4a5a5c73b   Jan Engelhardt   netfilter: xtable...
99
  	int ret;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
100

2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
101
102
103
  	if (sinfo->what != XT_CONNBYTES_PKTS &&
  	    sinfo->what != XT_CONNBYTES_BYTES &&
  	    sinfo->what != XT_CONNBYTES_AVGPKT)
bd414ee60   Jan Engelhardt   netfilter: xtable...
104
  		return -EINVAL;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
105

2e4e6a17a   Harald Welte   [NETFILTER] x_tab...
106
107
108
  	if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
  	    sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
  	    sinfo->direction != XT_CONNBYTES_DIR_BOTH)
bd414ee60   Jan Engelhardt   netfilter: xtable...
109
  		return -EINVAL;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
110

ecb2421b5   Florian Westphal   netfilter: add an...
111
  	ret = nf_ct_netns_get(par->net, par->family);
f95c74e33   Jan Engelhardt   netfilter: xtable...
112
  	if (ret < 0)
b26066447   Florian Westphal   netfilter: x_tabl...
113
114
115
  		pr_info_ratelimited("cannot load conntrack support for proto=%u
  ",
  				    par->family);
a8756201b   Tim Gardner   netfilter: xt_con...
116
117
118
119
120
121
  
  	/*
  	 * This filter cannot function correctly unless connection tracking
  	 * accounting is enabled, so complain in the hope that someone notices.
  	 */
  	if (!nf_ct_acct_enabled(par->net)) {
b167a37c7   Joe Perches   netfilter: Conver...
122
123
  		pr_warn("Forcing CT accounting to be enabled
  ");
a8756201b   Tim Gardner   netfilter: xt_con...
124
125
  		nf_ct_set_acct(par->net, true);
  	}
f95c74e33   Jan Engelhardt   netfilter: xtable...
126
  	return ret;
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
127
  }
6be3d8598   Jan Engelhardt   netfilter: xtable...
128
  static void connbytes_mt_destroy(const struct xt_mtdtor_param *par)
11078c371   Yasuyuki Kozakai   [NETFILTER]: x_ta...
129
  {
ecb2421b5   Florian Westphal   netfilter: add an...
130
  	nf_ct_netns_put(par->net, par->family);
11078c371   Yasuyuki Kozakai   [NETFILTER]: x_ta...
131
  }
92f3b2b1b   Jan Engelhardt   netfilter: xtable...
132
133
134
135
136
137
138
139
140
  static struct xt_match connbytes_mt_reg __read_mostly = {
  	.name       = "connbytes",
  	.revision   = 0,
  	.family     = NFPROTO_UNSPEC,
  	.checkentry = connbytes_mt_check,
  	.match      = connbytes_mt,
  	.destroy    = connbytes_mt_destroy,
  	.matchsize  = sizeof(struct xt_connbytes_info),
  	.me         = THIS_MODULE,
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
141
  };
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
142
  static int __init connbytes_mt_init(void)
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
143
  {
92f3b2b1b   Jan Engelhardt   netfilter: xtable...
144
  	return xt_register_match(&connbytes_mt_reg);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
145
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
146
  static void __exit connbytes_mt_exit(void)
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
147
  {
92f3b2b1b   Jan Engelhardt   netfilter: xtable...
148
  	xt_unregister_match(&connbytes_mt_reg);
9d810fd2d   Harald Welte   [NETFILTER]: Add ...
149
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
150
151
  module_init(connbytes_mt_init);
  module_exit(connbytes_mt_exit);