diff options
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 3 | ||||
-rw-r--r-- | include/linux/netfilter/xt_conntrack.h | 36 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 155 |
3 files changed, 1 insertions, 193 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 54f935794922..6746473ef033 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -238,9 +238,6 @@ What (Why): | |||
238 | - "forwarding" header files like ipt_mac.h in | 238 | - "forwarding" header files like ipt_mac.h in |
239 | include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/ | 239 | include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/ |
240 | 240 | ||
241 | - xt_conntrack match revision 0 | ||
242 | (superseded by xt_conntrack match revision 1) | ||
243 | |||
244 | - xt_iprange match revision 0, | 241 | - xt_iprange match revision 0, |
245 | include/linux/netfilter_ipv4/ipt_iprange.h | 242 | include/linux/netfilter_ipv4/ipt_iprange.h |
246 | (superseded by xt_iprange match revision 1) | 243 | (superseded by xt_iprange match revision 1) |
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h index 7ae05338e94c..54f47a2f6152 100644 --- a/include/linux/netfilter/xt_conntrack.h +++ b/include/linux/netfilter/xt_conntrack.h | |||
@@ -32,42 +32,6 @@ enum { | |||
32 | XT_CONNTRACK_DIRECTION = 1 << 12, | 32 | XT_CONNTRACK_DIRECTION = 1 << 12, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | /* This is exposed to userspace, so remains frozen in time. */ | ||
36 | struct ip_conntrack_old_tuple | ||
37 | { | ||
38 | struct { | ||
39 | __be32 ip; | ||
40 | union { | ||
41 | __u16 all; | ||
42 | } u; | ||
43 | } src; | ||
44 | |||
45 | struct { | ||
46 | __be32 ip; | ||
47 | union { | ||
48 | __u16 all; | ||
49 | } u; | ||
50 | |||
51 | /* The protocol. */ | ||
52 | __u16 protonum; | ||
53 | } dst; | ||
54 | }; | ||
55 | |||
56 | struct xt_conntrack_info | ||
57 | { | ||
58 | unsigned int statemask, statusmask; | ||
59 | |||
60 | struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; | ||
61 | struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; | ||
62 | |||
63 | unsigned long expires_min, expires_max; | ||
64 | |||
65 | /* Flags word */ | ||
66 | __u8 flags; | ||
67 | /* Inverse flags */ | ||
68 | __u8 invflags; | ||
69 | }; | ||
70 | |||
71 | struct xt_conntrack_mtinfo1 { | 35 | struct xt_conntrack_mtinfo1 { |
72 | union nf_inet_addr origsrc_addr, origsrc_mask; | 36 | union nf_inet_addr origsrc_addr, origsrc_mask; |
73 | union nf_inet_addr origdst_addr, origdst_mask; | 37 | union nf_inet_addr origdst_addr, origdst_mask; |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index fc581800698e..6dc4652f2fe8 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -19,101 +19,12 @@ | |||
19 | 19 | ||
20 | MODULE_LICENSE("GPL"); | 20 | MODULE_LICENSE("GPL"); |
21 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); | 21 | MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); |
22 | MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); | 22 | MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>"); |
23 | MODULE_DESCRIPTION("Xtables: connection tracking state match"); | 23 | MODULE_DESCRIPTION("Xtables: connection tracking state match"); |
24 | MODULE_ALIAS("ipt_conntrack"); | 24 | MODULE_ALIAS("ipt_conntrack"); |
25 | MODULE_ALIAS("ip6t_conntrack"); | 25 | MODULE_ALIAS("ip6t_conntrack"); |
26 | 26 | ||
27 | static bool | 27 | static bool |
28 | conntrack_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) | ||
29 | { | ||
30 | const struct xt_conntrack_info *sinfo = par->matchinfo; | ||
31 | const struct nf_conn *ct; | ||
32 | enum ip_conntrack_info ctinfo; | ||
33 | unsigned int statebit; | ||
34 | |||
35 | ct = nf_ct_get(skb, &ctinfo); | ||
36 | |||
37 | #define FWINV(bool, invflg) ((bool) ^ !!(sinfo->invflags & (invflg))) | ||
38 | |||
39 | if (ct == &nf_conntrack_untracked) | ||
40 | statebit = XT_CONNTRACK_STATE_UNTRACKED; | ||
41 | else if (ct) | ||
42 | statebit = XT_CONNTRACK_STATE_BIT(ctinfo); | ||
43 | else | ||
44 | statebit = XT_CONNTRACK_STATE_INVALID; | ||
45 | |||
46 | if (sinfo->flags & XT_CONNTRACK_STATE) { | ||
47 | if (ct) { | ||
48 | if (test_bit(IPS_SRC_NAT_BIT, &ct->status)) | ||
49 | statebit |= XT_CONNTRACK_STATE_SNAT; | ||
50 | if (test_bit(IPS_DST_NAT_BIT, &ct->status)) | ||
51 | statebit |= XT_CONNTRACK_STATE_DNAT; | ||
52 | } | ||
53 | if (FWINV((statebit & sinfo->statemask) == 0, | ||
54 | XT_CONNTRACK_STATE)) | ||
55 | return false; | ||
56 | } | ||
57 | |||
58 | if (ct == NULL) { | ||
59 | if (sinfo->flags & ~XT_CONNTRACK_STATE) | ||
60 | return false; | ||
61 | return true; | ||
62 | } | ||
63 | |||
64 | if (sinfo->flags & XT_CONNTRACK_PROTO && | ||
65 | FWINV(nf_ct_protonum(ct) != | ||
66 | sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, | ||
67 | XT_CONNTRACK_PROTO)) | ||
68 | return false; | ||
69 | |||
70 | if (sinfo->flags & XT_CONNTRACK_ORIGSRC && | ||
71 | FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip & | ||
72 | sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != | ||
73 | sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, | ||
74 | XT_CONNTRACK_ORIGSRC)) | ||
75 | return false; | ||
76 | |||
77 | if (sinfo->flags & XT_CONNTRACK_ORIGDST && | ||
78 | FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip & | ||
79 | sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != | ||
80 | sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, | ||
81 | XT_CONNTRACK_ORIGDST)) | ||
82 | return false; | ||
83 | |||
84 | if (sinfo->flags & XT_CONNTRACK_REPLSRC && | ||
85 | FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip & | ||
86 | sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != | ||
87 | sinfo->tuple[IP_CT_DIR_REPLY].src.ip, | ||
88 | XT_CONNTRACK_REPLSRC)) | ||
89 | return false; | ||
90 | |||
91 | if (sinfo->flags & XT_CONNTRACK_REPLDST && | ||
92 | FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip & | ||
93 | sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != | ||
94 | sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, | ||
95 | XT_CONNTRACK_REPLDST)) | ||
96 | return false; | ||
97 | |||
98 | if (sinfo->flags & XT_CONNTRACK_STATUS && | ||
99 | FWINV((ct->status & sinfo->statusmask) == 0, | ||
100 | XT_CONNTRACK_STATUS)) | ||
101 | return false; | ||
102 | |||
103 | if(sinfo->flags & XT_CONNTRACK_EXPIRES) { | ||
104 | unsigned long expires = timer_pending(&ct->timeout) ? | ||
105 | (ct->timeout.expires - jiffies)/HZ : 0; | ||
106 | |||
107 | if (FWINV(!(expires >= sinfo->expires_min && | ||
108 | expires <= sinfo->expires_max), | ||
109 | XT_CONNTRACK_EXPIRES)) | ||
110 | return false; | ||
111 | } | ||
112 | return true; | ||
113 | #undef FWINV | ||
114 | } | ||
115 | |||
116 | static bool | ||
117 | conntrack_addrcmp(const union nf_inet_addr *kaddr, | 28 | conntrack_addrcmp(const union nf_inet_addr *kaddr, |
118 | const union nf_inet_addr *uaddr, | 29 | const union nf_inet_addr *uaddr, |
119 | const union nf_inet_addr *umask, unsigned int l3proto) | 30 | const union nf_inet_addr *umask, unsigned int l3proto) |
@@ -337,73 +248,9 @@ static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par) | |||
337 | conntrack_mt_destroy(par); | 248 | conntrack_mt_destroy(par); |
338 | } | 249 | } |
339 | 250 | ||
340 | #ifdef CONFIG_COMPAT | ||
341 | struct compat_xt_conntrack_info | ||
342 | { | ||
343 | compat_uint_t statemask; | ||
344 | compat_uint_t statusmask; | ||
345 | struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; | ||
346 | struct in_addr sipmsk[IP_CT_DIR_MAX]; | ||
347 | struct in_addr dipmsk[IP_CT_DIR_MAX]; | ||
348 | compat_ulong_t expires_min; | ||
349 | compat_ulong_t expires_max; | ||
350 | u_int8_t flags; | ||
351 | u_int8_t invflags; | ||
352 | }; | ||
353 | |||
354 | static void conntrack_mt_compat_from_user_v0(void *dst, void *src) | ||
355 | { | ||
356 | const struct compat_xt_conntrack_info *cm = src; | ||
357 | struct xt_conntrack_info m = { | ||
358 | .statemask = cm->statemask, | ||
359 | .statusmask = cm->statusmask, | ||
360 | .expires_min = cm->expires_min, | ||
361 | .expires_max = cm->expires_max, | ||
362 | .flags = cm->flags, | ||
363 | .invflags = cm->invflags, | ||
364 | }; | ||
365 | memcpy(m.tuple, cm->tuple, sizeof(m.tuple)); | ||
366 | memcpy(m.sipmsk, cm->sipmsk, sizeof(m.sipmsk)); | ||
367 | memcpy(m.dipmsk, cm->dipmsk, sizeof(m.dipmsk)); | ||
368 | memcpy(dst, &m, sizeof(m)); | ||
369 | } | ||
370 | |||
371 | static int conntrack_mt_compat_to_user_v0(void __user *dst, void *src) | ||
372 | { | ||
373 | const struct xt_conntrack_info *m = src; | ||
374 | struct compat_xt_conntrack_info cm = { | ||
375 | .statemask = m->statemask, | ||
376 | .statusmask = m->statusmask, | ||
377 | .expires_min = m->expires_min, | ||
378 | .expires_max = m->expires_max, | ||
379 | .flags = m->flags, | ||
380 | .invflags = m->invflags, | ||
381 | }; | ||
382 | memcpy(cm.tuple, m->tuple, sizeof(cm.tuple)); | ||
383 | memcpy(cm.sipmsk, m->sipmsk, sizeof(cm.sipmsk)); | ||
384 | memcpy(cm.dipmsk, m->dipmsk, sizeof(cm.dipmsk)); | ||
385 | return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; | ||
386 | } | ||
387 | #endif | ||
388 | |||
389 | static struct xt_match conntrack_mt_reg[] __read_mostly = { | 251 | static struct xt_match conntrack_mt_reg[] __read_mostly = { |
390 | { | 252 | { |
391 | .name = "conntrack", | 253 | .name = "conntrack", |
392 | .revision = 0, | ||
393 | .family = NFPROTO_IPV4, | ||
394 | .match = conntrack_mt_v0, | ||
395 | .checkentry = conntrack_mt_check, | ||
396 | .destroy = conntrack_mt_destroy, | ||
397 | .matchsize = sizeof(struct xt_conntrack_info), | ||
398 | .me = THIS_MODULE, | ||
399 | #ifdef CONFIG_COMPAT | ||
400 | .compatsize = sizeof(struct compat_xt_conntrack_info), | ||
401 | .compat_from_user = conntrack_mt_compat_from_user_v0, | ||
402 | .compat_to_user = conntrack_mt_compat_to_user_v0, | ||
403 | #endif | ||
404 | }, | ||
405 | { | ||
406 | .name = "conntrack", | ||
407 | .revision = 1, | 254 | .revision = 1, |
408 | .family = NFPROTO_UNSPEC, | 255 | .family = NFPROTO_UNSPEC, |
409 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), | 256 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), |