Commit 97e08caec33a0923385b1215c3386c9ee1d07982
Committed by
Pablo Neira Ayuso
1 parent
8b3892ea87
netfilter: conntrack: avoid l4proto pkt_to_tuple calls
Handle common protocols (udp, tcp, ..), in the core and only do the call if needed by the l4proto tracker. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Showing 5 changed files with 15 additions and 78 deletions Side-by-side Diff
net/netfilter/nf_conntrack_core.c
... | ... | @@ -235,6 +235,10 @@ |
235 | 235 | unsigned int size; |
236 | 236 | const __be32 *ap; |
237 | 237 | __be32 _addrs[8]; |
238 | + struct { | |
239 | + __be16 sport; | |
240 | + __be16 dport; | |
241 | + } _inet_hdr, *inet_hdr; | |
238 | 242 | |
239 | 243 | memset(tuple, 0, sizeof(*tuple)); |
240 | 244 | |
... | ... | @@ -270,7 +274,17 @@ |
270 | 274 | tuple->dst.protonum = protonum; |
271 | 275 | tuple->dst.dir = IP_CT_DIR_ORIGINAL; |
272 | 276 | |
273 | - return l4proto->pkt_to_tuple(skb, dataoff, net, tuple); | |
277 | + if (unlikely(l4proto->pkt_to_tuple)) | |
278 | + return l4proto->pkt_to_tuple(skb, dataoff, net, tuple); | |
279 | + | |
280 | + /* Actually only need first 4 bytes to get ports. */ | |
281 | + inet_hdr = skb_header_pointer(skb, dataoff, sizeof(_inet_hdr), &_inet_hdr); | |
282 | + if (!inet_hdr) | |
283 | + return false; | |
284 | + | |
285 | + tuple->src.u.udp.port = inet_hdr->sport; | |
286 | + tuple->dst.u.udp.port = inet_hdr->dport; | |
287 | + return true; | |
274 | 288 | } |
275 | 289 | |
276 | 290 | static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, |
net/netfilter/nf_conntrack_proto_dccp.c
... | ... | @@ -388,21 +388,6 @@ |
388 | 388 | return &net->ct.nf_ct_proto.dccp; |
389 | 389 | } |
390 | 390 | |
391 | -static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, | |
392 | - struct net *net, struct nf_conntrack_tuple *tuple) | |
393 | -{ | |
394 | - struct dccp_hdr _hdr, *dh; | |
395 | - | |
396 | - /* Actually only need first 4 bytes to get ports. */ | |
397 | - dh = skb_header_pointer(skb, dataoff, 4, &_hdr); | |
398 | - if (dh == NULL) | |
399 | - return false; | |
400 | - | |
401 | - tuple->src.u.dccp.port = dh->dccph_sport; | |
402 | - tuple->dst.u.dccp.port = dh->dccph_dport; | |
403 | - return true; | |
404 | -} | |
405 | - | |
406 | 391 | static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, |
407 | 392 | unsigned int dataoff, unsigned int *timeouts) |
408 | 393 | { |
... | ... | @@ -856,7 +841,6 @@ |
856 | 841 | const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = { |
857 | 842 | .l3proto = AF_INET, |
858 | 843 | .l4proto = IPPROTO_DCCP, |
859 | - .pkt_to_tuple = dccp_pkt_to_tuple, | |
860 | 844 | .new = dccp_new, |
861 | 845 | .packet = dccp_packet, |
862 | 846 | .get_timeouts = dccp_get_timeouts, |
... | ... | @@ -891,7 +875,6 @@ |
891 | 875 | const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = { |
892 | 876 | .l3proto = AF_INET6, |
893 | 877 | .l4proto = IPPROTO_DCCP, |
894 | - .pkt_to_tuple = dccp_pkt_to_tuple, | |
895 | 878 | .new = dccp_new, |
896 | 879 | .packet = dccp_packet, |
897 | 880 | .get_timeouts = dccp_get_timeouts, |
net/netfilter/nf_conntrack_proto_sctp.c
... | ... | @@ -150,22 +150,6 @@ |
150 | 150 | return &net->ct.nf_ct_proto.sctp; |
151 | 151 | } |
152 | 152 | |
153 | -static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, | |
154 | - struct net *net, struct nf_conntrack_tuple *tuple) | |
155 | -{ | |
156 | - const struct sctphdr *hp; | |
157 | - struct sctphdr _hdr; | |
158 | - | |
159 | - /* Actually only need first 4 bytes to get ports. */ | |
160 | - hp = skb_header_pointer(skb, dataoff, 4, &_hdr); | |
161 | - if (hp == NULL) | |
162 | - return false; | |
163 | - | |
164 | - tuple->src.u.sctp.port = hp->source; | |
165 | - tuple->dst.u.sctp.port = hp->dest; | |
166 | - return true; | |
167 | -} | |
168 | - | |
169 | 153 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
170 | 154 | /* Print out the private part of the conntrack. */ |
171 | 155 | static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct) |
... | ... | @@ -772,7 +756,6 @@ |
772 | 756 | const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = { |
773 | 757 | .l3proto = PF_INET, |
774 | 758 | .l4proto = IPPROTO_SCTP, |
775 | - .pkt_to_tuple = sctp_pkt_to_tuple, | |
776 | 759 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
777 | 760 | .print_conntrack = sctp_print_conntrack, |
778 | 761 | #endif |
... | ... | @@ -808,7 +791,6 @@ |
808 | 791 | const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = { |
809 | 792 | .l3proto = PF_INET6, |
810 | 793 | .l4proto = IPPROTO_SCTP, |
811 | - .pkt_to_tuple = sctp_pkt_to_tuple, | |
812 | 794 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
813 | 795 | .print_conntrack = sctp_print_conntrack, |
814 | 796 | #endif |
net/netfilter/nf_conntrack_proto_tcp.c
... | ... | @@ -276,23 +276,6 @@ |
276 | 276 | return &net->ct.nf_ct_proto.tcp; |
277 | 277 | } |
278 | 278 | |
279 | -static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, | |
280 | - struct net *net, struct nf_conntrack_tuple *tuple) | |
281 | -{ | |
282 | - const struct tcphdr *hp; | |
283 | - struct tcphdr _hdr; | |
284 | - | |
285 | - /* Actually only need first 4 bytes to get ports. */ | |
286 | - hp = skb_header_pointer(skb, dataoff, 4, &_hdr); | |
287 | - if (hp == NULL) | |
288 | - return false; | |
289 | - | |
290 | - tuple->src.u.tcp.port = hp->source; | |
291 | - tuple->dst.u.tcp.port = hp->dest; | |
292 | - | |
293 | - return true; | |
294 | -} | |
295 | - | |
296 | 279 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
297 | 280 | /* Print out the private part of the conntrack. */ |
298 | 281 | static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct) |
... | ... | @@ -1551,7 +1534,6 @@ |
1551 | 1534 | { |
1552 | 1535 | .l3proto = PF_INET, |
1553 | 1536 | .l4proto = IPPROTO_TCP, |
1554 | - .pkt_to_tuple = tcp_pkt_to_tuple, | |
1555 | 1537 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
1556 | 1538 | .print_conntrack = tcp_print_conntrack, |
1557 | 1539 | #endif |
... | ... | @@ -1588,7 +1570,6 @@ |
1588 | 1570 | { |
1589 | 1571 | .l3proto = PF_INET6, |
1590 | 1572 | .l4proto = IPPROTO_TCP, |
1591 | - .pkt_to_tuple = tcp_pkt_to_tuple, | |
1592 | 1573 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
1593 | 1574 | .print_conntrack = tcp_print_conntrack, |
1594 | 1575 | #endif |
net/netfilter/nf_conntrack_proto_udp.c
... | ... | @@ -36,25 +36,6 @@ |
36 | 36 | return &net->ct.nf_ct_proto.udp; |
37 | 37 | } |
38 | 38 | |
39 | -static bool udp_pkt_to_tuple(const struct sk_buff *skb, | |
40 | - unsigned int dataoff, | |
41 | - struct net *net, | |
42 | - struct nf_conntrack_tuple *tuple) | |
43 | -{ | |
44 | - const struct udphdr *hp; | |
45 | - struct udphdr _hdr; | |
46 | - | |
47 | - /* Actually only need first 4 bytes to get ports. */ | |
48 | - hp = skb_header_pointer(skb, dataoff, 4, &_hdr); | |
49 | - if (hp == NULL) | |
50 | - return false; | |
51 | - | |
52 | - tuple->src.u.udp.port = hp->source; | |
53 | - tuple->dst.u.udp.port = hp->dest; | |
54 | - | |
55 | - return true; | |
56 | -} | |
57 | - | |
58 | 39 | static unsigned int *udp_get_timeouts(struct net *net) |
59 | 40 | { |
60 | 41 | return udp_pernet(net)->timeouts; |
... | ... | @@ -293,7 +274,6 @@ |
293 | 274 | .l3proto = PF_INET, |
294 | 275 | .l4proto = IPPROTO_UDP, |
295 | 276 | .allow_clash = true, |
296 | - .pkt_to_tuple = udp_pkt_to_tuple, | |
297 | 277 | .packet = udp_packet, |
298 | 278 | .get_timeouts = udp_get_timeouts, |
299 | 279 | .new = udp_new, |
... | ... | @@ -324,7 +304,6 @@ |
324 | 304 | .l3proto = PF_INET, |
325 | 305 | .l4proto = IPPROTO_UDPLITE, |
326 | 306 | .allow_clash = true, |
327 | - .pkt_to_tuple = udp_pkt_to_tuple, | |
328 | 307 | .packet = udp_packet, |
329 | 308 | .get_timeouts = udp_get_timeouts, |
330 | 309 | .new = udp_new, |
... | ... | @@ -355,7 +334,6 @@ |
355 | 334 | .l3proto = PF_INET6, |
356 | 335 | .l4proto = IPPROTO_UDP, |
357 | 336 | .allow_clash = true, |
358 | - .pkt_to_tuple = udp_pkt_to_tuple, | |
359 | 337 | .packet = udp_packet, |
360 | 338 | .get_timeouts = udp_get_timeouts, |
361 | 339 | .new = udp_new, |
... | ... | @@ -386,7 +364,6 @@ |
386 | 364 | .l3proto = PF_INET6, |
387 | 365 | .l4proto = IPPROTO_UDPLITE, |
388 | 366 | .allow_clash = true, |
389 | - .pkt_to_tuple = udp_pkt_to_tuple, | |
390 | 367 | .packet = udp_packet, |
391 | 368 | .get_timeouts = udp_get_timeouts, |
392 | 369 | .new = udp_new, |