1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Header for use in defining a given L4 protocol for connection tracking. |
4 | * |
5 | * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> |
6 | * - generalized L3 protocol dependent part. |
7 | * |
8 | * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h |
9 | */ |
10 | |
11 | #ifndef _NF_CONNTRACK_L4PROTO_H |
12 | #define _NF_CONNTRACK_L4PROTO_H |
13 | #include <linux/netlink.h> |
14 | #include <net/netlink.h> |
15 | #include <net/netfilter/nf_conntrack.h> |
16 | #include <net/netns/generic.h> |
17 | |
18 | struct seq_file; |
19 | |
20 | struct nf_conntrack_l4proto { |
21 | /* L4 Protocol number. */ |
22 | u_int8_t l4proto; |
23 | |
24 | /* Resolve clashes on insertion races. */ |
25 | bool allow_clash; |
26 | |
27 | /* protoinfo nlattr size, closes a hole */ |
28 | u16 nlattr_size; |
29 | |
30 | /* called by gc worker if table is full */ |
31 | bool (*can_early_drop)(const struct nf_conn *ct); |
32 | |
33 | /* convert protoinfo to nfnetink attributes */ |
34 | int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla, |
35 | struct nf_conn *ct, bool destroy); |
36 | |
37 | /* convert nfnetlink attributes to protoinfo */ |
38 | int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct); |
39 | |
40 | int (*tuple_to_nlattr)(struct sk_buff *skb, |
41 | const struct nf_conntrack_tuple *t); |
42 | /* Calculate tuple nlattr size */ |
43 | unsigned int (*nlattr_tuple_size)(void); |
44 | int (*nlattr_to_tuple)(struct nlattr *tb[], |
45 | struct nf_conntrack_tuple *t, |
46 | u_int32_t flags); |
47 | const struct nla_policy *nla_policy; |
48 | |
49 | struct { |
50 | int (*nlattr_to_obj)(struct nlattr *tb[], |
51 | struct net *net, void *data); |
52 | int (*obj_to_nlattr)(struct sk_buff *skb, const void *data); |
53 | |
54 | u16 obj_size; |
55 | u16 nlattr_max; |
56 | const struct nla_policy *nla_policy; |
57 | } ctnl_timeout; |
58 | #ifdef CONFIG_NF_CONNTRACK_PROCFS |
59 | /* Print out the private part of the conntrack. */ |
60 | void (*print_conntrack)(struct seq_file *s, struct nf_conn *); |
61 | #endif |
62 | }; |
63 | |
64 | bool icmp_pkt_to_tuple(const struct sk_buff *skb, |
65 | unsigned int dataoff, |
66 | struct net *net, |
67 | struct nf_conntrack_tuple *tuple); |
68 | |
69 | bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, |
70 | unsigned int dataoff, |
71 | struct net *net, |
72 | struct nf_conntrack_tuple *tuple); |
73 | |
74 | bool nf_conntrack_invert_icmp_tuple(struct nf_conntrack_tuple *tuple, |
75 | const struct nf_conntrack_tuple *orig); |
76 | bool nf_conntrack_invert_icmpv6_tuple(struct nf_conntrack_tuple *tuple, |
77 | const struct nf_conntrack_tuple *orig); |
78 | |
79 | int nf_conntrack_inet_error(struct nf_conn *tmpl, struct sk_buff *skb, |
80 | unsigned int dataoff, |
81 | const struct nf_hook_state *state, |
82 | u8 l4proto, |
83 | union nf_inet_addr *outer_daddr); |
84 | |
85 | int nf_conntrack_icmpv4_error(struct nf_conn *tmpl, |
86 | struct sk_buff *skb, |
87 | unsigned int dataoff, |
88 | const struct nf_hook_state *state); |
89 | |
90 | int nf_conntrack_icmpv6_error(struct nf_conn *tmpl, |
91 | struct sk_buff *skb, |
92 | unsigned int dataoff, |
93 | const struct nf_hook_state *state); |
94 | |
95 | int nf_conntrack_icmp_packet(struct nf_conn *ct, |
96 | struct sk_buff *skb, |
97 | enum ip_conntrack_info ctinfo, |
98 | const struct nf_hook_state *state); |
99 | |
100 | int nf_conntrack_icmpv6_packet(struct nf_conn *ct, |
101 | struct sk_buff *skb, |
102 | enum ip_conntrack_info ctinfo, |
103 | const struct nf_hook_state *state); |
104 | |
105 | int nf_conntrack_udp_packet(struct nf_conn *ct, |
106 | struct sk_buff *skb, |
107 | unsigned int dataoff, |
108 | enum ip_conntrack_info ctinfo, |
109 | const struct nf_hook_state *state); |
110 | int nf_conntrack_udplite_packet(struct nf_conn *ct, |
111 | struct sk_buff *skb, |
112 | unsigned int dataoff, |
113 | enum ip_conntrack_info ctinfo, |
114 | const struct nf_hook_state *state); |
115 | int nf_conntrack_tcp_packet(struct nf_conn *ct, |
116 | struct sk_buff *skb, |
117 | unsigned int dataoff, |
118 | enum ip_conntrack_info ctinfo, |
119 | const struct nf_hook_state *state); |
120 | int nf_conntrack_dccp_packet(struct nf_conn *ct, |
121 | struct sk_buff *skb, |
122 | unsigned int dataoff, |
123 | enum ip_conntrack_info ctinfo, |
124 | const struct nf_hook_state *state); |
125 | int nf_conntrack_sctp_packet(struct nf_conn *ct, |
126 | struct sk_buff *skb, |
127 | unsigned int dataoff, |
128 | enum ip_conntrack_info ctinfo, |
129 | const struct nf_hook_state *state); |
130 | int nf_conntrack_gre_packet(struct nf_conn *ct, |
131 | struct sk_buff *skb, |
132 | unsigned int dataoff, |
133 | enum ip_conntrack_info ctinfo, |
134 | const struct nf_hook_state *state); |
135 | |
136 | void nf_conntrack_generic_init_net(struct net *net); |
137 | void nf_conntrack_tcp_init_net(struct net *net); |
138 | void nf_conntrack_udp_init_net(struct net *net); |
139 | void nf_conntrack_gre_init_net(struct net *net); |
140 | void nf_conntrack_dccp_init_net(struct net *net); |
141 | void nf_conntrack_sctp_init_net(struct net *net); |
142 | void nf_conntrack_icmp_init_net(struct net *net); |
143 | void nf_conntrack_icmpv6_init_net(struct net *net); |
144 | |
145 | /* Existing built-in generic protocol */ |
146 | extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic; |
147 | |
148 | #define MAX_NF_CT_PROTO IPPROTO_UDPLITE |
149 | |
150 | const struct nf_conntrack_l4proto *nf_ct_l4proto_find(u8 l4proto); |
151 | |
152 | /* Generic netlink helpers */ |
153 | int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, |
154 | const struct nf_conntrack_tuple *tuple); |
155 | int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], |
156 | struct nf_conntrack_tuple *t, |
157 | u_int32_t flags); |
158 | unsigned int nf_ct_port_nlattr_tuple_size(void); |
159 | extern const struct nla_policy nf_ct_port_nla_policy[]; |
160 | |
161 | #ifdef CONFIG_SYSCTL |
162 | __printf(4, 5) __cold |
163 | void nf_ct_l4proto_log_invalid(const struct sk_buff *skb, |
164 | const struct nf_conn *ct, |
165 | const struct nf_hook_state *state, |
166 | const char *fmt, ...); |
167 | __printf(4, 5) __cold |
168 | void nf_l4proto_log_invalid(const struct sk_buff *skb, |
169 | const struct nf_hook_state *state, |
170 | u8 protonum, |
171 | const char *fmt, ...); |
172 | #else |
173 | static inline __printf(4, 5) __cold |
174 | void nf_l4proto_log_invalid(const struct sk_buff *skb, |
175 | const struct nf_hook_state *state, |
176 | u8 protonum, |
177 | const char *fmt, ...) {} |
178 | static inline __printf(4, 5) __cold |
179 | void nf_ct_l4proto_log_invalid(const struct sk_buff *skb, |
180 | const struct nf_conn *ct, |
181 | const struct nf_hook_state *state, |
182 | const char *fmt, ...) { } |
183 | #endif /* CONFIG_SYSCTL */ |
184 | |
185 | #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
186 | static inline struct nf_generic_net *nf_generic_pernet(struct net *net) |
187 | { |
188 | return &net->ct.nf_ct_proto.generic; |
189 | } |
190 | |
191 | static inline struct nf_tcp_net *nf_tcp_pernet(struct net *net) |
192 | { |
193 | return &net->ct.nf_ct_proto.tcp; |
194 | } |
195 | |
196 | static inline struct nf_udp_net *nf_udp_pernet(struct net *net) |
197 | { |
198 | return &net->ct.nf_ct_proto.udp; |
199 | } |
200 | |
201 | static inline struct nf_icmp_net *nf_icmp_pernet(struct net *net) |
202 | { |
203 | return &net->ct.nf_ct_proto.icmp; |
204 | } |
205 | |
206 | static inline struct nf_icmp_net *nf_icmpv6_pernet(struct net *net) |
207 | { |
208 | return &net->ct.nf_ct_proto.icmpv6; |
209 | } |
210 | |
211 | /* Caller must check nf_ct_protonum(ct) is IPPROTO_TCP before calling. */ |
212 | static inline void nf_ct_set_tcp_be_liberal(struct nf_conn *ct) |
213 | { |
214 | ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; |
215 | ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; |
216 | } |
217 | |
218 | /* Caller must check nf_ct_protonum(ct) is IPPROTO_TCP before calling. */ |
219 | static inline bool nf_conntrack_tcp_established(const struct nf_conn *ct) |
220 | { |
221 | return ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED && |
222 | test_bit(IPS_ASSURED_BIT, &ct->status); |
223 | } |
224 | #endif |
225 | |
226 | #ifdef CONFIG_NF_CT_PROTO_DCCP |
227 | static inline struct nf_dccp_net *nf_dccp_pernet(struct net *net) |
228 | { |
229 | return &net->ct.nf_ct_proto.dccp; |
230 | } |
231 | #endif |
232 | |
233 | #ifdef CONFIG_NF_CT_PROTO_SCTP |
234 | static inline struct nf_sctp_net *nf_sctp_pernet(struct net *net) |
235 | { |
236 | return &net->ct.nf_ct_proto.sctp; |
237 | } |
238 | #endif |
239 | |
240 | #ifdef CONFIG_NF_CT_PROTO_GRE |
241 | static inline struct nf_gre_net *nf_gre_pernet(struct net *net) |
242 | { |
243 | return &net->ct.nf_ct_proto.gre; |
244 | } |
245 | #endif |
246 | |
247 | #endif /*_NF_CONNTRACK_PROTOCOL_H*/ |
248 | |