aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-03-25 23:09:15 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-25 23:09:15 -0400
commit6002f266b3e7f0acc2d5158cddbed41730b02e82 (patch)
treef776f47618eef4da0d6c43b6f34fe6634d426a8d /net
parent359b9ab614aba71c2c3bc047efbd6d12dd4a2b9e (diff)
[NETFILTER]: nf_conntrack: introduce expectation classes and policies
Introduce expectation classes and policies. An expectation class is used to distinguish different types of expectations by the same helper (for example audio/video/t.120). The expectation policy is used to hold the maximum number of expectations and the initial timeout for each class. The individual classes are isolated from each other, which means that for example an audio expectation will only evict other audio expectations. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c12
-rw-r--r--net/netfilter/nf_conntrack_amanda.c14
-rw-r--r--net/netfilter/nf_conntrack_expect.c50
-rw-r--r--net/netfilter/nf_conntrack_ftp.c10
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c66
-rw-r--r--net/netfilter/nf_conntrack_helper.c3
-rw-r--r--net/netfilter/nf_conntrack_irc.c10
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c9
-rw-r--r--net/netfilter/nf_conntrack_pptp.c14
-rw-r--r--net/netfilter/nf_conntrack_sane.c11
-rw-r--r--net/netfilter/nf_conntrack_sip.c10
-rw-r--r--net/netfilter/nf_conntrack_tftp.c11
12 files changed, 148 insertions, 72 deletions
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 540ce6ae887c..000e080bac5c 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -50,6 +50,7 @@
50#include <net/udp.h> 50#include <net/udp.h>
51 51
52#include <net/netfilter/nf_nat.h> 52#include <net/netfilter/nf_nat.h>
53#include <net/netfilter/nf_conntrack_expect.h>
53#include <net/netfilter/nf_conntrack_helper.h> 54#include <net/netfilter/nf_conntrack_helper.h>
54#include <net/netfilter/nf_nat_helper.h> 55#include <net/netfilter/nf_nat_helper.h>
55 56
@@ -1267,11 +1268,15 @@ static int help(struct sk_buff *skb, unsigned int protoff,
1267 return ret; 1268 return ret;
1268} 1269}
1269 1270
1271static const struct nf_conntrack_expect_policy snmp_exp_policy = {
1272 .max_expected = 0,
1273 .timeout = 180,
1274};
1275
1270static struct nf_conntrack_helper snmp_helper __read_mostly = { 1276static struct nf_conntrack_helper snmp_helper __read_mostly = {
1271 .max_expected = 0,
1272 .timeout = 180,
1273 .me = THIS_MODULE, 1277 .me = THIS_MODULE,
1274 .help = help, 1278 .help = help,
1279 .expect_policy = &snmp_exp_policy,
1275 .name = "snmp", 1280 .name = "snmp",
1276 .tuple.src.l3num = AF_INET, 1281 .tuple.src.l3num = AF_INET,
1277 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT), 1282 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT),
@@ -1279,10 +1284,9 @@ static struct nf_conntrack_helper snmp_helper __read_mostly = {
1279}; 1284};
1280 1285
1281static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { 1286static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1282 .max_expected = 0,
1283 .timeout = 180,
1284 .me = THIS_MODULE, 1287 .me = THIS_MODULE,
1285 .help = help, 1288 .help = help,
1289 .expect_policy = &snmp_exp_policy,
1286 .name = "snmp_trap", 1290 .name = "snmp_trap",
1287 .tuple.src.l3num = AF_INET, 1291 .tuple.src.l3num = AF_INET,
1288 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT), 1292 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index 7b8239c0cd5e..d14585a19b7d 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -148,7 +148,8 @@ static int amanda_help(struct sk_buff *skb,
148 goto out; 148 goto out;
149 } 149 }
150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
151 nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3, 151 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family,
152 &tuple->src.u3, &tuple->dst.u3,
152 IPPROTO_TCP, NULL, &port); 153 IPPROTO_TCP, NULL, &port);
153 154
154 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook); 155 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
@@ -164,26 +165,29 @@ out:
164 return ret; 165 return ret;
165} 166}
166 167
168static const struct nf_conntrack_expect_policy amanda_exp_policy = {
169 .max_expected = 3,
170 .timeout = 180,
171};
172
167static struct nf_conntrack_helper amanda_helper[2] __read_mostly = { 173static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
168 { 174 {
169 .name = "amanda", 175 .name = "amanda",
170 .max_expected = 3,
171 .timeout = 180,
172 .me = THIS_MODULE, 176 .me = THIS_MODULE,
173 .help = amanda_help, 177 .help = amanda_help,
174 .tuple.src.l3num = AF_INET, 178 .tuple.src.l3num = AF_INET,
175 .tuple.src.u.udp.port = __constant_htons(10080), 179 .tuple.src.u.udp.port = __constant_htons(10080),
176 .tuple.dst.protonum = IPPROTO_UDP, 180 .tuple.dst.protonum = IPPROTO_UDP,
181 .expect_policy = &amanda_exp_policy,
177 }, 182 },
178 { 183 {
179 .name = "amanda", 184 .name = "amanda",
180 .max_expected = 3,
181 .timeout = 180,
182 .me = THIS_MODULE, 185 .me = THIS_MODULE,
183 .help = amanda_help, 186 .help = amanda_help,
184 .tuple.src.l3num = AF_INET6, 187 .tuple.src.l3num = AF_INET6,
185 .tuple.src.u.udp.port = __constant_htons(10080), 188 .tuple.src.u.udp.port = __constant_htons(10080),
186 .tuple.dst.protonum = IPPROTO_UDP, 189 .tuple.dst.protonum = IPPROTO_UDP,
190 .expect_policy = &amanda_exp_policy,
187 }, 191 },
188}; 192};
189 193
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 882602f1c0ef..e31beeb33b2b 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -54,7 +54,7 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
54 nf_ct_expect_count--; 54 nf_ct_expect_count--;
55 55
56 hlist_del(&exp->lnode); 56 hlist_del(&exp->lnode);
57 master_help->expecting--; 57 master_help->expecting[exp->class]--;
58 nf_ct_expect_put(exp); 58 nf_ct_expect_put(exp);
59 59
60 NF_CT_STAT_INC(expect_delete); 60 NF_CT_STAT_INC(expect_delete);
@@ -171,7 +171,7 @@ void nf_ct_remove_expectations(struct nf_conn *ct)
171 struct hlist_node *n, *next; 171 struct hlist_node *n, *next;
172 172
173 /* Optimization: most connection never expect any others. */ 173 /* Optimization: most connection never expect any others. */
174 if (!help || help->expecting == 0) 174 if (!help)
175 return; 175 return;
176 176
177 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) { 177 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
@@ -205,7 +205,7 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
205static inline int expect_matches(const struct nf_conntrack_expect *a, 205static inline int expect_matches(const struct nf_conntrack_expect *a,
206 const struct nf_conntrack_expect *b) 206 const struct nf_conntrack_expect *b)
207{ 207{
208 return a->master == b->master 208 return a->master == b->master && a->class == b->class
209 && nf_ct_tuple_equal(&a->tuple, &b->tuple) 209 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
210 && nf_ct_tuple_mask_equal(&a->mask, &b->mask); 210 && nf_ct_tuple_mask_equal(&a->mask, &b->mask);
211} 211}
@@ -240,7 +240,8 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
240} 240}
241EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); 241EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
242 242
243void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family, 243void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class,
244 int family,
244 const union nf_inet_addr *saddr, 245 const union nf_inet_addr *saddr,
245 const union nf_inet_addr *daddr, 246 const union nf_inet_addr *daddr,
246 u_int8_t proto, const __be16 *src, const __be16 *dst) 247 u_int8_t proto, const __be16 *src, const __be16 *dst)
@@ -253,6 +254,7 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
253 len = 16; 254 len = 16;
254 255
255 exp->flags = 0; 256 exp->flags = 0;
257 exp->class = class;
256 exp->expectfn = NULL; 258 exp->expectfn = NULL;
257 exp->helper = NULL; 259 exp->helper = NULL;
258 exp->tuple.src.l3num = family; 260 exp->tuple.src.l3num = family;
@@ -309,19 +311,21 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_put);
309static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) 311static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
310{ 312{
311 struct nf_conn_help *master_help = nfct_help(exp->master); 313 struct nf_conn_help *master_help = nfct_help(exp->master);
314 const struct nf_conntrack_expect_policy *p;
312 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple); 315 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
313 316
314 atomic_inc(&exp->use); 317 atomic_inc(&exp->use);
315 318
316 hlist_add_head(&exp->lnode, &master_help->expectations); 319 hlist_add_head(&exp->lnode, &master_help->expectations);
317 master_help->expecting++; 320 master_help->expecting[exp->class]++;
318 321
319 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); 322 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]);
320 nf_ct_expect_count++; 323 nf_ct_expect_count++;
321 324
322 setup_timer(&exp->timeout, nf_ct_expectation_timed_out, 325 setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
323 (unsigned long)exp); 326 (unsigned long)exp);
324 exp->timeout.expires = jiffies + master_help->helper->timeout * HZ; 327 p = &master_help->helper->expect_policy[exp->class];
328 exp->timeout.expires = jiffies + p->timeout * HZ;
325 add_timer(&exp->timeout); 329 add_timer(&exp->timeout);
326 330
327 atomic_inc(&exp->use); 331 atomic_inc(&exp->use);
@@ -329,35 +333,41 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
329} 333}
330 334
331/* Race with expectations being used means we could have none to find; OK. */ 335/* Race with expectations being used means we could have none to find; OK. */
332static void evict_oldest_expect(struct nf_conn *master) 336static void evict_oldest_expect(struct nf_conn *master,
337 struct nf_conntrack_expect *new)
333{ 338{
334 struct nf_conn_help *master_help = nfct_help(master); 339 struct nf_conn_help *master_help = nfct_help(master);
335 struct nf_conntrack_expect *exp = NULL; 340 struct nf_conntrack_expect *exp, *last = NULL;
336 struct hlist_node *n; 341 struct hlist_node *n;
337 342
338 hlist_for_each_entry(exp, n, &master_help->expectations, lnode) 343 hlist_for_each_entry(exp, n, &master_help->expectations, lnode) {
339 ; /* nothing */ 344 if (exp->class == new->class)
345 last = exp;
346 }
340 347
341 if (exp && del_timer(&exp->timeout)) { 348 if (last && del_timer(&last->timeout)) {
342 nf_ct_unlink_expect(exp); 349 nf_ct_unlink_expect(last);
343 nf_ct_expect_put(exp); 350 nf_ct_expect_put(last);
344 } 351 }
345} 352}
346 353
347static inline int refresh_timer(struct nf_conntrack_expect *i) 354static inline int refresh_timer(struct nf_conntrack_expect *i)
348{ 355{
349 struct nf_conn_help *master_help = nfct_help(i->master); 356 struct nf_conn_help *master_help = nfct_help(i->master);
357 const struct nf_conntrack_expect_policy *p;
350 358
351 if (!del_timer(&i->timeout)) 359 if (!del_timer(&i->timeout))
352 return 0; 360 return 0;
353 361
354 i->timeout.expires = jiffies + master_help->helper->timeout*HZ; 362 p = &master_help->helper->expect_policy[i->class];
363 i->timeout.expires = jiffies + p->timeout * HZ;
355 add_timer(&i->timeout); 364 add_timer(&i->timeout);
356 return 1; 365 return 1;
357} 366}
358 367
359int nf_ct_expect_related(struct nf_conntrack_expect *expect) 368int nf_ct_expect_related(struct nf_conntrack_expect *expect)
360{ 369{
370 const struct nf_conntrack_expect_policy *p;
361 struct nf_conntrack_expect *i; 371 struct nf_conntrack_expect *i;
362 struct nf_conn *master = expect->master; 372 struct nf_conn *master = expect->master;
363 struct nf_conn_help *master_help = nfct_help(master); 373 struct nf_conn_help *master_help = nfct_help(master);
@@ -386,9 +396,15 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
386 } 396 }
387 } 397 }
388 /* Will be over limit? */ 398 /* Will be over limit? */
389 if (master_help->helper->max_expected && 399 p = &master_help->helper->expect_policy[expect->class];
390 master_help->expecting >= master_help->helper->max_expected) 400 if (p->max_expected &&
391 evict_oldest_expect(master); 401 master_help->expecting[expect->class] >= p->max_expected) {
402 evict_oldest_expect(master, expect);
403 if (master_help->expecting[expect->class] >= p->max_expected) {
404 ret = -EMFILE;
405 goto out;
406 }
407 }
392 408
393 if (nf_ct_expect_count >= nf_ct_expect_max) { 409 if (nf_ct_expect_count >= nf_ct_expect_max) {
394 if (net_ratelimit()) 410 if (net_ratelimit())
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 6770baf2e845..7eff876bb8bc 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -483,7 +483,7 @@ static int help(struct sk_buff *skb,
483 daddr = &cmd.u3; 483 daddr = &cmd.u3;
484 } 484 }
485 485
486 nf_ct_expect_init(exp, cmd.l3num, 486 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, cmd.l3num,
487 &ct->tuplehash[!dir].tuple.src.u3, daddr, 487 &ct->tuplehash[!dir].tuple.src.u3, daddr,
488 IPPROTO_TCP, NULL, &cmd.u.tcp.port); 488 IPPROTO_TCP, NULL, &cmd.u.tcp.port);
489 489
@@ -517,6 +517,11 @@ out_update_nl:
517static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly; 517static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly;
518static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly; 518static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly;
519 519
520static const struct nf_conntrack_expect_policy ftp_exp_policy = {
521 .max_expected = 1,
522 .timeout = 5 * 60,
523};
524
520/* don't make this __exit, since it's called from __init ! */ 525/* don't make this __exit, since it's called from __init ! */
521static void nf_conntrack_ftp_fini(void) 526static void nf_conntrack_ftp_fini(void)
522{ 527{
@@ -556,8 +561,7 @@ static int __init nf_conntrack_ftp_init(void)
556 for (j = 0; j < 2; j++) { 561 for (j = 0; j < 2; j++) {
557 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); 562 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
558 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; 563 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
559 ftp[i][j].max_expected = 1; 564 ftp[i][j].expect_policy = &ftp_exp_policy;
560 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
561 ftp[i][j].me = THIS_MODULE; 565 ftp[i][j].me = THIS_MODULE;
562 ftp[i][j].help = help; 566 ftp[i][j].help = help;
563 tmpname = &ftp_names[i][j][0]; 567 tmpname = &ftp_names[i][j][0];
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 898f1922b5b8..505052d495cf 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -277,7 +277,8 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
277 /* Create expect for RTP */ 277 /* Create expect for RTP */
278 if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL) 278 if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL)
279 return -1; 279 return -1;
280 nf_ct_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num, 280 nf_ct_expect_init(rtp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
281 ct->tuplehash[!dir].tuple.src.l3num,
281 &ct->tuplehash[!dir].tuple.src.u3, 282 &ct->tuplehash[!dir].tuple.src.u3,
282 &ct->tuplehash[!dir].tuple.dst.u3, 283 &ct->tuplehash[!dir].tuple.dst.u3,
283 IPPROTO_UDP, NULL, &rtp_port); 284 IPPROTO_UDP, NULL, &rtp_port);
@@ -287,7 +288,8 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
287 nf_ct_expect_put(rtp_exp); 288 nf_ct_expect_put(rtp_exp);
288 return -1; 289 return -1;
289 } 290 }
290 nf_ct_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num, 291 nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT,
292 ct->tuplehash[!dir].tuple.src.l3num,
291 &ct->tuplehash[!dir].tuple.src.u3, 293 &ct->tuplehash[!dir].tuple.src.u3,
292 &ct->tuplehash[!dir].tuple.dst.u3, 294 &ct->tuplehash[!dir].tuple.dst.u3,
293 IPPROTO_UDP, NULL, &rtcp_port); 295 IPPROTO_UDP, NULL, &rtcp_port);
@@ -344,7 +346,8 @@ static int expect_t120(struct sk_buff *skb,
344 /* Create expect for T.120 connections */ 346 /* Create expect for T.120 connections */
345 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 347 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
346 return -1; 348 return -1;
347 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 349 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
350 ct->tuplehash[!dir].tuple.src.l3num,
348 &ct->tuplehash[!dir].tuple.src.u3, 351 &ct->tuplehash[!dir].tuple.src.u3,
349 &ct->tuplehash[!dir].tuple.dst.u3, 352 &ct->tuplehash[!dir].tuple.dst.u3,
350 IPPROTO_TCP, NULL, &port); 353 IPPROTO_TCP, NULL, &port);
@@ -612,13 +615,17 @@ static int h245_help(struct sk_buff *skb, unsigned int protoff,
612} 615}
613 616
614/****************************************************************************/ 617/****************************************************************************/
618static const struct nf_conntrack_expect_policy h245_exp_policy = {
619 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
620 .timeout = 240,
621};
622
615static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { 623static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
616 .name = "H.245", 624 .name = "H.245",
617 .me = THIS_MODULE, 625 .me = THIS_MODULE,
618 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
619 .timeout = 240,
620 .tuple.dst.protonum = IPPROTO_UDP, 626 .tuple.dst.protonum = IPPROTO_UDP,
621 .help = h245_help 627 .help = h245_help,
628 .expect_policy = &h245_exp_policy,
622}; 629};
623 630
624/****************************************************************************/ 631/****************************************************************************/
@@ -676,7 +683,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
676 /* Create expect for h245 connection */ 683 /* Create expect for h245 connection */
677 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 684 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
678 return -1; 685 return -1;
679 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 686 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
687 ct->tuplehash[!dir].tuple.src.l3num,
680 &ct->tuplehash[!dir].tuple.src.u3, 688 &ct->tuplehash[!dir].tuple.src.u3,
681 &ct->tuplehash[!dir].tuple.dst.u3, 689 &ct->tuplehash[!dir].tuple.dst.u3,
682 IPPROTO_TCP, NULL, &port); 690 IPPROTO_TCP, NULL, &port);
@@ -792,7 +800,8 @@ static int expect_callforwarding(struct sk_buff *skb,
792 /* Create expect for the second call leg */ 800 /* Create expect for the second call leg */
793 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 801 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
794 return -1; 802 return -1;
795 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 803 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
804 ct->tuplehash[!dir].tuple.src.l3num,
796 &ct->tuplehash[!dir].tuple.src.u3, &addr, 805 &ct->tuplehash[!dir].tuple.src.u3, &addr,
797 IPPROTO_TCP, NULL, &port); 806 IPPROTO_TCP, NULL, &port);
798 exp->helper = nf_conntrack_helper_q931; 807 exp->helper = nf_conntrack_helper_q931;
@@ -1156,28 +1165,30 @@ static int q931_help(struct sk_buff *skb, unsigned int protoff,
1156} 1165}
1157 1166
1158/****************************************************************************/ 1167/****************************************************************************/
1168static const struct nf_conntrack_expect_policy q931_exp_policy = {
1169 /* T.120 and H.245 */
1170 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4,
1171 .timeout = 240,
1172};
1173
1159static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { 1174static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
1160 { 1175 {
1161 .name = "Q.931", 1176 .name = "Q.931",
1162 .me = THIS_MODULE, 1177 .me = THIS_MODULE,
1163 /* T.120 and H.245 */
1164 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4,
1165 .timeout = 240,
1166 .tuple.src.l3num = AF_INET, 1178 .tuple.src.l3num = AF_INET,
1167 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1179 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1168 .tuple.dst.protonum = IPPROTO_TCP, 1180 .tuple.dst.protonum = IPPROTO_TCP,
1169 .help = q931_help 1181 .help = q931_help,
1182 .expect_policy = &q931_exp_policy,
1170 }, 1183 },
1171 { 1184 {
1172 .name = "Q.931", 1185 .name = "Q.931",
1173 .me = THIS_MODULE, 1186 .me = THIS_MODULE,
1174 /* T.120 and H.245 */
1175 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4,
1176 .timeout = 240,
1177 .tuple.src.l3num = AF_INET6, 1187 .tuple.src.l3num = AF_INET6,
1178 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1188 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1179 .tuple.dst.protonum = IPPROTO_TCP, 1189 .tuple.dst.protonum = IPPROTO_TCP,
1180 .help = q931_help 1190 .help = q931_help,
1191 .expect_policy = &q931_exp_policy,
1181 }, 1192 },
1182}; 1193};
1183 1194
@@ -1261,7 +1272,8 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct,
1261 /* Create expect for Q.931 */ 1272 /* Create expect for Q.931 */
1262 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1273 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1263 return -1; 1274 return -1;
1264 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1275 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
1276 ct->tuplehash[!dir].tuple.src.l3num,
1265 gkrouted_only ? /* only accept calls from GK? */ 1277 gkrouted_only ? /* only accept calls from GK? */
1266 &ct->tuplehash[!dir].tuple.src.u3 : NULL, 1278 &ct->tuplehash[!dir].tuple.src.u3 : NULL,
1267 &ct->tuplehash[!dir].tuple.dst.u3, 1279 &ct->tuplehash[!dir].tuple.dst.u3,
@@ -1332,7 +1344,8 @@ static int process_gcf(struct sk_buff *skb, struct nf_conn *ct,
1332 /* Need new expect */ 1344 /* Need new expect */
1333 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1345 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1334 return -1; 1346 return -1;
1335 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1347 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
1348 ct->tuplehash[!dir].tuple.src.l3num,
1336 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1349 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1337 IPPROTO_UDP, NULL, &port); 1350 IPPROTO_UDP, NULL, &port);
1338 exp->helper = nf_conntrack_helper_ras; 1351 exp->helper = nf_conntrack_helper_ras;
@@ -1536,7 +1549,8 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct,
1536 /* Need new expect */ 1549 /* Need new expect */
1537 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1550 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1538 return -1; 1551 return -1;
1539 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1552 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
1553 ct->tuplehash[!dir].tuple.src.l3num,
1540 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1554 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1541 IPPROTO_TCP, NULL, &port); 1555 IPPROTO_TCP, NULL, &port);
1542 exp->flags = NF_CT_EXPECT_PERMANENT; 1556 exp->flags = NF_CT_EXPECT_PERMANENT;
@@ -1589,7 +1603,8 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct,
1589 /* Need new expect for call signal */ 1603 /* Need new expect for call signal */
1590 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1604 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1591 return -1; 1605 return -1;
1592 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1606 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
1607 ct->tuplehash[!dir].tuple.src.l3num,
1593 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1608 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1594 IPPROTO_TCP, NULL, &port); 1609 IPPROTO_TCP, NULL, &port);
1595 exp->flags = NF_CT_EXPECT_PERMANENT; 1610 exp->flags = NF_CT_EXPECT_PERMANENT;
@@ -1728,26 +1743,29 @@ static int ras_help(struct sk_buff *skb, unsigned int protoff,
1728} 1743}
1729 1744
1730/****************************************************************************/ 1745/****************************************************************************/
1746static const struct nf_conntrack_expect_policy ras_exp_policy = {
1747 .max_expected = 32,
1748 .timeout = 240,
1749};
1750
1731static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { 1751static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
1732 { 1752 {
1733 .name = "RAS", 1753 .name = "RAS",
1734 .me = THIS_MODULE, 1754 .me = THIS_MODULE,
1735 .max_expected = 32,
1736 .timeout = 240,
1737 .tuple.src.l3num = AF_INET, 1755 .tuple.src.l3num = AF_INET,
1738 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1756 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1739 .tuple.dst.protonum = IPPROTO_UDP, 1757 .tuple.dst.protonum = IPPROTO_UDP,
1740 .help = ras_help, 1758 .help = ras_help,
1759 .expect_policy = &ras_exp_policy,
1741 }, 1760 },
1742 { 1761 {
1743 .name = "RAS", 1762 .name = "RAS",
1744 .me = THIS_MODULE, 1763 .me = THIS_MODULE,
1745 .max_expected = 32,
1746 .timeout = 240,
1747 .tuple.src.l3num = AF_INET6, 1764 .tuple.src.l3num = AF_INET6,
1748 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1765 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1749 .tuple.dst.protonum = IPPROTO_UDP, 1766 .tuple.dst.protonum = IPPROTO_UDP,
1750 .help = ras_help, 1767 .help = ras_help,
1768 .expect_policy = &ras_exp_policy,
1751 }, 1769 },
1752}; 1770};
1753 1771
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index b1fd21cc1dbc..e350f56d43c9 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -110,7 +110,8 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
110{ 110{
111 unsigned int h = helper_hash(&me->tuple); 111 unsigned int h = helper_hash(&me->tuple);
112 112
113 BUG_ON(me->timeout == 0); 113 BUG_ON(me->expect_policy == NULL);
114 BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
114 115
115 mutex_lock(&nf_ct_helper_mutex); 116 mutex_lock(&nf_ct_helper_mutex);
116 hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]); 117 hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index c336b07a0d4c..02f21cbe5ae7 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -187,7 +187,8 @@ static int help(struct sk_buff *skb, unsigned int protoff,
187 } 187 }
188 tuple = &ct->tuplehash[!dir].tuple; 188 tuple = &ct->tuplehash[!dir].tuple;
189 port = htons(dcc_port); 189 port = htons(dcc_port);
190 nf_ct_expect_init(exp, tuple->src.l3num, 190 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
191 tuple->src.l3num,
191 NULL, &tuple->dst.u3, 192 NULL, &tuple->dst.u3,
192 IPPROTO_TCP, NULL, &port); 193 IPPROTO_TCP, NULL, &port);
193 194
@@ -210,6 +211,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
210 211
211static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly; 212static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly;
212static char irc_names[MAX_PORTS][sizeof("irc-65535")] __read_mostly; 213static char irc_names[MAX_PORTS][sizeof("irc-65535")] __read_mostly;
214static struct nf_conntrack_expect_policy irc_exp_policy;
213 215
214static void nf_conntrack_irc_fini(void); 216static void nf_conntrack_irc_fini(void);
215 217
@@ -223,6 +225,9 @@ static int __init nf_conntrack_irc_init(void)
223 return -EINVAL; 225 return -EINVAL;
224 } 226 }
225 227
228 irc_exp_policy.max_expected = max_dcc_channels;
229 irc_exp_policy.timeout = dcc_timeout;
230
226 irc_buffer = kmalloc(65536, GFP_KERNEL); 231 irc_buffer = kmalloc(65536, GFP_KERNEL);
227 if (!irc_buffer) 232 if (!irc_buffer)
228 return -ENOMEM; 233 return -ENOMEM;
@@ -235,8 +240,7 @@ static int __init nf_conntrack_irc_init(void)
235 irc[i].tuple.src.l3num = AF_INET; 240 irc[i].tuple.src.l3num = AF_INET;
236 irc[i].tuple.src.u.tcp.port = htons(ports[i]); 241 irc[i].tuple.src.u.tcp.port = htons(ports[i]);
237 irc[i].tuple.dst.protonum = IPPROTO_TCP; 242 irc[i].tuple.dst.protonum = IPPROTO_TCP;
238 irc[i].max_expected = max_dcc_channels; 243 irc[i].expect_policy = &irc_exp_policy;
239 irc[i].timeout = dcc_timeout;
240 irc[i].me = THIS_MODULE; 244 irc[i].me = THIS_MODULE;
241 irc[i].help = help; 245 irc[i].help = help;
242 246
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 60dedaded84e..08404e6755fb 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -86,6 +86,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
86 86
87 exp->expectfn = NULL; 87 exp->expectfn = NULL;
88 exp->flags = NF_CT_EXPECT_PERMANENT; 88 exp->flags = NF_CT_EXPECT_PERMANENT;
89 exp->class = NF_CT_EXPECT_CLASS_DEFAULT;
89 exp->helper = NULL; 90 exp->helper = NULL;
90 91
91 nf_ct_expect_related(exp); 92 nf_ct_expect_related(exp);
@@ -96,19 +97,23 @@ out:
96 return NF_ACCEPT; 97 return NF_ACCEPT;
97} 98}
98 99
100static struct nf_conntrack_expect_policy exp_policy = {
101 .max_expected = 1,
102};
103
99static struct nf_conntrack_helper helper __read_mostly = { 104static struct nf_conntrack_helper helper __read_mostly = {
100 .name = "netbios-ns", 105 .name = "netbios-ns",
101 .tuple.src.l3num = AF_INET, 106 .tuple.src.l3num = AF_INET,
102 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT), 107 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT),
103 .tuple.dst.protonum = IPPROTO_UDP, 108 .tuple.dst.protonum = IPPROTO_UDP,
104 .max_expected = 1,
105 .me = THIS_MODULE, 109 .me = THIS_MODULE,
106 .help = help, 110 .help = help,
111 .expect_policy = &exp_policy,
107}; 112};
108 113
109static int __init nf_conntrack_netbios_ns_init(void) 114static int __init nf_conntrack_netbios_ns_init(void)
110{ 115{
111 helper.timeout = timeout; 116 exp_policy.timeout = timeout;
112 return nf_conntrack_helper_register(&helper); 117 return nf_conntrack_helper_register(&helper);
113} 118}
114 119
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index b5cb8e831230..8fd83470d1b3 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -208,7 +208,8 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
208 208
209 /* original direction, PNS->PAC */ 209 /* original direction, PNS->PAC */
210 dir = IP_CT_DIR_ORIGINAL; 210 dir = IP_CT_DIR_ORIGINAL;
211 nf_ct_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num, 211 nf_ct_expect_init(exp_orig, NF_CT_EXPECT_CLASS_DEFAULT,
212 ct->tuplehash[dir].tuple.src.l3num,
212 &ct->tuplehash[dir].tuple.src.u3, 213 &ct->tuplehash[dir].tuple.src.u3,
213 &ct->tuplehash[dir].tuple.dst.u3, 214 &ct->tuplehash[dir].tuple.dst.u3,
214 IPPROTO_GRE, &peer_callid, &callid); 215 IPPROTO_GRE, &peer_callid, &callid);
@@ -216,7 +217,8 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
216 217
217 /* reply direction, PAC->PNS */ 218 /* reply direction, PAC->PNS */
218 dir = IP_CT_DIR_REPLY; 219 dir = IP_CT_DIR_REPLY;
219 nf_ct_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num, 220 nf_ct_expect_init(exp_reply, NF_CT_EXPECT_CLASS_DEFAULT,
221 ct->tuplehash[dir].tuple.src.l3num,
220 &ct->tuplehash[dir].tuple.src.u3, 222 &ct->tuplehash[dir].tuple.src.u3,
221 &ct->tuplehash[dir].tuple.dst.u3, 223 &ct->tuplehash[dir].tuple.dst.u3,
222 IPPROTO_GRE, &callid, &peer_callid); 224 IPPROTO_GRE, &callid, &peer_callid);
@@ -575,17 +577,21 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
575 return ret; 577 return ret;
576} 578}
577 579
580static const struct nf_conntrack_expect_policy pptp_exp_policy = {
581 .max_expected = 2,
582 .timeout = 5 * 60,
583};
584
578/* control protocol helper */ 585/* control protocol helper */
579static struct nf_conntrack_helper pptp __read_mostly = { 586static struct nf_conntrack_helper pptp __read_mostly = {
580 .name = "pptp", 587 .name = "pptp",
581 .me = THIS_MODULE, 588 .me = THIS_MODULE,
582 .max_expected = 2,
583 .timeout = 5 * 60,
584 .tuple.src.l3num = AF_INET, 589 .tuple.src.l3num = AF_INET,
585 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT), 590 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT),
586 .tuple.dst.protonum = IPPROTO_TCP, 591 .tuple.dst.protonum = IPPROTO_TCP,
587 .help = conntrack_pptp_help, 592 .help = conntrack_pptp_help,
588 .destroy = pptp_destroy_siblings, 593 .destroy = pptp_destroy_siblings,
594 .expect_policy = &pptp_exp_policy,
589}; 595};
590 596
591static int __init nf_conntrack_pptp_init(void) 597static int __init nf_conntrack_pptp_init(void)
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index a70051d741a7..7542e25eede3 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -143,7 +143,8 @@ static int help(struct sk_buff *skb,
143 } 143 }
144 144
145 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 145 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
146 nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3, 146 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family,
147 &tuple->src.u3, &tuple->dst.u3,
147 IPPROTO_TCP, NULL, &reply->port); 148 IPPROTO_TCP, NULL, &reply->port);
148 149
149 pr_debug("nf_ct_sane: expect: "); 150 pr_debug("nf_ct_sane: expect: ");
@@ -163,6 +164,11 @@ out:
163static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly; 164static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly;
164static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly; 165static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly;
165 166
167static const struct nf_conntrack_expect_policy sane_exp_policy = {
168 .max_expected = 1,
169 .timeout = 5 * 60,
170};
171
166/* don't make this __exit, since it's called from __init ! */ 172/* don't make this __exit, since it's called from __init ! */
167static void nf_conntrack_sane_fini(void) 173static void nf_conntrack_sane_fini(void)
168{ 174{
@@ -200,8 +206,7 @@ static int __init nf_conntrack_sane_init(void)
200 for (j = 0; j < 2; j++) { 206 for (j = 0; j < 2; j++) {
201 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); 207 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
202 sane[i][j].tuple.dst.protonum = IPPROTO_TCP; 208 sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
203 sane[i][j].max_expected = 1; 209 sane[i][j].expect_policy = &sane_exp_policy;
204 sane[i][j].timeout = 5 * 60; /* 5 Minutes */
205 sane[i][j].me = THIS_MODULE; 210 sane[i][j].me = THIS_MODULE;
206 sane[i][j].help = help; 211 sane[i][j].help = help;
207 tmpname = &sane_names[i][j][0]; 212 tmpname = &sane_names[i][j][0];
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index c521c891d351..0021d5b60cec 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -380,7 +380,7 @@ static int set_expected_rtp(struct sk_buff *skb,
380 exp = nf_ct_expect_alloc(ct); 380 exp = nf_ct_expect_alloc(ct);
381 if (exp == NULL) 381 if (exp == NULL)
382 return NF_DROP; 382 return NF_DROP;
383 nf_ct_expect_init(exp, family, 383 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family,
384 &ct->tuplehash[!dir].tuple.src.u3, addr, 384 &ct->tuplehash[!dir].tuple.src.u3, addr,
385 IPPROTO_UDP, NULL, &port); 385 IPPROTO_UDP, NULL, &port);
386 386
@@ -476,6 +476,11 @@ out:
476static struct nf_conntrack_helper sip[MAX_PORTS][2] __read_mostly; 476static struct nf_conntrack_helper sip[MAX_PORTS][2] __read_mostly;
477static char sip_names[MAX_PORTS][2][sizeof("sip-65535")] __read_mostly; 477static char sip_names[MAX_PORTS][2][sizeof("sip-65535")] __read_mostly;
478 478
479static const struct nf_conntrack_expect_policy sip_exp_policy = {
480 .max_expected = 2,
481 .timeout = 3 * 60,
482};
483
479static void nf_conntrack_sip_fini(void) 484static void nf_conntrack_sip_fini(void)
480{ 485{
481 int i, j; 486 int i, j;
@@ -505,8 +510,7 @@ static int __init nf_conntrack_sip_init(void)
505 for (j = 0; j < 2; j++) { 510 for (j = 0; j < 2; j++) {
506 sip[i][j].tuple.dst.protonum = IPPROTO_UDP; 511 sip[i][j].tuple.dst.protonum = IPPROTO_UDP;
507 sip[i][j].tuple.src.u.udp.port = htons(ports[i]); 512 sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
508 sip[i][j].max_expected = 2; 513 sip[i][j].expect_policy = &sip_exp_policy;
509 sip[i][j].timeout = 3 * 60; /* 3 minutes */
510 sip[i][j].me = THIS_MODULE; 514 sip[i][j].me = THIS_MODULE;
511 sip[i][j].help = sip_help; 515 sip[i][j].help = sip_help;
512 516
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index bd2e800f23cc..a28341b30f21 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -63,7 +63,8 @@ static int tftp_help(struct sk_buff *skb,
63 if (exp == NULL) 63 if (exp == NULL)
64 return NF_DROP; 64 return NF_DROP;
65 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; 65 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
66 nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3, 66 nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family,
67 &tuple->src.u3, &tuple->dst.u3,
67 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port); 68 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);
68 69
69 pr_debug("expect: "); 70 pr_debug("expect: ");
@@ -92,6 +93,11 @@ static int tftp_help(struct sk_buff *skb,
92static struct nf_conntrack_helper tftp[MAX_PORTS][2] __read_mostly; 93static struct nf_conntrack_helper tftp[MAX_PORTS][2] __read_mostly;
93static char tftp_names[MAX_PORTS][2][sizeof("tftp-65535")] __read_mostly; 94static char tftp_names[MAX_PORTS][2][sizeof("tftp-65535")] __read_mostly;
94 95
96static const struct nf_conntrack_expect_policy tftp_exp_policy = {
97 .max_expected = 1,
98 .timeout = 5 * 60,
99};
100
95static void nf_conntrack_tftp_fini(void) 101static void nf_conntrack_tftp_fini(void)
96{ 102{
97 int i, j; 103 int i, j;
@@ -118,8 +124,7 @@ static int __init nf_conntrack_tftp_init(void)
118 for (j = 0; j < 2; j++) { 124 for (j = 0; j < 2; j++) {
119 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP; 125 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP;
120 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]); 126 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]);
121 tftp[i][j].max_expected = 1; 127 tftp[i][j].expect_policy = &tftp_exp_policy;
122 tftp[i][j].timeout = 5 * 60; /* 5 minutes */
123 tftp[i][j].me = THIS_MODULE; 128 tftp[i][j].me = THIS_MODULE;
124 tftp[i][j].help = tftp_help; 129 tftp[i][j].help = tftp_help;
125 130