Commit a47c5404816254d6cc4787f335c4720066a538e6
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
- net/netfilter/nf_conntrack_core.c
- net/netfilter/nf_conntrack_proto_dccp.c
- net/netfilter/nf_conntrack_proto_icmp.c
- net/netfilter/nf_conntrack_proto_icmpv6.c
- net/netfilter/nf_conntrack_proto_sctp.c
- net/netfilter/nf_conntrack_proto_tcp.c
- net/netfilter/nf_conntrack_proto_udp.c
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, |