Commit a47c5404816254d6cc4787f335c4720066a538e6

Authored by Florian Westphal
Committed by Pablo Neira Ayuso
1 parent 75dd48e2e4

netfilter: conntrack: handle builtin l4proto packet functions via direct calls

The l4 protocol trackers are invoked via indirect call: l4proto->packet().

With one exception (gre), all l4trackers are builtin, so we can make
.packet optional and use a direct call for most protocols.

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

Showing 8 changed files with 113 additions and 44 deletions Side-by-side Diff

include/net/netfilter/nf_conntrack_l4proto.h
... ... @@ -99,6 +99,43 @@
99 99 struct sk_buff *skb,
100 100 unsigned int dataoff,
101 101 const struct nf_hook_state *state);
  102 +
  103 +int nf_conntrack_icmp_packet(struct nf_conn *ct,
  104 + struct sk_buff *skb,
  105 + enum ip_conntrack_info ctinfo,
  106 + const struct nf_hook_state *state);
  107 +
  108 +int nf_conntrack_icmpv6_packet(struct nf_conn *ct,
  109 + struct sk_buff *skb,
  110 + enum ip_conntrack_info ctinfo,
  111 + const struct nf_hook_state *state);
  112 +
  113 +int nf_conntrack_udp_packet(struct nf_conn *ct,
  114 + struct sk_buff *skb,
  115 + unsigned int dataoff,
  116 + enum ip_conntrack_info ctinfo,
  117 + const struct nf_hook_state *state);
  118 +int nf_conntrack_udplite_packet(struct nf_conn *ct,
  119 + struct sk_buff *skb,
  120 + unsigned int dataoff,
  121 + enum ip_conntrack_info ctinfo,
  122 + const struct nf_hook_state *state);
  123 +int nf_conntrack_tcp_packet(struct nf_conn *ct,
  124 + struct sk_buff *skb,
  125 + unsigned int dataoff,
  126 + enum ip_conntrack_info ctinfo,
  127 + const struct nf_hook_state *state);
  128 +int nf_conntrack_dccp_packet(struct nf_conn *ct,
  129 + struct sk_buff *skb,
  130 + unsigned int dataoff,
  131 + enum ip_conntrack_info ctinfo,
  132 + const struct nf_hook_state *state);
  133 +int nf_conntrack_sctp_packet(struct nf_conn *ct,
  134 + struct sk_buff *skb,
  135 + unsigned int dataoff,
  136 + enum ip_conntrack_info ctinfo,
  137 + const struct nf_hook_state *state);
  138 +
102 139 /* Existing built-in generic protocol */
103 140 extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
104 141  
net/netfilter/nf_conntrack_core.c
... ... @@ -1522,6 +1522,45 @@
1522 1522 return ret;
1523 1523 }
1524 1524  
  1525 +/* Returns verdict for packet, or -1 for invalid. */
  1526 +static int nf_conntrack_handle_packet(struct nf_conn *ct,
  1527 + struct sk_buff *skb,
  1528 + unsigned int dataoff,
  1529 + enum ip_conntrack_info ctinfo,
  1530 + const struct nf_hook_state *state)
  1531 +{
  1532 + switch (nf_ct_protonum(ct)) {
  1533 + case IPPROTO_TCP:
  1534 + return nf_conntrack_tcp_packet(ct, skb, dataoff,
  1535 + ctinfo, state);
  1536 + case IPPROTO_UDP:
  1537 + return nf_conntrack_udp_packet(ct, skb, dataoff,
  1538 + ctinfo, state);
  1539 + case IPPROTO_ICMP:
  1540 + return nf_conntrack_icmp_packet(ct, skb, ctinfo, state);
  1541 + case IPPROTO_ICMPV6:
  1542 + return nf_conntrack_icmpv6_packet(ct, skb, ctinfo, state);
  1543 +#ifdef CONFIG_NF_CT_PROTO_UDPLITE
  1544 + case IPPROTO_UDPLITE:
  1545 + return nf_conntrack_udplite_packet(ct, skb, dataoff,
  1546 + ctinfo, state);
  1547 +#endif
  1548 +#ifdef CONFIG_NF_CT_PROTO_SCTP
  1549 + case IPPROTO_SCTP:
  1550 + return nf_conntrack_sctp_packet(ct, skb, dataoff,
  1551 + ctinfo, state);
  1552 +#endif
  1553 +#ifdef CONFIG_NF_CT_PROTO_DCCP
  1554 + case IPPROTO_DCCP:
  1555 + return nf_conntrack_dccp_packet(ct, skb, dataoff,
  1556 + ctinfo, state);
  1557 +#endif
  1558 + }
  1559 +
  1560 + WARN_ON_ONCE(1);
  1561 + return -NF_ACCEPT;
  1562 +}
  1563 +
1525 1564 unsigned int
1526 1565 nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
1527 1566 {
... ... @@ -1583,7 +1622,11 @@
1583 1622 goto out;
1584 1623 }
1585 1624  
1586   - ret = l4proto->packet(ct, skb, dataoff, ctinfo, state);
  1625 + if (l4proto->packet)
  1626 + ret = l4proto->packet(ct, skb, dataoff, ctinfo, state);
  1627 + else
  1628 + ret = nf_conntrack_handle_packet(ct, skb, dataoff, ctinfo, state);
  1629 +
1587 1630 if (ret <= 0) {
1588 1631 /* Invalid: inverse of the return code tells
1589 1632 * the netfilter core what to do */
net/netfilter/nf_conntrack_proto_dccp.c
... ... @@ -472,9 +472,10 @@
472 472 return true;
473 473 }
474 474  
475   -static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
476   - unsigned int dataoff, enum ip_conntrack_info ctinfo,
477   - const struct nf_hook_state *state)
  475 +int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
  476 + unsigned int dataoff,
  477 + enum ip_conntrack_info ctinfo,
  478 + const struct nf_hook_state *state)
478 479 {
479 480 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
480 481 struct dccp_hdr _dh, *dh;
... ... @@ -839,7 +840,6 @@
839 840  
840 841 const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp = {
841 842 .l4proto = IPPROTO_DCCP,
842   - .packet = dccp_packet,
843 843 .can_early_drop = dccp_can_early_drop,
844 844 #ifdef CONFIG_NF_CONNTRACK_PROCFS
845 845 .print_conntrack = dccp_print_conntrack,
net/netfilter/nf_conntrack_proto_icmp.c
... ... @@ -68,11 +68,10 @@
68 68 }
69 69  
70 70 /* Returns verdict for packet, or -1 for invalid. */
71   -static int icmp_packet(struct nf_conn *ct,
72   - struct sk_buff *skb,
73   - unsigned int dataoff,
74   - enum ip_conntrack_info ctinfo,
75   - const struct nf_hook_state *state)
  71 +int nf_conntrack_icmp_packet(struct nf_conn *ct,
  72 + struct sk_buff *skb,
  73 + enum ip_conntrack_info ctinfo,
  74 + const struct nf_hook_state *state)
76 75 {
77 76 /* Do not immediately delete the connection after the first
78 77 successful reply to avoid excessive conntrackd traffic
... ... @@ -350,9 +349,6 @@
350 349 .l4proto = IPPROTO_ICMP,
351 350 .pkt_to_tuple = icmp_pkt_to_tuple,
352 351 .invert_tuple = icmp_invert_tuple,
353   - .packet = icmp_packet,
354   - .destroy = NULL,
355   - .me = NULL,
356 352 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
357 353 .tuple_to_nlattr = icmp_tuple_to_nlattr,
358 354 .nlattr_tuple_size = icmp_nlattr_tuple_size,
net/netfilter/nf_conntrack_proto_icmpv6.c
... ... @@ -86,11 +86,10 @@
86 86 }
87 87  
88 88 /* Returns verdict for packet, or -1 for invalid. */
89   -static int icmpv6_packet(struct nf_conn *ct,
90   - struct sk_buff *skb,
91   - unsigned int dataoff,
92   - enum ip_conntrack_info ctinfo,
93   - const struct nf_hook_state *state)
  89 +int nf_conntrack_icmpv6_packet(struct nf_conn *ct,
  90 + struct sk_buff *skb,
  91 + enum ip_conntrack_info ctinfo,
  92 + const struct nf_hook_state *state)
94 93 {
95 94 unsigned int *timeout = nf_ct_timeout_lookup(ct);
96 95 static const u8 valid_new[] = {
... ... @@ -361,7 +360,6 @@
361 360 .l4proto = IPPROTO_ICMPV6,
362 361 .pkt_to_tuple = icmpv6_pkt_to_tuple,
363 362 .invert_tuple = icmpv6_invert_tuple,
364   - .packet = icmpv6_packet,
365 363 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
366 364 .tuple_to_nlattr = icmpv6_tuple_to_nlattr,
367 365 .nlattr_tuple_size = icmpv6_nlattr_tuple_size,
net/netfilter/nf_conntrack_proto_sctp.c
... ... @@ -357,11 +357,11 @@
357 357 }
358 358  
359 359 /* Returns verdict for packet, or -NF_ACCEPT for invalid. */
360   -static int sctp_packet(struct nf_conn *ct,
361   - struct sk_buff *skb,
362   - unsigned int dataoff,
363   - enum ip_conntrack_info ctinfo,
364   - const struct nf_hook_state *state)
  360 +int nf_conntrack_sctp_packet(struct nf_conn *ct,
  361 + struct sk_buff *skb,
  362 + unsigned int dataoff,
  363 + enum ip_conntrack_info ctinfo,
  364 + const struct nf_hook_state *state)
365 365 {
366 366 enum sctp_conntrack new_state, old_state;
367 367 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
368 368  
... ... @@ -759,9 +759,7 @@
759 759 #ifdef CONFIG_NF_CONNTRACK_PROCFS
760 760 .print_conntrack = sctp_print_conntrack,
761 761 #endif
762   - .packet = sctp_packet,
763 762 .can_early_drop = sctp_can_early_drop,
764   - .me = THIS_MODULE,
765 763 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
766 764 .nlattr_size = SCTP_NLATTR_SIZE,
767 765 .to_nlattr = sctp_to_nlattr,
net/netfilter/nf_conntrack_proto_tcp.c
... ... @@ -829,11 +829,11 @@
829 829 }
830 830  
831 831 /* Returns verdict for packet, or -1 for invalid. */
832   -static int tcp_packet(struct nf_conn *ct,
833   - struct sk_buff *skb,
834   - unsigned int dataoff,
835   - enum ip_conntrack_info ctinfo,
836   - const struct nf_hook_state *state)
  832 +int nf_conntrack_tcp_packet(struct nf_conn *ct,
  833 + struct sk_buff *skb,
  834 + unsigned int dataoff,
  835 + enum ip_conntrack_info ctinfo,
  836 + const struct nf_hook_state *state)
837 837 {
838 838 struct net *net = nf_ct_net(ct);
839 839 struct nf_tcp_net *tn = nf_tcp_pernet(net);
... ... @@ -1535,7 +1535,6 @@
1535 1535 #ifdef CONFIG_NF_CONNTRACK_PROCFS
1536 1536 .print_conntrack = tcp_print_conntrack,
1537 1537 #endif
1538   - .packet = tcp_packet,
1539 1538 .can_early_drop = tcp_can_early_drop,
1540 1539 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
1541 1540 .to_nlattr = tcp_to_nlattr,
net/netfilter/nf_conntrack_proto_udp.c
... ... @@ -85,11 +85,11 @@
85 85 }
86 86  
87 87 /* Returns verdict for packet, and may modify conntracktype */
88   -static int udp_packet(struct nf_conn *ct,
89   - struct sk_buff *skb,
90   - unsigned int dataoff,
91   - enum ip_conntrack_info ctinfo,
92   - const struct nf_hook_state *state)
  88 +int nf_conntrack_udp_packet(struct nf_conn *ct,
  89 + struct sk_buff *skb,
  90 + unsigned int dataoff,
  91 + enum ip_conntrack_info ctinfo,
  92 + const struct nf_hook_state *state)
93 93 {
94 94 unsigned int *timeouts;
95 95  
... ... @@ -177,11 +177,11 @@
177 177 }
178 178  
179 179 /* Returns verdict for packet, and may modify conntracktype */
180   -static int udplite_packet(struct nf_conn *ct,
181   - struct sk_buff *skb,
182   - unsigned int dataoff,
183   - enum ip_conntrack_info ctinfo,
184   - const struct nf_hook_state *state)
  180 +int nf_conntrack_udplite_packet(struct nf_conn *ct,
  181 + struct sk_buff *skb,
  182 + unsigned int dataoff,
  183 + enum ip_conntrack_info ctinfo,
  184 + const struct nf_hook_state *state)
185 185 {
186 186 unsigned int *timeouts;
187 187  
... ... @@ -319,7 +319,6 @@
319 319 {
320 320 .l4proto = IPPROTO_UDP,
321 321 .allow_clash = true,
322   - .packet = udp_packet,
323 322 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
324 323 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
325 324 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
... ... @@ -344,7 +343,6 @@
344 343 {
345 344 .l4proto = IPPROTO_UDPLITE,
346 345 .allow_clash = true,
347   - .packet = udplite_packet,
348 346 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
349 347 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
350 348 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,