Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Patrick McHardy and committed by
David S. Miller
6002f266 359b9ab6

+166 -77
+4 -1
include/net/netfilter/nf_conntrack.h
··· 75 75 76 76 struct nf_conntrack_helper; 77 77 78 + /* Must be kept in sync with the classes defined by helpers */ 79 + #define NF_CT_MAX_EXPECT_CLASSES 1 80 + 78 81 /* nf_conn feature for connections that have a helper */ 79 82 struct nf_conn_help { 80 83 /* Helper. if any */ ··· 88 85 struct hlist_head expectations; 89 86 90 87 /* Current number of expected connections */ 91 - unsigned int expecting; 88 + u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; 92 89 }; 93 90 94 91
+12 -1
include/net/netfilter/nf_conntrack_expect.h
··· 41 41 /* Flags */ 42 42 unsigned int flags; 43 43 44 + /* Expectation class */ 45 + unsigned int class; 46 + 44 47 #ifdef CONFIG_NF_NAT_NEEDED 45 48 __be32 saved_ip; 46 49 /* This is the original per-proto part, used to map the ··· 55 52 56 53 struct rcu_head rcu; 57 54 }; 55 + 56 + struct nf_conntrack_expect_policy 57 + { 58 + unsigned int max_expected; 59 + unsigned int timeout; 60 + }; 61 + 62 + #define NF_CT_EXPECT_CLASS_DEFAULT 0 58 63 59 64 #define NF_CT_EXPECT_PERMANENT 0x1 60 65 #define NF_CT_EXPECT_INACTIVE 0x2 ··· 86 75 /* Allocate space for an expectation: this is mandatory before calling 87 76 nf_ct_expect_related. You will have to call put afterwards. */ 88 77 struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me); 89 - void nf_ct_expect_init(struct nf_conntrack_expect *, int, 78 + void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, int, 90 79 const union nf_inet_addr *, 91 80 const union nf_inet_addr *, 92 81 u_int8_t, const __be16 *, const __be16 *);
+2 -3
include/net/netfilter/nf_conntrack_helper.h
··· 20 20 21 21 const char *name; /* name of the module */ 22 22 struct module *me; /* pointer to self */ 23 - unsigned int max_expected; /* Maximum number of concurrent 24 - * expected connections */ 25 - unsigned int timeout; /* timeout for expecteds */ 23 + const struct nf_conntrack_expect_policy *expect_policy; 26 24 27 25 /* Tuple of things we will help (compared against server response) */ 28 26 struct nf_conntrack_tuple tuple; ··· 35 37 void (*destroy)(struct nf_conn *ct); 36 38 37 39 int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct); 40 + unsigned int expect_class_max; 38 41 }; 39 42 40 43 extern struct nf_conntrack_helper *
+8 -4
net/ipv4/netfilter/nf_nat_snmp_basic.c
··· 50 50 #include <net/udp.h> 51 51 52 52 #include <net/netfilter/nf_nat.h> 53 + #include <net/netfilter/nf_conntrack_expect.h> 53 54 #include <net/netfilter/nf_conntrack_helper.h> 54 55 #include <net/netfilter/nf_nat_helper.h> 55 56 ··· 1268 1267 return ret; 1269 1268 } 1270 1269 1270 + static const struct nf_conntrack_expect_policy snmp_exp_policy = { 1271 + .max_expected = 0, 1272 + .timeout = 180, 1273 + }; 1274 + 1271 1275 static struct nf_conntrack_helper snmp_helper __read_mostly = { 1272 - .max_expected = 0, 1273 - .timeout = 180, 1274 1276 .me = THIS_MODULE, 1275 1277 .help = help, 1278 + .expect_policy = &snmp_exp_policy, 1276 1279 .name = "snmp", 1277 1280 .tuple.src.l3num = AF_INET, 1278 1281 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT), ··· 1284 1279 }; 1285 1280 1286 1281 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { 1287 - .max_expected = 0, 1288 - .timeout = 180, 1289 1282 .me = THIS_MODULE, 1290 1283 .help = help, 1284 + .expect_policy = &snmp_exp_policy, 1291 1285 .name = "snmp_trap", 1292 1286 .tuple.src.l3num = AF_INET, 1293 1287 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),
+9 -5
net/netfilter/nf_conntrack_amanda.c
··· 148 148 goto out; 149 149 } 150 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 153 IPPROTO_TCP, NULL, &port); 153 154 154 155 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook); ··· 165 164 return ret; 166 165 } 167 166 167 + static const struct nf_conntrack_expect_policy amanda_exp_policy = { 168 + .max_expected = 3, 169 + .timeout = 180, 170 + }; 171 + 168 172 static struct nf_conntrack_helper amanda_helper[2] __read_mostly = { 169 173 { 170 174 .name = "amanda", 171 - .max_expected = 3, 172 - .timeout = 180, 173 175 .me = THIS_MODULE, 174 176 .help = amanda_help, 175 177 .tuple.src.l3num = AF_INET, 176 178 .tuple.src.u.udp.port = __constant_htons(10080), 177 179 .tuple.dst.protonum = IPPROTO_UDP, 180 + .expect_policy = &amanda_exp_policy, 178 181 }, 179 182 { 180 183 .name = "amanda", 181 - .max_expected = 3, 182 - .timeout = 180, 183 184 .me = THIS_MODULE, 184 185 .help = amanda_help, 185 186 .tuple.src.l3num = AF_INET6, 186 187 .tuple.src.u.udp.port = __constant_htons(10080), 187 188 .tuple.dst.protonum = IPPROTO_UDP, 189 + .expect_policy = &amanda_exp_policy, 188 190 }, 189 191 }; 190 192
+33 -17
net/netfilter/nf_conntrack_expect.c
··· 54 54 nf_ct_expect_count--; 55 55 56 56 hlist_del(&exp->lnode); 57 - master_help->expecting--; 57 + master_help->expecting[exp->class]--; 58 58 nf_ct_expect_put(exp); 59 59 60 60 NF_CT_STAT_INC(expect_delete); ··· 171 171 struct hlist_node *n, *next; 172 172 173 173 /* Optimization: most connection never expect any others. */ 174 - if (!help || help->expecting == 0) 174 + if (!help) 175 175 return; 176 176 177 177 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) { ··· 205 205 static inline int expect_matches(const struct nf_conntrack_expect *a, 206 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 209 && nf_ct_tuple_equal(&a->tuple, &b->tuple) 210 210 && nf_ct_tuple_mask_equal(&a->mask, &b->mask); 211 211 } ··· 240 240 } 241 241 EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); 242 242 243 - void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family, 243 + void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, 244 + int family, 244 245 const union nf_inet_addr *saddr, 245 246 const union nf_inet_addr *daddr, 246 247 u_int8_t proto, const __be16 *src, const __be16 *dst) ··· 254 253 len = 16; 255 254 256 255 exp->flags = 0; 256 + exp->class = class; 257 257 exp->expectfn = NULL; 258 258 exp->helper = NULL; 259 259 exp->tuple.src.l3num = family; ··· 311 309 static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) 312 310 { 313 311 struct nf_conn_help *master_help = nfct_help(exp->master); 312 + const struct nf_conntrack_expect_policy *p; 314 313 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple); 315 314 316 315 atomic_inc(&exp->use); 317 316 318 317 hlist_add_head(&exp->lnode, &master_help->expectations); 319 - master_help->expecting++; 318 + master_help->expecting[exp->class]++; 320 319 321 320 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); 322 321 nf_ct_expect_count++; 323 322 324 323 setup_timer(&exp->timeout, nf_ct_expectation_timed_out, 325 324 (unsigned long)exp); 326 - exp->timeout.expires = jiffies + master_help->helper->timeout * HZ; 325 + p = &master_help->helper->expect_policy[exp->class]; 326 + exp->timeout.expires = jiffies + p->timeout * HZ; 327 327 add_timer(&exp->timeout); 328 328 329 329 atomic_inc(&exp->use); ··· 333 329 } 334 330 335 331 /* Race with expectations being used means we could have none to find; OK. */ 336 - static void evict_oldest_expect(struct nf_conn *master) 332 + static void evict_oldest_expect(struct nf_conn *master, 333 + struct nf_conntrack_expect *new) 337 334 { 338 335 struct nf_conn_help *master_help = nfct_help(master); 339 - struct nf_conntrack_expect *exp = NULL; 336 + struct nf_conntrack_expect *exp, *last = NULL; 340 337 struct hlist_node *n; 341 338 342 - hlist_for_each_entry(exp, n, &master_help->expectations, lnode) 343 - ; /* nothing */ 339 + hlist_for_each_entry(exp, n, &master_help->expectations, lnode) { 340 + if (exp->class == new->class) 341 + last = exp; 342 + } 344 343 345 - if (exp && del_timer(&exp->timeout)) { 346 - nf_ct_unlink_expect(exp); 347 - nf_ct_expect_put(exp); 344 + if (last && del_timer(&last->timeout)) { 345 + nf_ct_unlink_expect(last); 346 + nf_ct_expect_put(last); 348 347 } 349 348 } 350 349 351 350 static inline int refresh_timer(struct nf_conntrack_expect *i) 352 351 { 353 352 struct nf_conn_help *master_help = nfct_help(i->master); 353 + const struct nf_conntrack_expect_policy *p; 354 354 355 355 if (!del_timer(&i->timeout)) 356 356 return 0; 357 357 358 - i->timeout.expires = jiffies + master_help->helper->timeout*HZ; 358 + p = &master_help->helper->expect_policy[i->class]; 359 + i->timeout.expires = jiffies + p->timeout * HZ; 359 360 add_timer(&i->timeout); 360 361 return 1; 361 362 } 362 363 363 364 int nf_ct_expect_related(struct nf_conntrack_expect *expect) 364 365 { 366 + const struct nf_conntrack_expect_policy *p; 365 367 struct nf_conntrack_expect *i; 366 368 struct nf_conn *master = expect->master; 367 369 struct nf_conn_help *master_help = nfct_help(master); ··· 396 386 } 397 387 } 398 388 /* Will be over limit? */ 399 - if (master_help->helper->max_expected && 400 - master_help->expecting >= master_help->helper->max_expected) 401 - evict_oldest_expect(master); 389 + p = &master_help->helper->expect_policy[expect->class]; 390 + if (p->max_expected && 391 + master_help->expecting[expect->class] >= p->max_expected) { 392 + evict_oldest_expect(master, expect); 393 + if (master_help->expecting[expect->class] >= p->max_expected) { 394 + ret = -EMFILE; 395 + goto out; 396 + } 397 + } 402 398 403 399 if (nf_ct_expect_count >= nf_ct_expect_max) { 404 400 if (net_ratelimit())
+7 -3
net/netfilter/nf_conntrack_ftp.c
··· 483 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 487 &ct->tuplehash[!dir].tuple.src.u3, daddr, 488 488 IPPROTO_TCP, NULL, &cmd.u.tcp.port); 489 489 ··· 516 516 517 517 static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly; 518 518 static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly; 519 + 520 + static const struct nf_conntrack_expect_policy ftp_exp_policy = { 521 + .max_expected = 1, 522 + .timeout = 5 * 60, 523 + }; 519 524 520 525 /* don't make this __exit, since it's called from __init ! */ 521 526 static void nf_conntrack_ftp_fini(void) ··· 561 556 for (j = 0; j < 2; j++) { 562 557 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); 563 558 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; 564 - ftp[i][j].max_expected = 1; 565 - ftp[i][j].timeout = 5 * 60; /* 5 Minutes */ 559 + ftp[i][j].expect_policy = &ftp_exp_policy; 566 560 ftp[i][j].me = THIS_MODULE; 567 561 ftp[i][j].help = help; 568 562 tmpname = &ftp_names[i][j][0];
+42 -24
net/netfilter/nf_conntrack_h323_main.c
··· 277 277 /* Create expect for RTP */ 278 278 if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL) 279 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 282 &ct->tuplehash[!dir].tuple.src.u3, 282 283 &ct->tuplehash[!dir].tuple.dst.u3, 283 284 IPPROTO_UDP, NULL, &rtp_port); ··· 288 287 nf_ct_expect_put(rtp_exp); 289 288 return -1; 290 289 } 291 - nf_ct_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num, 290 + nf_ct_expect_init(rtcp_exp, NF_CT_EXPECT_CLASS_DEFAULT, 291 + ct->tuplehash[!dir].tuple.src.l3num, 292 292 &ct->tuplehash[!dir].tuple.src.u3, 293 293 &ct->tuplehash[!dir].tuple.dst.u3, 294 294 IPPROTO_UDP, NULL, &rtcp_port); ··· 346 344 /* Create expect for T.120 connections */ 347 345 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 348 346 return -1; 349 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 347 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 348 + ct->tuplehash[!dir].tuple.src.l3num, 350 349 &ct->tuplehash[!dir].tuple.src.u3, 351 350 &ct->tuplehash[!dir].tuple.dst.u3, 352 351 IPPROTO_TCP, NULL, &port); ··· 615 612 } 616 613 617 614 /****************************************************************************/ 615 + static const struct nf_conntrack_expect_policy h245_exp_policy = { 616 + .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */, 617 + .timeout = 240, 618 + }; 619 + 618 620 static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { 619 621 .name = "H.245", 620 622 .me = THIS_MODULE, 621 - .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */, 622 - .timeout = 240, 623 623 .tuple.dst.protonum = IPPROTO_UDP, 624 - .help = h245_help 624 + .help = h245_help, 625 + .expect_policy = &h245_exp_policy, 625 626 }; 626 627 627 628 /****************************************************************************/ ··· 683 676 /* Create expect for h245 connection */ 684 677 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 685 678 return -1; 686 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 679 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 680 + ct->tuplehash[!dir].tuple.src.l3num, 687 681 &ct->tuplehash[!dir].tuple.src.u3, 688 682 &ct->tuplehash[!dir].tuple.dst.u3, 689 683 IPPROTO_TCP, NULL, &port); ··· 800 792 /* Create expect for the second call leg */ 801 793 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 802 794 return -1; 803 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 795 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 796 + ct->tuplehash[!dir].tuple.src.l3num, 804 797 &ct->tuplehash[!dir].tuple.src.u3, &addr, 805 798 IPPROTO_TCP, NULL, &port); 806 799 exp->helper = nf_conntrack_helper_q931; ··· 1165 1156 } 1166 1157 1167 1158 /****************************************************************************/ 1159 + static const struct nf_conntrack_expect_policy q931_exp_policy = { 1160 + /* T.120 and H.245 */ 1161 + .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4, 1162 + .timeout = 240, 1163 + }; 1164 + 1168 1165 static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { 1169 1166 { 1170 1167 .name = "Q.931", 1171 1168 .me = THIS_MODULE, 1172 - /* T.120 and H.245 */ 1173 - .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4, 1174 - .timeout = 240, 1175 1169 .tuple.src.l3num = AF_INET, 1176 1170 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1177 1171 .tuple.dst.protonum = IPPROTO_TCP, 1178 - .help = q931_help 1172 + .help = q931_help, 1173 + .expect_policy = &q931_exp_policy, 1179 1174 }, 1180 1175 { 1181 1176 .name = "Q.931", 1182 1177 .me = THIS_MODULE, 1183 - /* T.120 and H.245 */ 1184 - .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4, 1185 - .timeout = 240, 1186 1178 .tuple.src.l3num = AF_INET6, 1187 1179 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1188 1180 .tuple.dst.protonum = IPPROTO_TCP, 1189 - .help = q931_help 1181 + .help = q931_help, 1182 + .expect_policy = &q931_exp_policy, 1190 1183 }, 1191 1184 }; 1192 1185 ··· 1272 1261 /* Create expect for Q.931 */ 1273 1262 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1274 1263 return -1; 1275 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1264 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1265 + ct->tuplehash[!dir].tuple.src.l3num, 1276 1266 gkrouted_only ? /* only accept calls from GK? */ 1277 1267 &ct->tuplehash[!dir].tuple.src.u3 : NULL, 1278 1268 &ct->tuplehash[!dir].tuple.dst.u3, ··· 1344 1332 /* Need new expect */ 1345 1333 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1346 1334 return -1; 1347 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1335 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1336 + ct->tuplehash[!dir].tuple.src.l3num, 1348 1337 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1349 1338 IPPROTO_UDP, NULL, &port); 1350 1339 exp->helper = nf_conntrack_helper_ras; ··· 1549 1536 /* Need new expect */ 1550 1537 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1551 1538 return -1; 1552 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1539 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1540 + ct->tuplehash[!dir].tuple.src.l3num, 1553 1541 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1554 1542 IPPROTO_TCP, NULL, &port); 1555 1543 exp->flags = NF_CT_EXPECT_PERMANENT; ··· 1603 1589 /* Need new expect for call signal */ 1604 1590 if ((exp = nf_ct_expect_alloc(ct)) == NULL) 1605 1591 return -1; 1606 - nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1592 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, 1593 + ct->tuplehash[!dir].tuple.src.l3num, 1607 1594 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1608 1595 IPPROTO_TCP, NULL, &port); 1609 1596 exp->flags = NF_CT_EXPECT_PERMANENT; ··· 1743 1728 } 1744 1729 1745 1730 /****************************************************************************/ 1731 + static const struct nf_conntrack_expect_policy ras_exp_policy = { 1732 + .max_expected = 32, 1733 + .timeout = 240, 1734 + }; 1735 + 1746 1736 static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = { 1747 1737 { 1748 1738 .name = "RAS", 1749 1739 .me = THIS_MODULE, 1750 - .max_expected = 32, 1751 - .timeout = 240, 1752 1740 .tuple.src.l3num = AF_INET, 1753 1741 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1754 1742 .tuple.dst.protonum = IPPROTO_UDP, 1755 1743 .help = ras_help, 1744 + .expect_policy = &ras_exp_policy, 1756 1745 }, 1757 1746 { 1758 1747 .name = "RAS", 1759 1748 .me = THIS_MODULE, 1760 - .max_expected = 32, 1761 - .timeout = 240, 1762 1749 .tuple.src.l3num = AF_INET6, 1763 1750 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1764 1751 .tuple.dst.protonum = IPPROTO_UDP, 1765 1752 .help = ras_help, 1753 + .expect_policy = &ras_exp_policy, 1766 1754 }, 1767 1755 }; 1768 1756
+2 -1
net/netfilter/nf_conntrack_helper.c
··· 110 110 { 111 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 116 mutex_lock(&nf_ct_helper_mutex); 116 117 hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
+7 -3
net/netfilter/nf_conntrack_irc.c
··· 187 187 } 188 188 tuple = &ct->tuplehash[!dir].tuple; 189 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 192 NULL, &tuple->dst.u3, 192 193 IPPROTO_TCP, NULL, &port); 193 194 ··· 211 210 212 211 static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly; 213 212 static char irc_names[MAX_PORTS][sizeof("irc-65535")] __read_mostly; 213 + static struct nf_conntrack_expect_policy irc_exp_policy; 214 214 215 215 static void nf_conntrack_irc_fini(void); 216 216 ··· 225 223 return -EINVAL; 226 224 } 227 225 226 + irc_exp_policy.max_expected = max_dcc_channels; 227 + irc_exp_policy.timeout = dcc_timeout; 228 + 228 229 irc_buffer = kmalloc(65536, GFP_KERNEL); 229 230 if (!irc_buffer) 230 231 return -ENOMEM; ··· 240 235 irc[i].tuple.src.l3num = AF_INET; 241 236 irc[i].tuple.src.u.tcp.port = htons(ports[i]); 242 237 irc[i].tuple.dst.protonum = IPPROTO_TCP; 243 - irc[i].max_expected = max_dcc_channels; 244 - irc[i].timeout = dcc_timeout; 238 + irc[i].expect_policy = &irc_exp_policy; 245 239 irc[i].me = THIS_MODULE; 246 240 irc[i].help = help; 247 241
+7 -2
net/netfilter/nf_conntrack_netbios_ns.c
··· 86 86 87 87 exp->expectfn = NULL; 88 88 exp->flags = NF_CT_EXPECT_PERMANENT; 89 + exp->class = NF_CT_EXPECT_CLASS_DEFAULT; 89 90 exp->helper = NULL; 90 91 91 92 nf_ct_expect_related(exp); ··· 97 96 return NF_ACCEPT; 98 97 } 99 98 99 + static struct nf_conntrack_expect_policy exp_policy = { 100 + .max_expected = 1, 101 + }; 102 + 100 103 static struct nf_conntrack_helper helper __read_mostly = { 101 104 .name = "netbios-ns", 102 105 .tuple.src.l3num = AF_INET, 103 106 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT), 104 107 .tuple.dst.protonum = IPPROTO_UDP, 105 - .max_expected = 1, 106 108 .me = THIS_MODULE, 107 109 .help = help, 110 + .expect_policy = &exp_policy, 108 111 }; 109 112 110 113 static int __init nf_conntrack_netbios_ns_init(void) 111 114 { 112 - helper.timeout = timeout; 115 + exp_policy.timeout = timeout; 113 116 return nf_conntrack_helper_register(&helper); 114 117 } 115 118
+10 -4
net/netfilter/nf_conntrack_pptp.c
··· 208 208 209 209 /* original direction, PNS->PAC */ 210 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 213 &ct->tuplehash[dir].tuple.src.u3, 213 214 &ct->tuplehash[dir].tuple.dst.u3, 214 215 IPPROTO_GRE, &peer_callid, &callid); ··· 217 216 218 217 /* reply direction, PAC->PNS */ 219 218 dir = IP_CT_DIR_REPLY; 220 - nf_ct_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num, 219 + nf_ct_expect_init(exp_reply, NF_CT_EXPECT_CLASS_DEFAULT, 220 + ct->tuplehash[dir].tuple.src.l3num, 221 221 &ct->tuplehash[dir].tuple.src.u3, 222 222 &ct->tuplehash[dir].tuple.dst.u3, 223 223 IPPROTO_GRE, &callid, &peer_callid); ··· 577 575 return ret; 578 576 } 579 577 578 + static const struct nf_conntrack_expect_policy pptp_exp_policy = { 579 + .max_expected = 2, 580 + .timeout = 5 * 60, 581 + }; 582 + 580 583 /* control protocol helper */ 581 584 static struct nf_conntrack_helper pptp __read_mostly = { 582 585 .name = "pptp", 583 586 .me = THIS_MODULE, 584 - .max_expected = 2, 585 - .timeout = 5 * 60, 586 587 .tuple.src.l3num = AF_INET, 587 588 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT), 588 589 .tuple.dst.protonum = IPPROTO_TCP, 589 590 .help = conntrack_pptp_help, 590 591 .destroy = pptp_destroy_siblings, 592 + .expect_policy = &pptp_exp_policy, 591 593 }; 592 594 593 595 static int __init nf_conntrack_pptp_init(void)
+8 -3
net/netfilter/nf_conntrack_sane.c
··· 143 143 } 144 144 145 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 148 IPPROTO_TCP, NULL, &reply->port); 148 149 149 150 pr_debug("nf_ct_sane: expect: "); ··· 163 162 164 163 static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly; 165 164 static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly; 165 + 166 + static const struct nf_conntrack_expect_policy sane_exp_policy = { 167 + .max_expected = 1, 168 + .timeout = 5 * 60, 169 + }; 166 170 167 171 /* don't make this __exit, since it's called from __init ! */ 168 172 static void nf_conntrack_sane_fini(void) ··· 206 200 for (j = 0; j < 2; j++) { 207 201 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); 208 202 sane[i][j].tuple.dst.protonum = IPPROTO_TCP; 209 - sane[i][j].max_expected = 1; 210 - sane[i][j].timeout = 5 * 60; /* 5 Minutes */ 203 + sane[i][j].expect_policy = &sane_exp_policy; 211 204 sane[i][j].me = THIS_MODULE; 212 205 sane[i][j].help = help; 213 206 tmpname = &sane_names[i][j][0];
+7 -3
net/netfilter/nf_conntrack_sip.c
··· 380 380 exp = nf_ct_expect_alloc(ct); 381 381 if (exp == NULL) 382 382 return NF_DROP; 383 - nf_ct_expect_init(exp, family, 383 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, family, 384 384 &ct->tuplehash[!dir].tuple.src.u3, addr, 385 385 IPPROTO_UDP, NULL, &port); 386 386 ··· 476 476 static struct nf_conntrack_helper sip[MAX_PORTS][2] __read_mostly; 477 477 static char sip_names[MAX_PORTS][2][sizeof("sip-65535")] __read_mostly; 478 478 479 + static const struct nf_conntrack_expect_policy sip_exp_policy = { 480 + .max_expected = 2, 481 + .timeout = 3 * 60, 482 + }; 483 + 479 484 static void nf_conntrack_sip_fini(void) 480 485 { 481 486 int i, j; ··· 510 505 for (j = 0; j < 2; j++) { 511 506 sip[i][j].tuple.dst.protonum = IPPROTO_UDP; 512 507 sip[i][j].tuple.src.u.udp.port = htons(ports[i]); 513 - sip[i][j].max_expected = 2; 514 - sip[i][j].timeout = 3 * 60; /* 3 minutes */ 508 + sip[i][j].expect_policy = &sip_exp_policy; 515 509 sip[i][j].me = THIS_MODULE; 516 510 sip[i][j].help = sip_help; 517 511
+8 -3
net/netfilter/nf_conntrack_tftp.c
··· 63 63 if (exp == NULL) 64 64 return NF_DROP; 65 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 68 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port); 68 69 69 70 pr_debug("expect: "); ··· 93 92 static struct nf_conntrack_helper tftp[MAX_PORTS][2] __read_mostly; 94 93 static char tftp_names[MAX_PORTS][2][sizeof("tftp-65535")] __read_mostly; 95 94 95 + static const struct nf_conntrack_expect_policy tftp_exp_policy = { 96 + .max_expected = 1, 97 + .timeout = 5 * 60, 98 + }; 99 + 96 100 static void nf_conntrack_tftp_fini(void) 97 101 { 98 102 int i, j; ··· 124 118 for (j = 0; j < 2; j++) { 125 119 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP; 126 120 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]); 127 - tftp[i][j].max_expected = 1; 128 - tftp[i][j].timeout = 5 * 60; /* 5 minutes */ 121 + tftp[i][j].expect_policy = &tftp_exp_policy; 129 122 tftp[i][j].me = THIS_MODULE; 130 123 tftp[i][j].help = tftp_help; 131 124