aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-12-15 03:46:26 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2011-01-13 06:05:12 -0500
commitb017900aac4a158b9bf7ffdcb8a369a91115b3e4 (patch)
tree8516ac2dae8db038e7e45d76a1c8ecfb75faf7a9
parent5df15196a2bbf16ca4c6a797ec00ff36d0d5c179 (diff)
netfilter: xt_conntrack: support matching on port ranges
Add a new revision 3 that contains port ranges for all of origsrc, origdst, replsrc and repldst. The high ports are appended to the original v2 data structure to allow sharing most of the code with v1 and v2. Use of the revision specific port matching function is made dependant on par->match->revision. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/linux/netfilter/xt_conntrack.h15
-rw-r--r--net/netfilter/xt_conntrack.c75
2 files changed, 88 insertions, 2 deletions
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index 54f47a2f6152..74b904d8f99c 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -58,4 +58,19 @@ struct xt_conntrack_mtinfo2 {
58 __u16 state_mask, status_mask; 58 __u16 state_mask, status_mask;
59}; 59};
60 60
61struct xt_conntrack_mtinfo3 {
62 union nf_inet_addr origsrc_addr, origsrc_mask;
63 union nf_inet_addr origdst_addr, origdst_mask;
64 union nf_inet_addr replsrc_addr, replsrc_mask;
65 union nf_inet_addr repldst_addr, repldst_mask;
66 __u32 expires_min, expires_max;
67 __u16 l4proto;
68 __u16 origsrc_port, origdst_port;
69 __u16 replsrc_port, repldst_port;
70 __u16 match_flags, invert_flags;
71 __u16 state_mask, status_mask;
72 __u16 origsrc_port_high, origdst_port_high;
73 __u16 replsrc_port_high, repldst_port_high;
74};
75
61#endif /*_XT_CONNTRACK_H*/ 76#endif /*_XT_CONNTRACK_H*/
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index e536710ad916..4ef1b63ad73f 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -112,6 +112,54 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
112 return true; 112 return true;
113} 113}
114 114
115static inline bool
116port_match(u16 min, u16 max, u16 port, bool invert)
117{
118 return (port >= min && port <= max) ^ invert;
119}
120
121static inline bool
122ct_proto_port_check_v3(const struct xt_conntrack_mtinfo3 *info,
123 const struct nf_conn *ct)
124{
125 const struct nf_conntrack_tuple *tuple;
126
127 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
128 if ((info->match_flags & XT_CONNTRACK_PROTO) &&
129 (nf_ct_protonum(ct) == info->l4proto) ^
130 !(info->invert_flags & XT_CONNTRACK_PROTO))
131 return false;
132
133 /* Shortcut to match all recognized protocols by using ->src.all. */
134 if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
135 !port_match(info->origsrc_port, info->origsrc_port_high,
136 ntohs(tuple->src.u.all),
137 info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
138 return false;
139
140 if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
141 !port_match(info->origdst_port, info->origdst_port_high,
142 ntohs(tuple->dst.u.all),
143 info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
144 return false;
145
146 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
147
148 if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
149 !port_match(info->replsrc_port, info->replsrc_port_high,
150 ntohs(tuple->src.u.all),
151 info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
152 return false;
153
154 if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
155 !port_match(info->repldst_port, info->repldst_port_high,
156 ntohs(tuple->dst.u.all),
157 info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
158 return false;
159
160 return true;
161}
162
115static bool 163static bool
116conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, 164conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
117 u16 state_mask, u16 status_mask) 165 u16 state_mask, u16 status_mask)
@@ -170,8 +218,13 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
170 !(info->invert_flags & XT_CONNTRACK_REPLDST)) 218 !(info->invert_flags & XT_CONNTRACK_REPLDST))
171 return false; 219 return false;
172 220
173 if (!ct_proto_port_check(info, ct)) 221 if (par->match->revision != 3) {
174 return false; 222 if (!ct_proto_port_check(info, ct))
223 return false;
224 } else {
225 if (!ct_proto_port_check_v3(par->matchinfo, ct))
226 return false;
227 }
175 228
176 if ((info->match_flags & XT_CONNTRACK_STATUS) && 229 if ((info->match_flags & XT_CONNTRACK_STATUS) &&
177 (!!(status_mask & ct->status) ^ 230 (!!(status_mask & ct->status) ^
@@ -207,6 +260,14 @@ conntrack_mt_v2(const struct sk_buff *skb, struct xt_action_param *par)
207 return conntrack_mt(skb, par, info->state_mask, info->status_mask); 260 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
208} 261}
209 262
263static bool
264conntrack_mt_v3(const struct sk_buff *skb, struct xt_action_param *par)
265{
266 const struct xt_conntrack_mtinfo3 *info = par->matchinfo;
267
268 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
269}
270
210static int conntrack_mt_check(const struct xt_mtchk_param *par) 271static int conntrack_mt_check(const struct xt_mtchk_param *par)
211{ 272{
212 int ret; 273 int ret;
@@ -244,6 +305,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
244 .destroy = conntrack_mt_destroy, 305 .destroy = conntrack_mt_destroy,
245 .me = THIS_MODULE, 306 .me = THIS_MODULE,
246 }, 307 },
308 {
309 .name = "conntrack",
310 .revision = 3,
311 .family = NFPROTO_UNSPEC,
312 .matchsize = sizeof(struct xt_conntrack_mtinfo3),
313 .match = conntrack_mt_v3,
314 .checkentry = conntrack_mt_check,
315 .destroy = conntrack_mt_destroy,
316 .me = THIS_MODULE,
317 },
247}; 318};
248 319
249static int __init conntrack_mt_init(void) 320static int __init conntrack_mt_init(void)