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
5858 __u16 state_mask, status_mask;
5959 };
6060
61+struct 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+
6176 #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
112112 return true;
113113 }
114114
115+static inline bool
116+port_match(u16 min, u16 max, u16 port, bool invert)
117+{
118+ return (port >= min && port <= max) ^ invert;
119+}
120+
121+static inline bool
122+ct_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+
115163 static bool
116164 conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
117165 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
170218 !(info->invert_flags & XT_CONNTRACK_REPLDST))
171219 return false;
172220
173− if (!ct_proto_port_check(info, ct))
174− return false;
221+ if (par->match->revision != 3) {
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+ }
175228
176229 if ((info->match_flags & XT_CONNTRACK_STATUS) &&
177230 (!!(status_mask & ct->status) ^
@@ -207,6 +260,14 @@ conntrack_mt_v2(const struct sk_buff *skb, struct xt_action_param *par) · 29 unmodified lines
207260 return conntrack_mt(skb, par, info->state_mask, info->status_mask);
208261 }
209262
263+static bool
264+conntrack_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+
210271 static int conntrack_mt_check(const struct xt_mtchk_param *par)
211272 {
212273 int ret;
@@ -244,6 +305,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { · 31 unmodified lines
244305 .destroy = conntrack_mt_destroy,
245306 .me = THIS_MODULE,
246307 },
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+ },
247318 };
248319
249320 static int __init conntrack_mt_init(void)