Commit c779e849608a875448f6ffc2a5c2a15523bdcd00

Authored by Florian Westphal
Committed by Pablo Neira Ayuso
1 parent 97e08caec3

netfilter: conntrack: remove get_timeout() indirection

Not needed, we can have the l4trackers fetch it themselvs.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 12 changed files with 94 additions and 104 deletions Side-by-side Diff

include/net/netfilter/nf_conntrack_l4proto.h
... ... @@ -45,13 +45,12 @@
45 45 int (*packet)(struct nf_conn *ct,
46 46 const struct sk_buff *skb,
47 47 unsigned int dataoff,
48   - enum ip_conntrack_info ctinfo,
49   - unsigned int *timeouts);
  48 + enum ip_conntrack_info ctinfo);
50 49  
51 50 /* Called when a new connection for this protocol found;
52 51 * returns TRUE if it's OK. If so, packet() called next. */
53 52 bool (*new)(struct nf_conn *ct, const struct sk_buff *skb,
54   - unsigned int dataoff, unsigned int *timeouts);
  53 + unsigned int dataoff);
55 54  
56 55 /* Called when a conntrack entry is destroyed */
57 56 void (*destroy)(struct nf_conn *ct);
... ... @@ -62,9 +61,6 @@
62 61  
63 62 /* called by gc worker if table is full */
64 63 bool (*can_early_drop)(const struct nf_conn *ct);
65   -
66   - /* Return the array of timeouts for this protocol. */
67   - unsigned int *(*get_timeouts)(struct net *net);
68 64  
69 65 /* convert protoinfo to nfnetink attributes */
70 66 int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
include/net/netfilter/nf_conntrack_timeout.h
... ... @@ -67,27 +67,17 @@
67 67 #endif
68 68 };
69 69  
70   -static inline unsigned int *
71   -nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct,
72   - const struct nf_conntrack_l4proto *l4proto)
  70 +static inline unsigned int *nf_ct_timeout_lookup(const struct nf_conn *ct)
73 71 {
  72 + unsigned int *timeouts = NULL;
74 73 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
75 74 struct nf_conn_timeout *timeout_ext;
76   - unsigned int *timeouts;
77 75  
78 76 timeout_ext = nf_ct_timeout_find(ct);
79   - if (timeout_ext) {
  77 + if (timeout_ext)
80 78 timeouts = nf_ct_timeout_data(timeout_ext);
81   - if (unlikely(!timeouts))
82   - timeouts = l4proto->get_timeouts(net);
83   - } else {
84   - timeouts = l4proto->get_timeouts(net);
85   - }
86   -
87   - return timeouts;
88   -#else
89   - return l4proto->get_timeouts(net);
90 79 #endif
  80 + return timeouts;
91 81 }
92 82  
93 83 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
... ... @@ -19,6 +19,7 @@
19 19 #include <net/netfilter/nf_conntrack_tuple.h>
20 20 #include <net/netfilter/nf_conntrack_l4proto.h>
21 21 #include <net/netfilter/nf_conntrack_core.h>
  22 +#include <net/netfilter/nf_conntrack_timeout.h>
22 23 #include <net/netfilter/nf_conntrack_zones.h>
23 24 #include <net/netfilter/nf_log.h>
24 25  
25 26  
... ... @@ -80,12 +81,16 @@
80 81 static int icmp_packet(struct nf_conn *ct,
81 82 const struct sk_buff *skb,
82 83 unsigned int dataoff,
83   - enum ip_conntrack_info ctinfo,
84   - unsigned int *timeout)
  84 + enum ip_conntrack_info ctinfo)
85 85 {
86 86 /* Do not immediately delete the connection after the first
87 87 successful reply to avoid excessive conntrackd traffic
88 88 and also to handle correctly ICMP echo reply duplicates. */
  89 + unsigned int *timeout = nf_ct_timeout_lookup(ct);
  90 +
  91 + if (!timeout)
  92 + timeout = icmp_get_timeouts(nf_ct_net(ct));
  93 +
89 94 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
90 95  
91 96 return NF_ACCEPT;
... ... @@ -93,7 +98,7 @@
93 98  
94 99 /* Called when a new connection for this protocol found. */
95 100 static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
96   - unsigned int dataoff, unsigned int *timeouts)
  101 + unsigned int dataoff)
97 102 {
98 103 static const u_int8_t valid_new[] = {
99 104 [ICMP_ECHO] = 1,
100 105  
... ... @@ -280,9 +285,11 @@
280 285 struct nf_icmp_net *in = icmp_pernet(net);
281 286  
282 287 if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) {
  288 + if (!timeout)
  289 + timeout = &in->timeout;
283 290 *timeout =
284 291 ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMP_TIMEOUT])) * HZ;
285   - } else {
  292 + } else if (timeout) {
286 293 /* Set default ICMP timeout. */
287 294 *timeout = in->timeout;
288 295 }
... ... @@ -357,7 +364,6 @@
357 364 .pkt_to_tuple = icmp_pkt_to_tuple,
358 365 .invert_tuple = icmp_invert_tuple,
359 366 .packet = icmp_packet,
360   - .get_timeouts = icmp_get_timeouts,
361 367 .new = icmp_new,
362 368 .error = icmp_error,
363 369 .destroy = NULL,
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
... ... @@ -23,6 +23,7 @@
23 23 #include <net/netfilter/nf_conntrack_tuple.h>
24 24 #include <net/netfilter/nf_conntrack_l4proto.h>
25 25 #include <net/netfilter/nf_conntrack_core.h>
  26 +#include <net/netfilter/nf_conntrack_timeout.h>
26 27 #include <net/netfilter/nf_conntrack_zones.h>
27 28 #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
28 29 #include <net/netfilter/nf_log.h>
29 30  
... ... @@ -93,9 +94,13 @@
93 94 static int icmpv6_packet(struct nf_conn *ct,
94 95 const struct sk_buff *skb,
95 96 unsigned int dataoff,
96   - enum ip_conntrack_info ctinfo,
97   - unsigned int *timeout)
  97 + enum ip_conntrack_info ctinfo)
98 98 {
  99 + unsigned int *timeout = nf_ct_timeout_lookup(ct);
  100 +
  101 + if (!timeout)
  102 + timeout = icmpv6_get_timeouts(nf_ct_net(ct));
  103 +
99 104 /* Do not immediately delete the connection after the first
100 105 successful reply to avoid excessive conntrackd traffic
101 106 and also to handle correctly ICMP echo reply duplicates. */
... ... @@ -106,7 +111,7 @@
106 111  
107 112 /* Called when a new connection for this protocol found. */
108 113 static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
109   - unsigned int dataoff, unsigned int *timeouts)
  114 + unsigned int dataoff)
110 115 {
111 116 static const u_int8_t valid_new[] = {
112 117 [ICMPV6_ECHO_REQUEST - 128] = 1,
... ... @@ -280,6 +285,8 @@
280 285 unsigned int *timeout = data;
281 286 struct nf_icmp_net *in = icmpv6_pernet(net);
282 287  
  288 + if (!timeout)
  289 + timeout = icmpv6_get_timeouts(net);
283 290 if (tb[CTA_TIMEOUT_ICMPV6_TIMEOUT]) {
284 291 *timeout =
285 292 ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMPV6_TIMEOUT])) * HZ;
... ... @@ -358,7 +365,6 @@
358 365 .pkt_to_tuple = icmpv6_pkt_to_tuple,
359 366 .invert_tuple = icmpv6_invert_tuple,
360 367 .packet = icmpv6_packet,
361   - .get_timeouts = icmpv6_get_timeouts,
362 368 .new = icmpv6_new,
363 369 .error = icmpv6_error,
364 370 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
net/netfilter/nf_conntrack_core.c
... ... @@ -1337,7 +1337,6 @@
1337 1337 const struct nf_conntrack_zone *zone;
1338 1338 struct nf_conn_timeout *timeout_ext;
1339 1339 struct nf_conntrack_zone tmp;
1340   - unsigned int *timeouts;
1341 1340  
1342 1341 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l4proto)) {
1343 1342 pr_debug("Can't invert tuple.\n");
1344 1343  
... ... @@ -1356,15 +1355,8 @@
1356 1355 }
1357 1356  
1358 1357 timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
1359   - if (timeout_ext) {
1360   - timeouts = nf_ct_timeout_data(timeout_ext);
1361   - if (unlikely(!timeouts))
1362   - timeouts = l4proto->get_timeouts(net);
1363   - } else {
1364   - timeouts = l4proto->get_timeouts(net);
1365   - }
1366 1358  
1367   - if (!l4proto->new(ct, skb, dataoff, timeouts)) {
  1359 + if (!l4proto->new(ct, skb, dataoff)) {
1368 1360 nf_conntrack_free(ct);
1369 1361 pr_debug("can't track with proto module\n");
1370 1362 return NULL;
... ... @@ -1493,7 +1485,6 @@
1493 1485 const struct nf_conntrack_l4proto *l4proto;
1494 1486 struct nf_conn *ct, *tmpl;
1495 1487 enum ip_conntrack_info ctinfo;
1496   - unsigned int *timeouts;
1497 1488 u_int8_t protonum;
1498 1489 int dataoff, ret;
1499 1490  
... ... @@ -1552,10 +1543,7 @@
1552 1543 goto out;
1553 1544 }
1554 1545  
1555   - /* Decide what timeout policy we want to apply to this flow. */
1556   - timeouts = nf_ct_timeout_lookup(net, ct, l4proto);
1557   -
1558   - ret = l4proto->packet(ct, skb, dataoff, ctinfo, timeouts);
  1546 + ret = l4proto->packet(ct, skb, dataoff, ctinfo);
1559 1547 if (ret <= 0) {
1560 1548 /* Invalid: inverse of the return code tells
1561 1549 * the netfilter core what to do */
net/netfilter/nf_conntrack_proto_dccp.c
... ... @@ -23,6 +23,7 @@
23 23 #include <net/netfilter/nf_conntrack.h>
24 24 #include <net/netfilter/nf_conntrack_l4proto.h>
25 25 #include <net/netfilter/nf_conntrack_ecache.h>
  26 +#include <net/netfilter/nf_conntrack_timeout.h>
26 27 #include <net/netfilter/nf_log.h>
27 28  
28 29 /* Timeouts are based on values from RFC4340:
... ... @@ -389,7 +390,7 @@
389 390 }
390 391  
391 392 static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
392   - unsigned int dataoff, unsigned int *timeouts)
  393 + unsigned int dataoff)
393 394 {
394 395 struct net *net = nf_ct_net(ct);
395 396 struct nf_dccp_net *dn;
396 397  
397 398  
... ... @@ -437,19 +438,14 @@
437 438 ntohl(dhack->dccph_ack_nr_low);
438 439 }
439 440  
440   -static unsigned int *dccp_get_timeouts(struct net *net)
441   -{
442   - return dccp_pernet(net)->dccp_timeout;
443   -}
444   -
445 441 static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
446   - unsigned int dataoff, enum ip_conntrack_info ctinfo,
447   - unsigned int *timeouts)
  442 + unsigned int dataoff, enum ip_conntrack_info ctinfo)
448 443 {
449 444 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
450 445 struct dccp_hdr _dh, *dh;
451 446 u_int8_t type, old_state, new_state;
452 447 enum ct_dccp_roles role;
  448 + unsigned int *timeouts;
453 449  
454 450 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
455 451 BUG_ON(dh == NULL);
... ... @@ -523,6 +519,9 @@
523 519 if (new_state != old_state)
524 520 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
525 521  
  522 + timeouts = nf_ct_timeout_lookup(ct);
  523 + if (!timeouts)
  524 + timeouts = dccp_pernet(nf_ct_net(ct))->dccp_timeout;
526 525 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
527 526  
528 527 return NF_ACCEPT;
... ... @@ -843,7 +842,6 @@
843 842 .l4proto = IPPROTO_DCCP,
844 843 .new = dccp_new,
845 844 .packet = dccp_packet,
846   - .get_timeouts = dccp_get_timeouts,
847 845 .error = dccp_error,
848 846 .can_early_drop = dccp_can_early_drop,
849 847 #ifdef CONFIG_NF_CONNTRACK_PROCFS
... ... @@ -877,7 +875,6 @@
877 875 .l4proto = IPPROTO_DCCP,
878 876 .new = dccp_new,
879 877 .packet = dccp_packet,
880   - .get_timeouts = dccp_get_timeouts,
881 878 .error = dccp_error,
882 879 .can_early_drop = dccp_can_early_drop,
883 880 #ifdef CONFIG_NF_CONNTRACK_PROCFS
net/netfilter/nf_conntrack_proto_generic.c
... ... @@ -11,6 +11,7 @@
11 11 #include <linux/timer.h>
12 12 #include <linux/netfilter.h>
13 13 #include <net/netfilter/nf_conntrack_l4proto.h>
  14 +#include <net/netfilter/nf_conntrack_timeout.h>
14 15  
15 16 static const unsigned int nf_ct_generic_timeout = 600*HZ;
16 17  
17 18  
18 19  
19 20  
... ... @@ -41,25 +42,24 @@
41 42 return true;
42 43 }
43 44  
44   -static unsigned int *generic_get_timeouts(struct net *net)
45   -{
46   - return &(generic_pernet(net)->timeout);
47   -}
48   -
49 45 /* Returns verdict for packet, or -1 for invalid. */
50 46 static int generic_packet(struct nf_conn *ct,
51 47 const struct sk_buff *skb,
52 48 unsigned int dataoff,
53   - enum ip_conntrack_info ctinfo,
54   - unsigned int *timeout)
  49 + enum ip_conntrack_info ctinfo)
55 50 {
  51 + const unsigned int *timeout = nf_ct_timeout_lookup(ct);
  52 +
  53 + if (!timeout)
  54 + timeout = &generic_pernet(nf_ct_net(ct))->timeout;
  55 +
56 56 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
57 57 return NF_ACCEPT;
58 58 }
59 59  
60 60 /* Called when a new connection for this protocol found. */
61 61 static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
62   - unsigned int dataoff, unsigned int *timeouts)
  62 + unsigned int dataoff)
63 63 {
64 64 bool ret;
65 65  
66 66  
67 67  
... ... @@ -78,9 +78,12 @@
78 78 static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
79 79 struct net *net, void *data)
80 80 {
81   - unsigned int *timeout = data;
82 81 struct nf_generic_net *gn = generic_pernet(net);
  82 + unsigned int *timeout = data;
83 83  
  84 + if (!timeout)
  85 + timeout = &gn->timeout;
  86 +
84 87 if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT])
85 88 *timeout =
86 89 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
... ... @@ -160,7 +163,6 @@
160 163 .l4proto = 255,
161 164 .pkt_to_tuple = generic_pkt_to_tuple,
162 165 .packet = generic_packet,
163   - .get_timeouts = generic_get_timeouts,
164 166 .new = generic_new,
165 167 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
166 168 .ctnl_timeout = {
net/netfilter/nf_conntrack_proto_gre.c
... ... @@ -39,6 +39,7 @@
39 39 #include <net/netfilter/nf_conntrack_l4proto.h>
40 40 #include <net/netfilter/nf_conntrack_helper.h>
41 41 #include <net/netfilter/nf_conntrack_core.h>
  42 +#include <net/netfilter/nf_conntrack_timeout.h>
42 43 #include <linux/netfilter/nf_conntrack_proto_gre.h>
43 44 #include <linux/netfilter/nf_conntrack_pptp.h>
44 45  
... ... @@ -234,8 +235,7 @@
234 235 static int gre_packet(struct nf_conn *ct,
235 236 const struct sk_buff *skb,
236 237 unsigned int dataoff,
237   - enum ip_conntrack_info ctinfo,
238   - unsigned int *timeouts)
  238 + enum ip_conntrack_info ctinfo)
239 239 {
240 240 /* If we've seen traffic both ways, this is a GRE connection.
241 241 * Extend timeout. */
242 242  
... ... @@ -254,8 +254,13 @@
254 254  
255 255 /* Called when a new connection for this protocol found. */
256 256 static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb,
257   - unsigned int dataoff, unsigned int *timeouts)
  257 + unsigned int dataoff)
258 258 {
  259 + unsigned int *timeouts = nf_ct_timeout_lookup(ct);
  260 +
  261 + if (!timeouts)
  262 + timeouts = gre_get_timeouts(nf_ct_net(ct));
  263 +
259 264 pr_debug(": ");
260 265 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
261 266  
... ... @@ -291,6 +296,8 @@
291 296 unsigned int *timeouts = data;
292 297 struct netns_proto_gre *net_gre = gre_pernet(net);
293 298  
  299 + if (!timeouts)
  300 + timeouts = gre_get_timeouts(net);
294 301 /* set default timeouts for GRE. */
295 302 timeouts[GRE_CT_UNREPLIED] = net_gre->gre_timeouts[GRE_CT_UNREPLIED];
296 303 timeouts[GRE_CT_REPLIED] = net_gre->gre_timeouts[GRE_CT_REPLIED];
... ... @@ -350,7 +357,6 @@
350 357 #ifdef CONFIG_NF_CONNTRACK_PROCFS
351 358 .print_conntrack = gre_print_conntrack,
352 359 #endif
353   - .get_timeouts = gre_get_timeouts,
354 360 .packet = gre_packet,
355 361 .new = gre_new,
356 362 .destroy = gre_destroy,
net/netfilter/nf_conntrack_proto_sctp.c
... ... @@ -28,6 +28,7 @@
28 28 #include <net/netfilter/nf_conntrack.h>
29 29 #include <net/netfilter/nf_conntrack_l4proto.h>
30 30 #include <net/netfilter/nf_conntrack_ecache.h>
  31 +#include <net/netfilter/nf_conntrack_timeout.h>
31 32  
32 33 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
33 34 closely. They're more complex. --RR
34 35  
... ... @@ -272,17 +273,11 @@
272 273 return sctp_conntracks[dir][i][cur_state];
273 274 }
274 275  
275   -static unsigned int *sctp_get_timeouts(struct net *net)
276   -{
277   - return sctp_pernet(net)->timeouts;
278   -}
279   -
280 276 /* Returns verdict for packet, or -NF_ACCEPT for invalid. */
281 277 static int sctp_packet(struct nf_conn *ct,
282 278 const struct sk_buff *skb,
283 279 unsigned int dataoff,
284   - enum ip_conntrack_info ctinfo,
285   - unsigned int *timeouts)
  280 + enum ip_conntrack_info ctinfo)
286 281 {
287 282 enum sctp_conntrack new_state, old_state;
288 283 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
... ... @@ -291,6 +286,7 @@
291 286 const struct sctp_chunkhdr *sch;
292 287 struct sctp_chunkhdr _sch;
293 288 u_int32_t offset, count;
  289 + unsigned int *timeouts;
294 290 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
295 291  
296 292 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
... ... @@ -379,6 +375,10 @@
379 375 }
380 376 spin_unlock_bh(&ct->lock);
381 377  
  378 + timeouts = nf_ct_timeout_lookup(ct);
  379 + if (!timeouts)
  380 + timeouts = sctp_pernet(nf_ct_net(ct))->timeouts;
  381 +
382 382 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
383 383  
384 384 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
... ... @@ -399,7 +399,7 @@
399 399  
400 400 /* Called when a new connection for this protocol found. */
401 401 static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
402   - unsigned int dataoff, unsigned int *timeouts)
  402 + unsigned int dataoff)
403 403 {
404 404 enum sctp_conntrack new_state;
405 405 const struct sctphdr *sh;
... ... @@ -760,7 +760,6 @@
760 760 .print_conntrack = sctp_print_conntrack,
761 761 #endif
762 762 .packet = sctp_packet,
763   - .get_timeouts = sctp_get_timeouts,
764 763 .new = sctp_new,
765 764 .error = sctp_error,
766 765 .can_early_drop = sctp_can_early_drop,
... ... @@ -795,7 +794,6 @@
795 794 .print_conntrack = sctp_print_conntrack,
796 795 #endif
797 796 .packet = sctp_packet,
798   - .get_timeouts = sctp_get_timeouts,
799 797 .new = sctp_new,
800 798 .error = sctp_error,
801 799 .can_early_drop = sctp_can_early_drop,
net/netfilter/nf_conntrack_proto_tcp.c
... ... @@ -29,6 +29,7 @@
29 29 #include <net/netfilter/nf_conntrack_ecache.h>
30 30 #include <net/netfilter/nf_conntrack_seqadj.h>
31 31 #include <net/netfilter/nf_conntrack_synproxy.h>
  32 +#include <net/netfilter/nf_conntrack_timeout.h>
32 33 #include <net/netfilter/nf_log.h>
33 34 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
34 35 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
35 36  
36 37  
37 38  
... ... @@ -768,27 +769,21 @@
768 769 return NF_ACCEPT;
769 770 }
770 771  
771   -static unsigned int *tcp_get_timeouts(struct net *net)
772   -{
773   - return tcp_pernet(net)->timeouts;
774   -}
775   -
776 772 /* Returns verdict for packet, or -1 for invalid. */
777 773 static int tcp_packet(struct nf_conn *ct,
778 774 const struct sk_buff *skb,
779 775 unsigned int dataoff,
780   - enum ip_conntrack_info ctinfo,
781   - unsigned int *timeouts)
  776 + enum ip_conntrack_info ctinfo)
782 777 {
783 778 struct net *net = nf_ct_net(ct);
784 779 struct nf_tcp_net *tn = tcp_pernet(net);
785 780 struct nf_conntrack_tuple *tuple;
786 781 enum tcp_conntrack new_state, old_state;
  782 + unsigned int index, *timeouts;
787 783 enum ip_conntrack_dir dir;
788 784 const struct tcphdr *th;
789 785 struct tcphdr _tcph;
790 786 unsigned long timeout;
791   - unsigned int index;
792 787  
793 788 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
794 789 BUG_ON(th == NULL);
... ... @@ -1021,6 +1016,10 @@
1021 1016 && new_state == TCP_CONNTRACK_FIN_WAIT)
1022 1017 ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
1023 1018  
  1019 + timeouts = nf_ct_timeout_lookup(ct);
  1020 + if (!timeouts)
  1021 + timeouts = tn->timeouts;
  1022 +
1024 1023 if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
1025 1024 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
1026 1025 timeout = timeouts[TCP_CONNTRACK_RETRANS];
... ... @@ -1070,7 +1069,7 @@
1070 1069  
1071 1070 /* Called when a new connection for this protocol found. */
1072 1071 static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
1073   - unsigned int dataoff, unsigned int *timeouts)
  1072 + unsigned int dataoff)
1074 1073 {
1075 1074 enum tcp_conntrack new_state;
1076 1075 const struct tcphdr *th;
1077 1076  
1078 1077  
... ... @@ -1288,10 +1287,12 @@
1288 1287 static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
1289 1288 struct net *net, void *data)
1290 1289 {
1291   - unsigned int *timeouts = data;
1292 1290 struct nf_tcp_net *tn = tcp_pernet(net);
  1291 + unsigned int *timeouts = data;
1293 1292 int i;
1294 1293  
  1294 + if (!timeouts)
  1295 + timeouts = tn->timeouts;
1295 1296 /* set default TCP timeouts. */
1296 1297 for (i=0; i<TCP_CONNTRACK_TIMEOUT_MAX; i++)
1297 1298 timeouts[i] = tn->timeouts[i];
... ... @@ -1538,7 +1539,6 @@
1538 1539 .print_conntrack = tcp_print_conntrack,
1539 1540 #endif
1540 1541 .packet = tcp_packet,
1541   - .get_timeouts = tcp_get_timeouts,
1542 1542 .new = tcp_new,
1543 1543 .error = tcp_error,
1544 1544 .can_early_drop = tcp_can_early_drop,
... ... @@ -1574,7 +1574,6 @@
1574 1574 .print_conntrack = tcp_print_conntrack,
1575 1575 #endif
1576 1576 .packet = tcp_packet,
1577   - .get_timeouts = tcp_get_timeouts,
1578 1577 .new = tcp_new,
1579 1578 .error = tcp_error,
1580 1579 .can_early_drop = tcp_can_early_drop,
net/netfilter/nf_conntrack_proto_udp.c
... ... @@ -22,6 +22,7 @@
22 22 #include <linux/netfilter_ipv6.h>
23 23 #include <net/netfilter/nf_conntrack_l4proto.h>
24 24 #include <net/netfilter/nf_conntrack_ecache.h>
  25 +#include <net/netfilter/nf_conntrack_timeout.h>
25 26 #include <net/netfilter/nf_log.h>
26 27 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
27 28 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
28 29  
... ... @@ -45,9 +46,14 @@
45 46 static int udp_packet(struct nf_conn *ct,
46 47 const struct sk_buff *skb,
47 48 unsigned int dataoff,
48   - enum ip_conntrack_info ctinfo,
49   - unsigned int *timeouts)
  49 + enum ip_conntrack_info ctinfo)
50 50 {
  51 + unsigned int *timeouts;
  52 +
  53 + timeouts = nf_ct_timeout_lookup(ct);
  54 + if (!timeouts)
  55 + timeouts = udp_get_timeouts(nf_ct_net(ct));
  56 +
51 57 /* If we've seen traffic both ways, this is some kind of UDP
52 58 stream. Extend timeout. */
53 59 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
... ... @@ -65,7 +71,7 @@
65 71  
66 72 /* Called when a new connection for this protocol found. */
67 73 static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
68   - unsigned int dataoff, unsigned int *timeouts)
  74 + unsigned int dataoff)
69 75 {
70 76 return true;
71 77 }
... ... @@ -176,6 +182,9 @@
176 182 unsigned int *timeouts = data;
177 183 struct nf_udp_net *un = udp_pernet(net);
178 184  
  185 + if (!timeouts)
  186 + timeouts = un->timeouts;
  187 +
179 188 /* set default timeouts for UDP. */
180 189 timeouts[UDP_CT_UNREPLIED] = un->timeouts[UDP_CT_UNREPLIED];
181 190 timeouts[UDP_CT_REPLIED] = un->timeouts[UDP_CT_REPLIED];
... ... @@ -275,7 +284,6 @@
275 284 .l4proto = IPPROTO_UDP,
276 285 .allow_clash = true,
277 286 .packet = udp_packet,
278   - .get_timeouts = udp_get_timeouts,
279 287 .new = udp_new,
280 288 .error = udp_error,
281 289 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
... ... @@ -305,7 +313,6 @@
305 313 .l4proto = IPPROTO_UDPLITE,
306 314 .allow_clash = true,
307 315 .packet = udp_packet,
308   - .get_timeouts = udp_get_timeouts,
309 316 .new = udp_new,
310 317 .error = udplite_error,
311 318 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
... ... @@ -335,7 +342,6 @@
335 342 .l4proto = IPPROTO_UDP,
336 343 .allow_clash = true,
337 344 .packet = udp_packet,
338   - .get_timeouts = udp_get_timeouts,
339 345 .new = udp_new,
340 346 .error = udp_error,
341 347 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
... ... @@ -365,7 +371,6 @@
365 371 .l4proto = IPPROTO_UDPLITE,
366 372 .allow_clash = true,
367 373 .packet = udp_packet,
368   - .get_timeouts = udp_get_timeouts,
369 374 .new = udp_new,
370 375 .error = udplite_error,
371 376 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
... ... @@ -388,4 +393,5 @@
388 393 };
389 394 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udplite6);
390 395 #endif
  396 +#include <net/netfilter/nf_conntrack_timeout.h>
net/netfilter/nfnetlink_cttimeout.c
... ... @@ -46,7 +46,7 @@
46 46 };
47 47  
48 48 static int
49   -ctnl_timeout_parse_policy(void *timeouts,
  49 +ctnl_timeout_parse_policy(void *timeout,
50 50 const struct nf_conntrack_l4proto *l4proto,
51 51 struct net *net, const struct nlattr *attr)
52 52 {
... ... @@ -67,7 +67,7 @@
67 67 if (ret < 0)
68 68 goto err;
69 69  
70   - ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts);
  70 + ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeout);
71 71  
72 72 err:
73 73 kfree(tb);
... ... @@ -372,7 +372,6 @@
372 372 struct netlink_ext_ack *extack)
373 373 {
374 374 const struct nf_conntrack_l4proto *l4proto;
375   - unsigned int *timeouts;
376 375 __u16 l3num;
377 376 __u8 l4num;
378 377 int ret;
... ... @@ -392,9 +391,7 @@
392 391 goto err;
393 392 }
394 393  
395   - timeouts = l4proto->get_timeouts(net);
396   -
397   - ret = ctnl_timeout_parse_policy(timeouts, l4proto, net,
  394 + ret = ctnl_timeout_parse_policy(NULL, l4proto, net,
398 395 cda[CTA_TIMEOUT_DATA]);
399 396 if (ret < 0)
400 397 goto err;
... ... @@ -431,7 +428,6 @@
431 428  
432 429 if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
433 430 struct nlattr *nest_parms;
434   - unsigned int *timeouts = l4proto->get_timeouts(net);
435 431 int ret;
436 432  
437 433 nest_parms = nla_nest_start(skb,
... ... @@ -439,7 +435,7 @@
439 435 if (!nest_parms)
440 436 goto nla_put_failure;
441 437  
442   - ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
  438 + ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, NULL);
443 439 if (ret < 0)
444 440 goto nla_put_failure;
445 441