blob: 59623cc56e8df57ddf791d382b1cd24c1cffc142 [file] [log] [blame]
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08001/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -08007 */
8
9#include <linux/types.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080010#include <linux/timer.h>
11#include <linux/module.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080012#include <linux/udp.h>
13#include <linux/seq_file.h>
14#include <linux/skbuff.h>
15#include <linux/ipv6.h>
16#include <net/ip6_checksum.h>
17#include <net/checksum.h>
Martin Josefssonf6180122006-11-29 02:35:01 +010018
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080019#include <linux/netfilter.h>
20#include <linux/netfilter_ipv4.h>
21#include <linux/netfilter_ipv6.h>
Martin Josefsson605dcad2006-11-29 02:35:06 +010022#include <net/netfilter/nf_conntrack_l4proto.h>
Martin Josefssonf6180122006-11-29 02:35:01 +010023#include <net/netfilter/nf_conntrack_ecache.h>
Patrick McHardyf01ffbd2007-12-17 22:38:49 -080024#include <net/netfilter/nf_log.h>
Christoph Paasch9d2493f2009-03-16 15:15:35 +010025#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080027
Pablo Neira Ayuso5a41db92012-02-28 02:23:28 +010028static unsigned int udp_timeouts[UDP_CT_MAX] = {
29 [UDP_CT_UNREPLIED] = 30*HZ,
30 [UDP_CT_REPLIED] = 180*HZ,
31};
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080032
Gao feng0ce490a2012-05-28 21:04:13 +000033static inline struct nf_udp_net *udp_pernet(struct net *net)
34{
35 return &net->ct.nf_ct_proto.udp;
36}
37
Jan Engelhardt09f263c2008-04-14 11:15:53 +020038static bool udp_pkt_to_tuple(const struct sk_buff *skb,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080039 unsigned int dataoff,
40 struct nf_conntrack_tuple *tuple)
41{
Jan Engelhardtda3f13c2008-01-31 04:52:29 -080042 const struct udphdr *hp;
43 struct udphdr _hdr;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080044
45 /* Actually only need first 8 bytes. */
46 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
47 if (hp == NULL)
Jan Engelhardt09f263c2008-04-14 11:15:53 +020048 return false;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080049
50 tuple->src.u.udp.port = hp->source;
51 tuple->dst.u.udp.port = hp->dest;
52
Jan Engelhardt09f263c2008-04-14 11:15:53 +020053 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080054}
55
Jan Engelhardt09f263c2008-04-14 11:15:53 +020056static bool udp_invert_tuple(struct nf_conntrack_tuple *tuple,
57 const struct nf_conntrack_tuple *orig)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080058{
59 tuple->src.u.udp.port = orig->dst.u.udp.port;
60 tuple->dst.u.udp.port = orig->src.u.udp.port;
Jan Engelhardt09f263c2008-04-14 11:15:53 +020061 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080062}
63
64/* Print out the per-protocol part of the tuple. */
65static int udp_print_tuple(struct seq_file *s,
66 const struct nf_conntrack_tuple *tuple)
67{
68 return seq_printf(s, "sport=%hu dport=%hu ",
69 ntohs(tuple->src.u.udp.port),
70 ntohs(tuple->dst.u.udp.port));
71}
72
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +010073static unsigned int *udp_get_timeouts(struct net *net)
74{
Gao feng0ce490a2012-05-28 21:04:13 +000075 return udp_pernet(net)->timeouts;
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +010076}
77
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080078/* Returns verdict for packet, and may modify conntracktype */
Patrick McHardyc88130b2008-01-31 04:42:11 -080079static int udp_packet(struct nf_conn *ct,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080080 const struct sk_buff *skb,
81 unsigned int dataoff,
82 enum ip_conntrack_info ctinfo,
Jan Engelhardt76108ce2008-10-08 11:35:00 +020083 u_int8_t pf,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +010084 unsigned int hooknum,
85 unsigned int *timeouts)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080086{
87 /* If we've seen traffic both ways, this is some kind of UDP
88 stream. Extend timeout. */
Patrick McHardyc88130b2008-01-31 04:42:11 -080089 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
Pablo Neira Ayuso5a41db92012-02-28 02:23:28 +010090 nf_ct_refresh_acct(ct, ctinfo, skb,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +010091 timeouts[UDP_CT_REPLIED]);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080092 /* Also, more likely to be important, and not a probe */
Patrick McHardyc88130b2008-01-31 04:42:11 -080093 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
Patrick McHardy858b31332010-02-03 13:48:53 +010094 nf_conntrack_event_cache(IPCT_ASSURED, ct);
Pablo Neira Ayuso5a41db92012-02-28 02:23:28 +010095 } else {
96 nf_ct_refresh_acct(ct, ctinfo, skb,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +010097 timeouts[UDP_CT_UNREPLIED]);
Pablo Neira Ayuso5a41db92012-02-28 02:23:28 +010098 }
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -080099 return NF_ACCEPT;
100}
101
102/* Called when a new connection for this protocol found. */
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200103static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +0100104 unsigned int dataoff, unsigned int *timeouts)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800105{
Jan Engelhardt09f263c2008-04-14 11:15:53 +0200106 return true;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800107}
108
Patrick McHardy8fea97e2010-02-15 17:45:08 +0100109static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
110 unsigned int dataoff, enum ip_conntrack_info *ctinfo,
Jan Engelhardt76108ce2008-10-08 11:35:00 +0200111 u_int8_t pf,
Patrick McHardy96f6bf82006-04-06 14:19:24 -0700112 unsigned int hooknum)
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800113{
114 unsigned int udplen = skb->len - dataoff;
Jan Engelhardtda3f13c2008-01-31 04:52:29 -0800115 const struct udphdr *hdr;
116 struct udphdr _hdr;
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800117
118 /* Header is too small? */
119 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
120 if (hdr == NULL) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200121 if (LOG_INVALID(net, IPPROTO_UDP))
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800122 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
123 "nf_ct_udp: short packet ");
124 return -NF_ACCEPT;
125 }
126
127 /* Truncated/malformed packets */
128 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200129 if (LOG_INVALID(net, IPPROTO_UDP))
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800130 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
131 "nf_ct_udp: truncated/malformed packet ");
132 return -NF_ACCEPT;
133 }
134
135 /* Packet with no checksum */
136 if (!hdr->check)
137 return NF_ACCEPT;
138
139 /* Checksum invalid? Ignore.
140 * We skip checking packets on the outgoing path
Patrick McHardy84fa7932006-08-29 16:44:56 -0700141 * because the checksum is assumed to be correct.
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800142 * FIXME: Source route IP option packets --RR */
Alexey Dobriyanc04d0552008-10-08 11:35:08 +0200143 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
Patrick McHardy96f6bf82006-04-06 14:19:24 -0700144 nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
Alexey Dobriyanc2a2c7e2008-10-08 11:35:08 +0200145 if (LOG_INVALID(net, IPPROTO_UDP))
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800146 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
147 "nf_ct_udp: bad UDP checksum ");
148 return -NF_ACCEPT;
149 }
150
151 return NF_ACCEPT;
152}
153
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100154#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
155
156#include <linux/netfilter/nfnetlink.h>
157#include <linux/netfilter/nfnetlink_cttimeout.h>
158
Gao feng8264deb2012-05-28 21:04:23 +0000159static int udp_timeout_nlattr_to_obj(struct nlattr *tb[],
160 struct net *net, void *data)
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100161{
162 unsigned int *timeouts = data;
Gao feng8264deb2012-05-28 21:04:23 +0000163 struct nf_udp_net *un = udp_pernet(net);
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100164
165 /* set default timeouts for UDP. */
Gao feng8264deb2012-05-28 21:04:23 +0000166 timeouts[UDP_CT_UNREPLIED] = un->timeouts[UDP_CT_UNREPLIED];
167 timeouts[UDP_CT_REPLIED] = un->timeouts[UDP_CT_REPLIED];
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100168
169 if (tb[CTA_TIMEOUT_UDP_UNREPLIED]) {
170 timeouts[UDP_CT_UNREPLIED] =
171 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_UNREPLIED])) * HZ;
172 }
173 if (tb[CTA_TIMEOUT_UDP_REPLIED]) {
174 timeouts[UDP_CT_REPLIED] =
175 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_REPLIED])) * HZ;
176 }
177 return 0;
178}
179
180static int
181udp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
182{
183 const unsigned int *timeouts = data;
184
David S. Miller3c60a172012-04-01 18:48:06 -0400185 if (nla_put_be32(skb, CTA_TIMEOUT_UDP_UNREPLIED,
186 htonl(timeouts[UDP_CT_UNREPLIED] / HZ)) ||
187 nla_put_be32(skb, CTA_TIMEOUT_UDP_REPLIED,
188 htonl(timeouts[UDP_CT_REPLIED] / HZ)))
189 goto nla_put_failure;
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100190 return 0;
191
192nla_put_failure:
193 return -ENOSPC;
194}
195
196static const struct nla_policy
197udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = {
198 [CTA_TIMEOUT_UDP_UNREPLIED] = { .type = NLA_U32 },
199 [CTA_TIMEOUT_UDP_REPLIED] = { .type = NLA_U32 },
200};
201#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
202
Patrick McHardy933a41e2006-11-29 02:35:18 +0100203#ifdef CONFIG_SYSCTL
Patrick McHardy933a41e2006-11-29 02:35:18 +0100204static struct ctl_table udp_sysctl_table[] = {
205 {
Patrick McHardy933a41e2006-11-29 02:35:18 +0100206 .procname = "nf_conntrack_udp_timeout",
Patrick McHardy933a41e2006-11-29 02:35:18 +0100207 .maxlen = sizeof(unsigned int),
208 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -0800209 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +0100210 },
211 {
Patrick McHardy933a41e2006-11-29 02:35:18 +0100212 .procname = "nf_conntrack_udp_timeout_stream",
Patrick McHardy933a41e2006-11-29 02:35:18 +0100213 .maxlen = sizeof(unsigned int),
214 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -0800215 .proc_handler = proc_dointvec_jiffies,
Patrick McHardy933a41e2006-11-29 02:35:18 +0100216 },
Eric W. Biedermanf8572d82009-11-05 13:32:03 -0800217 { }
Patrick McHardy933a41e2006-11-29 02:35:18 +0100218};
Patrick McHardya999e682006-11-29 02:35:20 +0100219#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
220static struct ctl_table udp_compat_sysctl_table[] = {
221 {
Patrick McHardya999e682006-11-29 02:35:20 +0100222 .procname = "ip_conntrack_udp_timeout",
Patrick McHardya999e682006-11-29 02:35:20 +0100223 .maxlen = sizeof(unsigned int),
224 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -0800225 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +0100226 },
227 {
Patrick McHardya999e682006-11-29 02:35:20 +0100228 .procname = "ip_conntrack_udp_timeout_stream",
Patrick McHardya999e682006-11-29 02:35:20 +0100229 .maxlen = sizeof(unsigned int),
230 .mode = 0644,
Alexey Dobriyan6d9f2392008-11-03 18:21:05 -0800231 .proc_handler = proc_dointvec_jiffies,
Patrick McHardya999e682006-11-29 02:35:20 +0100232 },
Eric W. Biedermanf8572d82009-11-05 13:32:03 -0800233 { }
Patrick McHardya999e682006-11-29 02:35:20 +0100234};
235#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
Patrick McHardy933a41e2006-11-29 02:35:18 +0100236#endif /* CONFIG_SYSCTL */
237
Gao fengdee73642012-06-21 04:36:44 +0000238static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn,
239 struct nf_udp_net *un)
Gao feng0ce490a2012-05-28 21:04:13 +0000240{
241#ifdef CONFIG_SYSCTL
Gao feng0ce490a2012-05-28 21:04:13 +0000242 if (pn->ctl_table)
243 return 0;
244 pn->ctl_table = kmemdup(udp_sysctl_table,
245 sizeof(udp_sysctl_table),
246 GFP_KERNEL);
247 if (!pn->ctl_table)
248 return -ENOMEM;
249 pn->ctl_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
250 pn->ctl_table[1].data = &un->timeouts[UDP_CT_REPLIED];
251#endif
252 return 0;
253}
254
Gao fengdee73642012-06-21 04:36:44 +0000255static int udp_kmemdup_compat_sysctl_table(struct nf_proto_net *pn,
256 struct nf_udp_net *un)
Gao feng0ce490a2012-05-28 21:04:13 +0000257{
258#ifdef CONFIG_SYSCTL
259#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
Gao feng0ce490a2012-05-28 21:04:13 +0000260 pn->ctl_compat_table = kmemdup(udp_compat_sysctl_table,
261 sizeof(udp_compat_sysctl_table),
262 GFP_KERNEL);
263 if (!pn->ctl_compat_table)
264 return -ENOMEM;
265
266 pn->ctl_compat_table[0].data = &un->timeouts[UDP_CT_UNREPLIED];
267 pn->ctl_compat_table[1].data = &un->timeouts[UDP_CT_REPLIED];
268#endif
269#endif
270 return 0;
271}
272
Gao fengdee73642012-06-21 04:36:44 +0000273static int udp_init_net(struct net *net, u_int16_t proto)
Gao feng0ce490a2012-05-28 21:04:13 +0000274{
275 int ret;
276 struct nf_udp_net *un = udp_pernet(net);
Gao fengdee73642012-06-21 04:36:44 +0000277 struct nf_proto_net *pn = &un->pn;
Gao feng0ce490a2012-05-28 21:04:13 +0000278
Gao fengdee73642012-06-21 04:36:44 +0000279 if (!pn->users) {
280 int i;
Gao feng0ce490a2012-05-28 21:04:13 +0000281
Gao fengdee73642012-06-21 04:36:44 +0000282 for (i = 0; i < UDP_CT_MAX; i++)
283 un->timeouts[i] = udp_timeouts[i];
Gao feng0ce490a2012-05-28 21:04:13 +0000284 }
Gao fengdee73642012-06-21 04:36:44 +0000285
286 if (proto == AF_INET) {
287 ret = udp_kmemdup_compat_sysctl_table(pn, un);
288 if (ret < 0)
289 return ret;
290
291 ret = udp_kmemdup_sysctl_table(pn, un);
292 if (ret < 0)
293 nf_ct_kfree_compat_sysctl_table(pn);
294 } else
295 ret = udp_kmemdup_sysctl_table(pn, un);
296
Gao feng0ce490a2012-05-28 21:04:13 +0000297 return ret;
298}
299
Pablo Neira Ayuso08911472012-06-29 05:23:24 +0000300static struct nf_proto_net *udp_get_net_proto(struct net *net)
301{
302 return &net->ct.nf_ct_proto.udp.pn;
303}
304
Patrick McHardy61075af2007-07-14 20:48:19 -0700305struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800306{
307 .l3proto = PF_INET,
Martin Josefsson605dcad2006-11-29 02:35:06 +0100308 .l4proto = IPPROTO_UDP,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800309 .name = "udp",
310 .pkt_to_tuple = udp_pkt_to_tuple,
311 .invert_tuple = udp_invert_tuple,
312 .print_tuple = udp_print_tuple,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800313 .packet = udp_packet,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +0100314 .get_timeouts = udp_get_timeouts,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800315 .new = udp_new,
Patrick McHardy96f6bf82006-04-06 14:19:24 -0700316 .error = udp_error,
Igor Maravićc0cd1152011-12-12 02:58:24 +0000317#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
Patrick McHardyfdf70832007-09-28 14:37:41 -0700318 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
319 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
Holger Eitzenbergera400c302009-03-25 21:53:39 +0100320 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
Patrick McHardyf73e9242007-09-28 14:39:55 -0700321 .nla_policy = nf_ct_port_nla_policy,
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -0800322#endif
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100323#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
324 .ctnl_timeout = {
325 .nlattr_to_obj = udp_timeout_nlattr_to_obj,
326 .obj_to_nlattr = udp_timeout_obj_to_nlattr,
327 .nlattr_max = CTA_TIMEOUT_UDP_MAX,
328 .obj_size = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
329 .nla_policy = udp_timeout_nla_policy,
330 },
331#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
Gao fengdee73642012-06-21 04:36:44 +0000332 .init_net = udp_init_net,
Pablo Neira Ayuso08911472012-06-29 05:23:24 +0000333 .get_net_proto = udp_get_net_proto,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800334};
Patrick McHardy13b18332006-12-02 22:11:25 -0800335EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800336
Patrick McHardy61075af2007-07-14 20:48:19 -0700337struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800338{
339 .l3proto = PF_INET6,
Martin Josefsson605dcad2006-11-29 02:35:06 +0100340 .l4proto = IPPROTO_UDP,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800341 .name = "udp",
342 .pkt_to_tuple = udp_pkt_to_tuple,
343 .invert_tuple = udp_invert_tuple,
344 .print_tuple = udp_print_tuple,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800345 .packet = udp_packet,
Pablo Neira Ayuso2c8503f2012-02-28 18:23:31 +0100346 .get_timeouts = udp_get_timeouts,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800347 .new = udp_new,
Patrick McHardy96f6bf82006-04-06 14:19:24 -0700348 .error = udp_error,
Igor Maravićc0cd1152011-12-12 02:58:24 +0000349#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
Patrick McHardyfdf70832007-09-28 14:37:41 -0700350 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
351 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
Holger Eitzenbergera400c302009-03-25 21:53:39 +0100352 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
Patrick McHardyf73e9242007-09-28 14:39:55 -0700353 .nla_policy = nf_ct_port_nla_policy,
Pablo Neira Ayusoc1d10ad2006-01-05 12:19:05 -0800354#endif
Pablo Neira Ayuso50978462012-02-28 19:13:48 +0100355#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
356 .ctnl_timeout = {
357 .nlattr_to_obj = udp_timeout_nlattr_to_obj,
358 .obj_to_nlattr = udp_timeout_obj_to_nlattr,
359 .nlattr_max = CTA_TIMEOUT_UDP_MAX,
360 .obj_size = sizeof(unsigned int) * CTA_TIMEOUT_UDP_MAX,
361 .nla_policy = udp_timeout_nla_policy,
362 },
363#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
Gao fengdee73642012-06-21 04:36:44 +0000364 .init_net = udp_init_net,
Pablo Neira Ayuso08911472012-06-29 05:23:24 +0000365 .get_net_proto = udp_get_net_proto,
Yasuyuki Kozakai9fb9cbb2005-11-09 16:38:16 -0800366};
Patrick McHardy13b18332006-12-02 22:11:25 -0800367EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);