aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-08 01:31:32 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:17:55 -0400
commitd4156e8cd93f5772483928aaf4960120caebd789 (patch)
treee740e629df29d8ea1ad21244998851362b64a70e
parentdf43b4e7ca46952756b2fc039ed80469b1bff62d (diff)
[NETFILTER]: nf_conntrack: reduce masks to a subset of tuples
Since conntrack currently allows to use masks for every bit of both helper and expectation tuples, we can't hash them and have to keep them on two global lists that are searched for every new connection. This patch removes the never used ability to use masks for the destination part of the expectation tuple and completely removes masks from helpers since the only reasonable choice is a full match on l3num, protonum and src.u.all. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/netfilter/nf_conntrack_expect.h3
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h5
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h65
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c6
-rw-r--r--net/netfilter/nf_conntrack_amanda.c6
-rw-r--r--net/netfilter/nf_conntrack_expect.c44
-rw-r--r--net/netfilter/nf_conntrack_ftp.c3
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c14
-rw-r--r--net/netfilter/nf_conntrack_helper.c3
-rw-r--r--net/netfilter/nf_conntrack_irc.c3
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c6
-rw-r--r--net/netfilter/nf_conntrack_netlink.c18
-rw-r--r--net/netfilter/nf_conntrack_pptp.c3
-rw-r--r--net/netfilter/nf_conntrack_sane.c2
-rw-r--r--net/netfilter/nf_conntrack_sip.c3
-rw-r--r--net/netfilter/nf_conntrack_tftp.c3
16 files changed, 71 insertions, 116 deletions
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index c0b1d1fb23e1..13643f7f7422 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -16,7 +16,8 @@ struct nf_conntrack_expect
16 struct list_head list; 16 struct list_head list;
17 17
18 /* We expect this tuple, with the following mask */ 18 /* We expect this tuple, with the following mask */
19 struct nf_conntrack_tuple tuple, mask; 19 struct nf_conntrack_tuple tuple;
20 struct nf_conntrack_tuple_mask mask;
20 21
21 /* Function to call after setup and insertion */ 22 /* Function to call after setup and insertion */
22 void (*expectfn)(struct nf_conn *new, 23 void (*expectfn)(struct nf_conn *new,
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index b43a75ba44ac..d62e6f093af4 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -24,10 +24,9 @@ struct nf_conntrack_helper
24 * expected connections */ 24 * expected connections */
25 unsigned int timeout; /* timeout for expecteds */ 25 unsigned int timeout; /* timeout for expecteds */
26 26
27 /* Mask of things we will help (compared against server response) */ 27 /* Tuple of things we will help (compared against server response) */
28 struct nf_conntrack_tuple tuple; 28 struct nf_conntrack_tuple tuple;
29 struct nf_conntrack_tuple mask; 29
30
31 /* Function to call when data passes; return verdict, or -1 to 30 /* Function to call when data passes; return verdict, or -1 to
32 invalidate. */ 31 invalidate. */
33 int (*help)(struct sk_buff **pskb, 32 int (*help)(struct sk_buff **pskb,
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index d02ce876b4ca..99934ab538e6 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -100,6 +100,14 @@ struct nf_conntrack_tuple
100 } dst; 100 } dst;
101}; 101};
102 102
103struct nf_conntrack_tuple_mask
104{
105 struct {
106 union nf_conntrack_address u3;
107 union nf_conntrack_man_proto u;
108 } src;
109};
110
103/* This is optimized opposed to a memset of the whole structure. Everything we 111/* This is optimized opposed to a memset of the whole structure. Everything we
104 * really care about is the source/destination unions */ 112 * really care about is the source/destination unions */
105#define NF_CT_TUPLE_U_BLANK(tuple) \ 113#define NF_CT_TUPLE_U_BLANK(tuple) \
@@ -161,31 +169,44 @@ static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
161 return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2); 169 return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
162} 170}
163 171
172static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
173 const struct nf_conntrack_tuple_mask *m2)
174{
175 return (m1->src.u3.all[0] == m2->src.u3.all[0] &&
176 m1->src.u3.all[1] == m2->src.u3.all[1] &&
177 m1->src.u3.all[2] == m2->src.u3.all[2] &&
178 m1->src.u3.all[3] == m2->src.u3.all[3] &&
179 m1->src.u.all == m2->src.u.all);
180}
181
182static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
183 const struct nf_conntrack_tuple *t2,
184 const struct nf_conntrack_tuple_mask *mask)
185{
186 int count;
187
188 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
189 if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
190 mask->src.u3.all[count])
191 return 0;
192 }
193
194 if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
195 return 0;
196
197 if (t1->src.l3num != t2->src.l3num ||
198 t1->dst.protonum != t2->dst.protonum)
199 return 0;
200
201 return 1;
202}
203
164static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, 204static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
165 const struct nf_conntrack_tuple *tuple, 205 const struct nf_conntrack_tuple *tuple,
166 const struct nf_conntrack_tuple *mask) 206 const struct nf_conntrack_tuple_mask *mask)
167{ 207{
168 int count = 0; 208 return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
169 209 nf_ct_tuple_dst_equal(t, tuple);
170 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
171 if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
172 mask->src.u3.all[count])
173 return 0;
174 }
175
176 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
177 if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
178 mask->dst.u3.all[count])
179 return 0;
180 }
181
182 if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
183 (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
184 (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
185 (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
186 return 0;
187
188 return 1;
189} 210}
190 211
191#endif /* _NF_CONNTRACK_TUPLE_H */ 212#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 6e88505d6162..6bfcd3a90f08 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1276,9 +1276,6 @@ static struct nf_conntrack_helper snmp_helper __read_mostly = {
1276 .tuple.src.l3num = AF_INET, 1276 .tuple.src.l3num = AF_INET,
1277 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT), 1277 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT),
1278 .tuple.dst.protonum = IPPROTO_UDP, 1278 .tuple.dst.protonum = IPPROTO_UDP,
1279 .mask.src.l3num = 0xFFFF,
1280 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1281 .mask.dst.protonum = 0xFF,
1282}; 1279};
1283 1280
1284static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { 1281static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
@@ -1290,9 +1287,6 @@ static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1290 .tuple.src.l3num = AF_INET, 1287 .tuple.src.l3num = AF_INET,
1291 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT), 1288 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),
1292 .tuple.dst.protonum = IPPROTO_UDP, 1289 .tuple.dst.protonum = IPPROTO_UDP,
1293 .mask.src.l3num = 0xFFFF,
1294 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1295 .mask.dst.protonum = 0xFF,
1296}; 1290};
1297 1291
1298/***************************************************************************** 1292/*****************************************************************************
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index d21359e6c14c..e42ab230ad88 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -174,9 +174,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
174 .tuple.src.l3num = AF_INET, 174 .tuple.src.l3num = AF_INET,
175 .tuple.src.u.udp.port = __constant_htons(10080), 175 .tuple.src.u.udp.port = __constant_htons(10080),
176 .tuple.dst.protonum = IPPROTO_UDP, 176 .tuple.dst.protonum = IPPROTO_UDP,
177 .mask.src.l3num = 0xFFFF,
178 .mask.src.u.udp.port = __constant_htons(0xFFFF),
179 .mask.dst.protonum = 0xFF,
180 }, 177 },
181 { 178 {
182 .name = "amanda", 179 .name = "amanda",
@@ -187,9 +184,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
187 .tuple.src.l3num = AF_INET6, 184 .tuple.src.l3num = AF_INET6,
188 .tuple.src.u.udp.port = __constant_htons(10080), 185 .tuple.src.u.udp.port = __constant_htons(10080),
189 .tuple.dst.protonum = IPPROTO_UDP, 186 .tuple.dst.protonum = IPPROTO_UDP,
190 .mask.src.l3num = 0xFFFF,
191 .mask.src.u.udp.port = __constant_htons(0xFFFF),
192 .mask.dst.protonum = 0xFF,
193 }, 187 },
194}; 188};
195 189
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 4130ea662c48..83b5ad85e0ee 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -141,25 +141,16 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
141{ 141{
142 /* Part covered by intersection of masks must be unequal, 142 /* Part covered by intersection of masks must be unequal,
143 otherwise they clash */ 143 otherwise they clash */
144 struct nf_conntrack_tuple intersect_mask; 144 struct nf_conntrack_tuple_mask intersect_mask;
145 int count; 145 int count;
146 146
147 intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
148 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all; 147 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
149 intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
150 intersect_mask.dst.protonum = a->mask.dst.protonum
151 & b->mask.dst.protonum;
152 148
153 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){ 149 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
154 intersect_mask.src.u3.all[count] = 150 intersect_mask.src.u3.all[count] =
155 a->mask.src.u3.all[count] & b->mask.src.u3.all[count]; 151 a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
156 } 152 }
157 153
158 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
159 intersect_mask.dst.u3.all[count] =
160 a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
161 }
162
163 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask); 154 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
164} 155}
165 156
@@ -168,7 +159,7 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
168{ 159{
169 return a->master == b->master 160 return a->master == b->master
170 && nf_ct_tuple_equal(&a->tuple, &b->tuple) 161 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
171 && nf_ct_tuple_equal(&a->mask, &b->mask); 162 && nf_ct_tuple_mask_equal(&a->mask, &b->mask);
172} 163}
173 164
174/* Generally a bad idea to call this: could have matched already. */ 165/* Generally a bad idea to call this: could have matched already. */
@@ -224,8 +215,6 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
224 exp->helper = NULL; 215 exp->helper = NULL;
225 exp->tuple.src.l3num = family; 216 exp->tuple.src.l3num = family;
226 exp->tuple.dst.protonum = proto; 217 exp->tuple.dst.protonum = proto;
227 exp->mask.src.l3num = 0xFFFF;
228 exp->mask.dst.protonum = 0xFF;
229 218
230 if (saddr) { 219 if (saddr) {
231 memcpy(&exp->tuple.src.u3, saddr, len); 220 memcpy(&exp->tuple.src.u3, saddr, len);
@@ -242,21 +231,6 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
242 memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3)); 231 memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
243 } 232 }
244 233
245 if (daddr) {
246 memcpy(&exp->tuple.dst.u3, daddr, len);
247 if (sizeof(exp->tuple.dst.u3) > len)
248 /* address needs to be cleared for nf_ct_tuple_equal */
249 memset((void *)&exp->tuple.dst.u3 + len, 0x00,
250 sizeof(exp->tuple.dst.u3) - len);
251 memset(&exp->mask.dst.u3, 0xFF, len);
252 if (sizeof(exp->mask.dst.u3) > len)
253 memset((void *)&exp->mask.dst.u3 + len, 0x00,
254 sizeof(exp->mask.dst.u3) - len);
255 } else {
256 memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
257 memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
258 }
259
260 if (src) { 234 if (src) {
261 exp->tuple.src.u.all = (__force u16)*src; 235 exp->tuple.src.u.all = (__force u16)*src;
262 exp->mask.src.u.all = 0xFFFF; 236 exp->mask.src.u.all = 0xFFFF;
@@ -265,13 +239,13 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
265 exp->mask.src.u.all = 0; 239 exp->mask.src.u.all = 0;
266 } 240 }
267 241
268 if (dst) { 242 memcpy(&exp->tuple.dst.u3, daddr, len);
269 exp->tuple.dst.u.all = (__force u16)*dst; 243 if (sizeof(exp->tuple.dst.u3) > len)
270 exp->mask.dst.u.all = 0xFFFF; 244 /* address needs to be cleared for nf_ct_tuple_equal */
271 } else { 245 memset((void *)&exp->tuple.dst.u3 + len, 0x00,
272 exp->tuple.dst.u.all = 0; 246 sizeof(exp->tuple.dst.u3) - len);
273 exp->mask.dst.u.all = 0; 247
274 } 248 exp->tuple.dst.u.all = (__force u16)*dst;
275} 249}
276EXPORT_SYMBOL_GPL(nf_ct_expect_init); 250EXPORT_SYMBOL_GPL(nf_ct_expect_init);
277 251
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 9ad15191bb44..198330b8ada4 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -560,9 +560,6 @@ static int __init nf_conntrack_ftp_init(void)
560 for (j = 0; j < 2; j++) { 560 for (j = 0; j < 2; j++) {
561 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); 561 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
562 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; 562 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
563 ftp[i][j].mask.src.l3num = 0xFFFF;
564 ftp[i][j].mask.src.u.tcp.port = htons(0xFFFF);
565 ftp[i][j].mask.dst.protonum = 0xFF;
566 ftp[i][j].max_expected = 1; 563 ftp[i][j].max_expected = 1;
567 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */ 564 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
568 ftp[i][j].me = THIS_MODULE; 565 ftp[i][j].me = THIS_MODULE;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 61ae90fb328a..8c57b8119bfb 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -626,8 +626,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
626 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */, 626 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
627 .timeout = 240, 627 .timeout = 240,
628 .tuple.dst.protonum = IPPROTO_UDP, 628 .tuple.dst.protonum = IPPROTO_UDP,
629 .mask.src.u.udp.port = __constant_htons(0xFFFF),
630 .mask.dst.protonum = 0xFF,
631 .help = h245_help 629 .help = h245_help
632}; 630};
633 631
@@ -1173,9 +1171,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
1173 .tuple.src.l3num = AF_INET, 1171 .tuple.src.l3num = AF_INET,
1174 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1172 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1175 .tuple.dst.protonum = IPPROTO_TCP, 1173 .tuple.dst.protonum = IPPROTO_TCP,
1176 .mask.src.l3num = 0xFFFF,
1177 .mask.src.u.tcp.port = __constant_htons(0xFFFF),
1178 .mask.dst.protonum = 0xFF,
1179 .help = q931_help 1174 .help = q931_help
1180 }, 1175 },
1181 { 1176 {
@@ -1187,9 +1182,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
1187 .tuple.src.l3num = AF_INET6, 1182 .tuple.src.l3num = AF_INET6,
1188 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1183 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1189 .tuple.dst.protonum = IPPROTO_TCP, 1184 .tuple.dst.protonum = IPPROTO_TCP,
1190 .mask.src.l3num = 0xFFFF,
1191 .mask.src.u.tcp.port = __constant_htons(0xFFFF),
1192 .mask.dst.protonum = 0xFF,
1193 .help = q931_help 1185 .help = q931_help
1194 }, 1186 },
1195}; 1187};
@@ -1751,9 +1743,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
1751 .tuple.src.l3num = AF_INET, 1743 .tuple.src.l3num = AF_INET,
1752 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1744 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1753 .tuple.dst.protonum = IPPROTO_UDP, 1745 .tuple.dst.protonum = IPPROTO_UDP,
1754 .mask.src.l3num = 0xFFFF,
1755 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1756 .mask.dst.protonum = 0xFF,
1757 .help = ras_help, 1746 .help = ras_help,
1758 }, 1747 },
1759 { 1748 {
@@ -1764,9 +1753,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
1764 .tuple.src.l3num = AF_INET6, 1753 .tuple.src.l3num = AF_INET6,
1765 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1754 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1766 .tuple.dst.protonum = IPPROTO_UDP, 1755 .tuple.dst.protonum = IPPROTO_UDP,
1767 .mask.src.l3num = 0xFFFF,
1768 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1769 .mask.dst.protonum = 0xFF,
1770 .help = ras_help, 1756 .help = ras_help,
1771 }, 1757 },
1772}; 1758};
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 89a5f7333d38..fdabf823f8cd 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -34,9 +34,10 @@ struct nf_conntrack_helper *
34__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) 34__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
35{ 35{
36 struct nf_conntrack_helper *h; 36 struct nf_conntrack_helper *h;
37 struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
37 38
38 list_for_each_entry(h, &helpers, list) { 39 list_for_each_entry(h, &helpers, list) {
39 if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask)) 40 if (nf_ct_tuple_src_mask_cmp(tuple, &h->tuple, &mask))
40 return h; 41 return h;
41 } 42 }
42 return NULL; 43 return NULL;
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 79da93e4396b..8c7340794bf6 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -239,9 +239,6 @@ static int __init nf_conntrack_irc_init(void)
239 irc[i].tuple.src.l3num = AF_INET; 239 irc[i].tuple.src.l3num = AF_INET;
240 irc[i].tuple.src.u.tcp.port = htons(ports[i]); 240 irc[i].tuple.src.u.tcp.port = htons(ports[i]);
241 irc[i].tuple.dst.protonum = IPPROTO_TCP; 241 irc[i].tuple.dst.protonum = IPPROTO_TCP;
242 irc[i].mask.src.l3num = 0xFFFF;
243 irc[i].mask.src.u.tcp.port = htons(0xFFFF);
244 irc[i].mask.dst.protonum = 0xFF;
245 irc[i].max_expected = max_dcc_channels; 242 irc[i].max_expected = max_dcc_channels;
246 irc[i].timeout = dcc_timeout; 243 irc[i].timeout = dcc_timeout;
247 irc[i].me = THIS_MODULE; 244 irc[i].me = THIS_MODULE;
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index ea585c789a83..1d59fabeb5f7 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -83,9 +83,6 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
83 83
84 exp->mask.src.u3.ip = mask; 84 exp->mask.src.u3.ip = mask;
85 exp->mask.src.u.udp.port = htons(0xFFFF); 85 exp->mask.src.u.udp.port = htons(0xFFFF);
86 exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
87 exp->mask.dst.u.udp.port = htons(0xFFFF);
88 exp->mask.dst.protonum = 0xFF;
89 86
90 exp->expectfn = NULL; 87 exp->expectfn = NULL;
91 exp->flags = NF_CT_EXPECT_PERMANENT; 88 exp->flags = NF_CT_EXPECT_PERMANENT;
@@ -104,9 +101,6 @@ static struct nf_conntrack_helper helper __read_mostly = {
104 .tuple.src.l3num = AF_INET, 101 .tuple.src.l3num = AF_INET,
105 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT), 102 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT),
106 .tuple.dst.protonum = IPPROTO_UDP, 103 .tuple.dst.protonum = IPPROTO_UDP,
107 .mask.src.l3num = 0xFFFF,
108 .mask.src.u.udp.port = __constant_htons(0xFFFF),
109 .mask.dst.protonum = 0xFF,
110 .max_expected = 1, 104 .max_expected = 1,
111 .me = THIS_MODULE, 105 .me = THIS_MODULE,
112 .help = help, 106 .help = help,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 954cc58b9d04..206491488f4e 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1094,22 +1094,29 @@ nfattr_failure:
1094static inline int 1094static inline int
1095ctnetlink_exp_dump_mask(struct sk_buff *skb, 1095ctnetlink_exp_dump_mask(struct sk_buff *skb,
1096 const struct nf_conntrack_tuple *tuple, 1096 const struct nf_conntrack_tuple *tuple,
1097 const struct nf_conntrack_tuple *mask) 1097 const struct nf_conntrack_tuple_mask *mask)
1098{ 1098{
1099 int ret; 1099 int ret;
1100 struct nf_conntrack_l3proto *l3proto; 1100 struct nf_conntrack_l3proto *l3proto;
1101 struct nf_conntrack_l4proto *l4proto; 1101 struct nf_conntrack_l4proto *l4proto;
1102 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); 1102 struct nf_conntrack_tuple m;
1103 struct nfattr *nest_parms;
1104
1105 memset(&m, 0xFF, sizeof(m));
1106 m.src.u.all = mask->src.u.all;
1107 memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
1108
1109 nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
1103 1110
1104 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 1111 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
1105 ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto); 1112 ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
1106 nf_ct_l3proto_put(l3proto); 1113 nf_ct_l3proto_put(l3proto);
1107 1114
1108 if (unlikely(ret < 0)) 1115 if (unlikely(ret < 0))
1109 goto nfattr_failure; 1116 goto nfattr_failure;
1110 1117
1111 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 1118 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
1112 ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto); 1119 ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
1113 nf_ct_l4proto_put(l4proto); 1120 nf_ct_l4proto_put(l4proto);
1114 if (unlikely(ret < 0)) 1121 if (unlikely(ret < 0))
1115 goto nfattr_failure; 1122 goto nfattr_failure;
@@ -1447,7 +1454,8 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1447 exp->master = ct; 1454 exp->master = ct;
1448 exp->helper = NULL; 1455 exp->helper = NULL;
1449 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); 1456 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
1450 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple)); 1457 memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
1458 exp->mask.src.u.all = mask.src.u.all;
1451 1459
1452 err = nf_ct_expect_related(exp); 1460 err = nf_ct_expect_related(exp);
1453 nf_ct_expect_put(exp); 1461 nf_ct_expect_put(exp);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 916e106d36bc..63dac5eb959f 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -585,9 +585,6 @@ static struct nf_conntrack_helper pptp __read_mostly = {
585 .tuple.src.l3num = AF_INET, 585 .tuple.src.l3num = AF_INET,
586 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT), 586 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT),
587 .tuple.dst.protonum = IPPROTO_TCP, 587 .tuple.dst.protonum = IPPROTO_TCP,
588 .mask.src.l3num = 0xffff,
589 .mask.src.u.tcp.port = __constant_htons(0xffff),
590 .mask.dst.protonum = 0xff,
591 .help = conntrack_pptp_help, 588 .help = conntrack_pptp_help,
592 .destroy = pptp_destroy_siblings, 589 .destroy = pptp_destroy_siblings,
593}; 590};
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 28ed303c565b..edd10df8aa08 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -206,8 +206,6 @@ static int __init nf_conntrack_sane_init(void)
206 for (j = 0; j < 2; j++) { 206 for (j = 0; j < 2; j++) {
207 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); 207 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
208 sane[i][j].tuple.dst.protonum = IPPROTO_TCP; 208 sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
209 sane[i][j].mask.src.u.tcp.port = 0xFFFF;
210 sane[i][j].mask.dst.protonum = 0xFF;
211 sane[i][j].max_expected = 1; 209 sane[i][j].max_expected = 1;
212 sane[i][j].timeout = 5 * 60; /* 5 Minutes */ 210 sane[i][j].timeout = 5 * 60; /* 5 Minutes */
213 sane[i][j].me = THIS_MODULE; 211 sane[i][j].me = THIS_MODULE;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 1f17f8040cd2..5b78f0e1f63b 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -506,9 +506,6 @@ static int __init nf_conntrack_sip_init(void)
506 for (j = 0; j < 2; j++) { 506 for (j = 0; j < 2; j++) {
507 sip[i][j].tuple.dst.protonum = IPPROTO_UDP; 507 sip[i][j].tuple.dst.protonum = IPPROTO_UDP;
508 sip[i][j].tuple.src.u.udp.port = htons(ports[i]); 508 sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
509 sip[i][j].mask.src.l3num = 0xFFFF;
510 sip[i][j].mask.src.u.udp.port = htons(0xFFFF);
511 sip[i][j].mask.dst.protonum = 0xFF;
512 sip[i][j].max_expected = 2; 509 sip[i][j].max_expected = 2;
513 sip[i][j].timeout = 3 * 60; /* 3 minutes */ 510 sip[i][j].timeout = 3 * 60; /* 3 minutes */
514 sip[i][j].me = THIS_MODULE; 511 sip[i][j].me = THIS_MODULE;
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index 53d57b4c0de7..db0387cf9bac 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -126,9 +126,6 @@ static int __init nf_conntrack_tftp_init(void)
126 for (j = 0; j < 2; j++) { 126 for (j = 0; j < 2; j++) {
127 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP; 127 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP;
128 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]); 128 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]);
129 tftp[i][j].mask.src.l3num = 0xFFFF;
130 tftp[i][j].mask.dst.protonum = 0xFF;
131 tftp[i][j].mask.src.u.udp.port = htons(0xFFFF);
132 tftp[i][j].max_expected = 1; 129 tftp[i][j].max_expected = 1;
133 tftp[i][j].timeout = 5 * 60; /* 5 minutes */ 130 tftp[i][j].timeout = 5 * 60; /* 5 minutes */
134 tftp[i][j].me = THIS_MODULE; 131 tftp[i][j].me = THIS_MODULE;