Commit 97e08caec33a0923385b1215c3386c9ee1d07982

Authored by Florian Westphal
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,