9 #include <linux/types.h>
11 #include <linux/module.h>
12 #include <linux/udp.h>
15 #include <linux/ipv6.h>
19 #include <linux/netfilter.h>
20 #include <linux/netfilter_ipv4.h>
21 #include <linux/netfilter_ipv6.h>
28 static unsigned int udp_timeouts[
UDP_CT_MAX] = {
35 return &net->ct.nf_ct_proto.udp;
38 static bool udp_pkt_to_tuple(
const struct sk_buff *
skb,
46 hp = skb_header_pointer(skb, dataoff,
sizeof(_hdr), &_hdr);
50 tuple->
src.u.udp.port = hp->source;
51 tuple->
dst.u.udp.port = hp->dest;
59 tuple->
src.u.udp.port = orig->
dst.u.udp.port;
60 tuple->
dst.u.udp.port = orig->
src.u.udp.port;
65 static int udp_print_tuple(
struct seq_file *
s,
73 static unsigned int *udp_get_timeouts(
struct net *
net)
75 return udp_pernet(net)->timeouts;
85 unsigned int *timeouts)
90 nf_ct_refresh_acct(ct, ctinfo, skb,
96 nf_ct_refresh_acct(ct, ctinfo, skb,
103 static bool udp_new(
struct nf_conn *ct,
const struct sk_buff *skb,
104 unsigned int dataoff,
unsigned int *timeouts)
112 unsigned int hooknum)
114 unsigned int udplen = skb->
len - dataoff;
119 hdr = skb_header_pointer(skb, dataoff,
sizeof(_hdr), &_hdr);
123 "nf_ct_udp: short packet ");
128 if (
ntohs(hdr->len) > udplen ||
ntohs(hdr->len) <
sizeof(*hdr)) {
131 "nf_ct_udp: truncated/malformed packet ");
144 nf_checksum(skb, hooknum, dataoff,
IPPROTO_UDP, pf)) {
147 "nf_ct_udp: bad UDP checksum ");
154 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
156 #include <linux/netfilter/nfnetlink.h>
159 static int udp_timeout_nlattr_to_obj(
struct nlattr *
tb[],
160 struct net *net,
void *
data)
162 unsigned int *timeouts =
data;
171 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_UNREPLIED])) *
HZ;
175 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDP_REPLIED])) *
HZ;
181 udp_timeout_obj_to_nlattr(
struct sk_buff *skb,
const void *data)
183 const unsigned int *timeouts =
data;
185 if (nla_put_be32(skb, CTA_TIMEOUT_UDP_UNREPLIED,
187 nla_put_be32(skb, CTA_TIMEOUT_UDP_REPLIED,
189 goto nla_put_failure;
204 static struct ctl_table udp_sysctl_table[] = {
206 .
procname =
"nf_conntrack_udp_timeout",
207 .maxlen =
sizeof(
unsigned int),
212 .procname =
"nf_conntrack_udp_timeout_stream",
213 .maxlen =
sizeof(
unsigned int),
219 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
220 static struct ctl_table udp_compat_sysctl_table[] = {
222 .
procname =
"ip_conntrack_udp_timeout",
223 .maxlen =
sizeof(
unsigned int),
228 .procname =
"ip_conntrack_udp_timeout_stream",
229 .maxlen =
sizeof(
unsigned int),
244 pn->ctl_table =
kmemdup(udp_sysctl_table,
245 sizeof(udp_sysctl_table),
255 static int udp_kmemdup_compat_sysctl_table(
struct nf_proto_net *pn,
259 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
260 pn->ctl_compat_table =
kmemdup(udp_compat_sysctl_table,
261 sizeof(udp_compat_sysctl_table),
263 if (!pn->ctl_compat_table)
287 ret = udp_kmemdup_compat_sysctl_table(pn, un);
291 ret = udp_kmemdup_sysctl_table(pn, un);
293 nf_ct_kfree_compat_sysctl_table(pn);
295 ret = udp_kmemdup_sysctl_table(pn, un);
300 static struct nf_proto_net *udp_get_net_proto(
struct net *net)
302 return &net->ct.nf_ct_proto.udp.pn;
310 .pkt_to_tuple = udp_pkt_to_tuple,
311 .invert_tuple = udp_invert_tuple,
312 .print_tuple = udp_print_tuple,
313 .packet = udp_packet,
314 .get_timeouts = udp_get_timeouts,
317 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
323 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
325 .nlattr_to_obj = udp_timeout_nlattr_to_obj,
326 .obj_to_nlattr = udp_timeout_obj_to_nlattr,
342 .pkt_to_tuple = udp_pkt_to_tuple,
343 .invert_tuple = udp_invert_tuple,
344 .print_tuple = udp_print_tuple,
345 .packet = udp_packet,
346 .get_timeouts = udp_get_timeouts,
349 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
355 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
357 .nlattr_to_obj = udp_timeout_nlattr_to_obj,
358 .obj_to_nlattr = udp_timeout_obj_to_nlattr,