1 /* (C) 1999-2001 Paul `Rusty' Russell
2  * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3  * (C) 2006-2012 Patrick McHardy <kaber@trash.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9 
10 #include <linux/types.h>
11 #include <linux/timer.h>
12 #include <linux/module.h>
13 #include <linux/udp.h>
14 #include <linux/seq_file.h>
15 #include <linux/skbuff.h>
16 #include <linux/ipv6.h>
17 #include <net/ip6_checksum.h>
18 #include <net/checksum.h>
19 
20 #include <linux/netfilter.h>
21 #include <linux/netfilter_ipv4.h>
22 #include <linux/netfilter_ipv6.h>
23 #include <net/netfilter/nf_conntrack_l4proto.h>
24 #include <net/netfilter/nf_conntrack_ecache.h>
25 #include <net/netfilter/nf_conntrack_timeout.h>
26 #include <net/netfilter/nf_log.h>
27 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
28 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
29 
30 static const unsigned int udp_timeouts[UDP_CT_MAX] = {
31 	[UDP_CT_UNREPLIED]	= 30*HZ,
32 	[UDP_CT_REPLIED]	= 180*HZ,
33 };
34 
udp_pernet(struct net * net)35 static inline struct nf_udp_net *udp_pernet(struct net *net)
36 {
37 	return &net->ct.nf_ct_proto.udp;
38 }
39 
udp_get_timeouts(struct net * net)40 static unsigned int *udp_get_timeouts(struct net *net)
41 {
42 	return udp_pernet(net)->timeouts;
43 }
44 
45 /* Returns verdict for packet, and may modify conntracktype */
udp_packet(struct nf_conn * ct,const struct sk_buff * skb,unsigned int dataoff,enum ip_conntrack_info ctinfo)46 static int udp_packet(struct nf_conn *ct,
47 		      const struct sk_buff *skb,
48 		      unsigned int dataoff,
49 		      enum ip_conntrack_info ctinfo)
50 {
51 	unsigned int *timeouts;
52 
53 	timeouts = nf_ct_timeout_lookup(ct);
54 	if (!timeouts)
55 		timeouts = udp_get_timeouts(nf_ct_net(ct));
56 
57 	/* If we've seen traffic both ways, this is some kind of UDP
58 	   stream.  Extend timeout. */
59 	if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
60 		nf_ct_refresh_acct(ct, ctinfo, skb,
61 				   timeouts[UDP_CT_REPLIED]);
62 		/* Also, more likely to be important, and not a probe */
63 		if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
64 			nf_conntrack_event_cache(IPCT_ASSURED, ct);
65 	} else {
66 		nf_ct_refresh_acct(ct, ctinfo, skb,
67 				   timeouts[UDP_CT_UNREPLIED]);
68 	}
69 	return NF_ACCEPT;
70 }
71 
72 /* Called when a new connection for this protocol found. */
udp_new(struct nf_conn * ct,const struct sk_buff * skb,unsigned int dataoff)73 static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
74 		    unsigned int dataoff)
75 {
76 	return true;
77 }
78 
79 #ifdef CONFIG_NF_CT_PROTO_UDPLITE
udplite_error_log(const struct sk_buff * skb,struct net * net,u8 pf,const char * msg)80 static void udplite_error_log(const struct sk_buff *skb, struct net *net,
81 			      u8 pf, const char *msg)
82 {
83 	nf_l4proto_log_invalid(skb, net, pf, IPPROTO_UDPLITE, "%s", msg);
84 }
85 
udplite_error(struct net * net,struct nf_conn * tmpl,struct sk_buff * skb,unsigned int dataoff,u8 pf,unsigned int hooknum)86 static int udplite_error(struct net *net, struct nf_conn *tmpl,
87 			 struct sk_buff *skb,
88 			 unsigned int dataoff,
89 			 u8 pf, unsigned int hooknum)
90 {
91 	unsigned int udplen = skb->len - dataoff;
92 	const struct udphdr *hdr;
93 	struct udphdr _hdr;
94 	unsigned int cscov;
95 
96 	/* Header is too small? */
97 	hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
98 	if (!hdr) {
99 		udplite_error_log(skb, net, pf, "short packet");
100 		return -NF_ACCEPT;
101 	}
102 
103 	cscov = ntohs(hdr->len);
104 	if (cscov == 0) {
105 		cscov = udplen;
106 	} else if (cscov < sizeof(*hdr) || cscov > udplen) {
107 		udplite_error_log(skb, net, pf, "invalid checksum coverage");
108 		return -NF_ACCEPT;
109 	}
110 
111 	/* UDPLITE mandates checksums */
112 	if (!hdr->check) {
113 		udplite_error_log(skb, net, pf, "checksum missing");
114 		return -NF_ACCEPT;
115 	}
116 
117 	/* Checksum invalid? Ignore. */
118 	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
119 	    nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
120 				pf)) {
121 		udplite_error_log(skb, net, pf, "bad checksum");
122 		return -NF_ACCEPT;
123 	}
124 
125 	return NF_ACCEPT;
126 }
127 #endif
128 
udp_error_log(const struct sk_buff * skb,struct net * net,u8 pf,const char * msg)129 static void udp_error_log(const struct sk_buff *skb, struct net *net,
130 			  u8 pf, const char *msg)
131 {
132 	nf_l4proto_log_invalid(skb, net, pf, IPPROTO_UDP, "%s", msg);
133 }
134 
udp_error(struct net * net,struct nf_conn * tmpl,struct sk_buff * skb,unsigned int dataoff,u_int8_t pf,unsigned int hooknum)135 static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
136 		     unsigned int dataoff,
137 		     u_int8_t pf,
138 		     unsigned int hooknum)
139 {
140 	unsigned int udplen = skb->len - dataoff;
141 	const struct udphdr *hdr;
142 	struct udphdr _hdr;
143 
144 	/* Header is too small? */
145 	hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
146 	if (hdr == NULL) {
147 		udp_error_log(skb, net, pf, "short packet");
148 		return -NF_ACCEPT;
149 	}
150 
151 	/* Truncated/malformed packets */
152 	if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
153 		udp_error_log(skb, net, pf, "truncated/malformed packet");
154 		return -NF_ACCEPT;
155 	}
156 
157 	/* Packet with no checksum */
158 	if (!hdr->check)
159 		return NF_ACCEPT;
160 
161 	/* Checksum invalid? Ignore.
162 	 * We skip checking packets on the outgoing path
163 	 * because the checksum is assumed to be correct.
164 	 * FIXME: Source route IP option packets --RR */
165 	if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
166 	    nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
167 		udp_error_log(skb, net, pf, "bad checksum");
168 		return -NF_ACCEPT;
169 	}
170 
171 	return NF_ACCEPT;
172 }
173 
174 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
175 
176 #include <linux/netfilter/nfnetlink.h>
177 #include <linux/netfilter/nfnetlink_cttimeout.h>
178 
udp_timeout_nlattr_to_obj(struct nlattr * tb[],struct net * net,void * data)179 static int udp_timeout_nlattr_to_obj(struct nlattr *tb[],
180 				     struct net *net, void *data)
181 {
182 	unsigned int *timeouts = data;
183 	struct nf_udp_net *un = udp_pernet(net);
184 
185 	if (!timeouts)
186 		timeouts = un->timeouts;
187 
188 	/* set default timeouts for UDP. */
189 	timeouts[UDP_CT_UNREPLIED] = un->timeouts[UDP_CT_UNREPLIED];
190 	timeouts[UDP_CT_REPLIED] = un->timeouts[UDP_CT_REPLIED];
191 
192 	if (tb[CTA_TIMEOUT_UDP_UNREPLIED]) {
193 		timeouts[UDP_CT_UNREPLIED] =
194 			ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_UNREPLIED])) * HZ;
195 	}
196 	if (tb[CTA_TIMEOUT_UDP_REPLIED]) {
197 		timeouts[UDP_CT_REPLIED] =
198 			ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_REPLIED])) * HZ;
199 	}
200 	return 0;
201 }
202 
203 static int
udp_timeout_obj_to_nlattr(struct sk_buff * skb,const void * data)204 udp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
205 {
206 	const unsigned int *timeouts = data;
207 
208 	if (nla_put_be32(skb, CTA_TIMEOUT_UDP_UNREPLIED,
209 			 htonl(timeouts[UDP_CT_UNREPLIED] / HZ)) ||
210 	    nla_put_be32(skb, CTA_TIMEOUT_UDP_REPLIED,
211 			 htonl(timeouts[UDP_CT_REPLIED] / HZ)))
212 		goto nla_put_failure;
213 	return 0;
214 
215 nla_put_failure:
216 	return -ENOSPC;
217 }
218 
219 static const struct nla_policy
220 udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = {
221        [CTA_TIMEOUT_UDP_UNREPLIED]	= { .type = NLA_U32 },
222        [CTA_TIMEOUT_UDP_REPLIED]	= { .type = NLA_U32 },
223 };
224 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
225 
226 #ifdef CONFIG_SYSCTL
227 static struct ctl_table udp_sysctl_table[] = {
228 	{
229 		.procname	= "nf_conntrack_udp_timeout",
230 		.maxlen		= sizeof(unsigned int),
231 		.mode		= 0644,
232 		.proc_handler	= proc_dointvec_jiffies,
233 	},
234 	{
235 		.procname	= "nf_conntrack_udp_timeout_stream",
236 		.maxlen		= sizeof(unsigned int),
237 		.mode		= 0644,
238 		.proc_handler	= proc_dointvec_jiffies,
239 	},
240 	{ }
241 };
242 #endif /* CONFIG_SYSCTL */
243 
udp_kmemdup_sysctl_table(struct nf_proto_net * pn,struct nf_udp_net * un)244 static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn,
245 				    struct nf_udp_net *un)
246 {
247 #ifdef CONFIG_SYSCTL
248 	if (pn->ctl_table)
249 		return 0;
250 	pn->ctl_table = kmemdup(udp_sysctl_table,
251 				sizeof(udp_sysctl_table),
252 				GFP_KERNEL);
253 	if (!pn->ctl_table)
254 		return -ENOMEM;
255 	pn->ctl_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
256 	pn->ctl_table[1].data = &un->timeouts[UDP_CT_REPLIED];
257 #endif
258 	return 0;
259 }
260 
udp_init_net(struct net * net,u_int16_t proto)261 static int udp_init_net(struct net *net, u_int16_t proto)
262 {
263 	struct nf_udp_net *un = udp_pernet(net);
264 	struct nf_proto_net *pn = &un->pn;
265 
266 	if (!pn->users) {
267 		int i;
268 
269 		for (i = 0; i < UDP_CT_MAX; i++)
270 			un->timeouts[i] = udp_timeouts[i];
271 	}
272 
273 	return udp_kmemdup_sysctl_table(pn, un);
274 }
275 
udp_get_net_proto(struct net * net)276 static struct nf_proto_net *udp_get_net_proto(struct net *net)
277 {
278 	return &net->ct.nf_ct_proto.udp.pn;
279 }
280 
281 const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
282 {
283 	.l3proto		= PF_INET,
284 	.l4proto		= IPPROTO_UDP,
285 	.allow_clash		= true,
286 	.packet			= udp_packet,
287 	.new			= udp_new,
288 	.error			= udp_error,
289 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
290 	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
291 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
292 	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
293 	.nla_policy		= nf_ct_port_nla_policy,
294 #endif
295 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
296 	.ctnl_timeout		= {
297 		.nlattr_to_obj	= udp_timeout_nlattr_to_obj,
298 		.obj_to_nlattr	= udp_timeout_obj_to_nlattr,
299 		.nlattr_max	= CTA_TIMEOUT_UDP_MAX,
300 		.obj_size	= sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
301 		.nla_policy	= udp_timeout_nla_policy,
302 	},
303 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
304 	.init_net		= udp_init_net,
305 	.get_net_proto		= udp_get_net_proto,
306 };
307 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
308 
309 #ifdef CONFIG_NF_CT_PROTO_UDPLITE
310 const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 =
311 {
312 	.l3proto		= PF_INET,
313 	.l4proto		= IPPROTO_UDPLITE,
314 	.allow_clash		= true,
315 	.packet			= udp_packet,
316 	.new			= udp_new,
317 	.error			= udplite_error,
318 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
319 	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
320 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
321 	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
322 	.nla_policy		= nf_ct_port_nla_policy,
323 #endif
324 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
325 	.ctnl_timeout		= {
326 		.nlattr_to_obj	= udp_timeout_nlattr_to_obj,
327 		.obj_to_nlattr	= udp_timeout_obj_to_nlattr,
328 		.nlattr_max	= CTA_TIMEOUT_UDP_MAX,
329 		.obj_size	= sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
330 		.nla_policy	= udp_timeout_nla_policy,
331 	},
332 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
333 	.init_net		= udp_init_net,
334 	.get_net_proto		= udp_get_net_proto,
335 };
336 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udplite4);
337 #endif
338 
339 const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 =
340 {
341 	.l3proto		= PF_INET6,
342 	.l4proto		= IPPROTO_UDP,
343 	.allow_clash		= true,
344 	.packet			= udp_packet,
345 	.new			= udp_new,
346 	.error			= udp_error,
347 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
348 	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
349 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
350 	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
351 	.nla_policy		= nf_ct_port_nla_policy,
352 #endif
353 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
354 	.ctnl_timeout		= {
355 		.nlattr_to_obj	= udp_timeout_nlattr_to_obj,
356 		.obj_to_nlattr	= udp_timeout_obj_to_nlattr,
357 		.nlattr_max	= CTA_TIMEOUT_UDP_MAX,
358 		.obj_size	= sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
359 		.nla_policy	= udp_timeout_nla_policy,
360 	},
361 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
362 	.init_net		= udp_init_net,
363 	.get_net_proto		= udp_get_net_proto,
364 };
365 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
366 
367 #ifdef CONFIG_NF_CT_PROTO_UDPLITE
368 const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 =
369 {
370 	.l3proto		= PF_INET6,
371 	.l4proto		= IPPROTO_UDPLITE,
372 	.allow_clash		= true,
373 	.packet			= udp_packet,
374 	.new			= udp_new,
375 	.error			= udplite_error,
376 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
377 	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
378 	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
379 	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
380 	.nla_policy		= nf_ct_port_nla_policy,
381 #endif
382 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
383 	.ctnl_timeout		= {
384 		.nlattr_to_obj	= udp_timeout_nlattr_to_obj,
385 		.obj_to_nlattr	= udp_timeout_obj_to_nlattr,
386 		.nlattr_max	= CTA_TIMEOUT_UDP_MAX,
387 		.obj_size	= sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
388 		.nla_policy	= udp_timeout_nla_policy,
389 	},
390 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
391 	.init_net		= udp_init_net,
392 	.get_net_proto		= udp_get_net_proto,
393 };
394 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udplite6);
395 #endif
396