Commit c779e849608a875448f6ffc2a5c2a15523bdcd00
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
- include/net/netfilter/nf_conntrack_timeout.h
- net/ipv4/netfilter/nf_conntrack_proto_icmp.c
- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
- net/netfilter/nf_conntrack_core.c
- net/netfilter/nf_conntrack_proto_dccp.c
- net/netfilter/nf_conntrack_proto_generic.c
- net/netfilter/nf_conntrack_proto_gre.c
- net/netfilter/nf_conntrack_proto_sctp.c
- net/netfilter/nf_conntrack_proto_tcp.c
- net/netfilter/nf_conntrack_proto_udp.c
- net/netfilter/nfnetlink_cttimeout.c
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 |