History

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.

Patrick McHardy committed 15 years ago

Commit b0179001 parent 5df15192 files · +88 −2Browse files

Unified · Split

2 files
  1. include/linux/netfilter/xt_conntrack.h +15 −0
  2. net/netfilter/xt_conntrack.c +73 −2
include/linux/netfilter/xt_conntrack.h+15−0
@@ -58,4 +58,19 @@ struct xt_conntrack_mtinfo2 { · 57 unmodified lines
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*/
net/netfilter/xt_conntrack.c+73−2
@@ -112,6 +112,54 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info, · 111 unmodified lines
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 bool163static 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, · 52 unmodified lines
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) · 29 unmodified lines
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 = { · 31 unmodified lines
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)