10 #include <linux/types.h>
12 #include <linux/module.h>
13 #include <linux/udp.h>
16 #include <linux/ipv6.h>
20 #include <linux/netfilter.h>
21 #include <linux/netfilter_ipv4.h>
22 #include <linux/netfilter_ipv6.h>
49 static bool udplite_pkt_to_tuple(
const struct sk_buff *
skb,
56 hp = skb_header_pointer(skb, dataoff,
sizeof(_hdr), &_hdr);
60 tuple->
src.u.udp.port = hp->source;
61 tuple->
dst.u.udp.port = hp->dest;
68 tuple->
src.u.udp.port = orig->
dst.u.udp.port;
69 tuple->
dst.u.udp.port = orig->
src.u.udp.port;
74 static int udplite_print_tuple(
struct seq_file *
s,
82 static unsigned int *udplite_get_timeouts(
struct net *
net)
84 return udplite_pernet(net)->timeouts;
88 static int udplite_packet(
struct nf_conn *
ct,
94 unsigned int *timeouts)
99 nf_ct_refresh_acct(ct, ctinfo, skb,
105 nf_ct_refresh_acct(ct, ctinfo, skb,
112 static bool udplite_new(
struct nf_conn *ct,
const struct sk_buff *skb,
113 unsigned int dataoff,
unsigned int *timeouts)
118 static int udplite_error(
struct net *
net,
struct nf_conn *tmpl,
120 unsigned int dataoff,
123 unsigned int hooknum)
125 unsigned int udplen = skb->
len - dataoff;
131 hdr = skb_header_pointer(skb, dataoff,
sizeof(_hdr), &_hdr);
135 "nf_ct_udplite: short packet ");
142 else if (cscov <
sizeof(*hdr) || cscov > udplen) {
145 "nf_ct_udplite: invalid checksum coverage ");
153 "nf_ct_udplite: checksum missing ");
159 nf_checksum_partial(skb, hooknum, dataoff, cscov,
IPPROTO_UDP,
163 "nf_ct_udplite: bad UDPLite checksum ");
170 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
172 #include <linux/netfilter/nfnetlink.h>
175 static int udplite_timeout_nlattr_to_obj(
struct nlattr *
tb[],
176 struct net *net,
void *
data)
178 unsigned int *timeouts =
data;
187 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_UNREPLIED])) *
HZ;
191 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_REPLIED])) *
HZ;
197 udplite_timeout_obj_to_nlattr(
struct sk_buff *skb,
const void *data)
199 const unsigned int *timeouts =
data;
201 if (nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_UNREPLIED,
203 nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_REPLIED,
205 goto nla_put_failure;
220 static struct ctl_table udplite_sysctl_table[] = {
222 .
procname =
"nf_conntrack_udplite_timeout",
223 .maxlen =
sizeof(
unsigned int),
228 .procname =
"nf_conntrack_udplite_timeout_stream",
229 .maxlen =
sizeof(
unsigned int),
244 pn->ctl_table =
kmemdup(udplite_sysctl_table,
245 sizeof(udplite_sysctl_table),
265 un->
timeouts[i] = udplite_timeouts[i];
268 return udplite_kmemdup_sysctl_table(pn, un);
276 .pkt_to_tuple = udplite_pkt_to_tuple,
277 .invert_tuple = udplite_invert_tuple,
278 .print_tuple = udplite_print_tuple,
279 .packet = udplite_packet,
280 .get_timeouts = udplite_get_timeouts,
282 .error = udplite_error,
283 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
289 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
291 .nlattr_to_obj = udplite_timeout_nlattr_to_obj,
292 .obj_to_nlattr = udplite_timeout_obj_to_nlattr,
294 .obj_size =
sizeof(
unsigned int) *
299 .
net_id = &udplite_net_id,
308 .pkt_to_tuple = udplite_pkt_to_tuple,
309 .invert_tuple = udplite_invert_tuple,
310 .print_tuple = udplite_print_tuple,
311 .packet = udplite_packet,
312 .get_timeouts = udplite_get_timeouts,
314 .error = udplite_error,
315 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
321 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
323 .nlattr_to_obj = udplite_timeout_nlattr_to_obj,
324 .obj_to_nlattr = udplite_timeout_obj_to_nlattr,
326 .obj_size =
sizeof(
unsigned int) *
331 .
net_id = &udplite_net_id,
335 static int udplite_net_init(
struct net *net)
340 &nf_conntrack_l4proto_udplite4);
342 pr_err(
"nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
346 &nf_conntrack_l4proto_udplite6);
348 pr_err(
"nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
349 goto cleanup_udplite4;
359 static void udplite_net_exit(
struct net *net)
366 .init = udplite_net_init,
367 .exit = udplite_net_exit,
368 .id = &udplite_net_id,
372 static int __init nf_conntrack_proto_udplite_init(
void)
377 static void __exit nf_conntrack_proto_udplite_exit(
void)