162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6. 462306a36Sopenharmony_ci * See also net/ipv4/udplite.c 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Changes: 962306a36Sopenharmony_ci * Fixes: 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#define pr_fmt(fmt) "UDPLite6: " fmt 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/export.h> 1462306a36Sopenharmony_ci#include <linux/proc_fs.h> 1562306a36Sopenharmony_ci#include "udp_impl.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic int udplitev6_sk_init(struct sock *sk) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci udpv6_init_sock(sk); 2062306a36Sopenharmony_ci pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, " 2162306a36Sopenharmony_ci "please contact the netdev mailing list\n"); 2262306a36Sopenharmony_ci return 0; 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic int udplitev6_rcv(struct sk_buff *skb) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic int udplitev6_err(struct sk_buff *skb, 3162306a36Sopenharmony_ci struct inet6_skb_parm *opt, 3262306a36Sopenharmony_ci u8 type, u8 code, int offset, __be32 info) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci return __udp6_lib_err(skb, opt, type, code, offset, info, 3562306a36Sopenharmony_ci &udplite_table); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic const struct inet6_protocol udplitev6_protocol = { 3962306a36Sopenharmony_ci .handler = udplitev6_rcv, 4062306a36Sopenharmony_ci .err_handler = udplitev6_err, 4162306a36Sopenharmony_ci .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistruct proto udplitev6_prot = { 4562306a36Sopenharmony_ci .name = "UDPLITEv6", 4662306a36Sopenharmony_ci .owner = THIS_MODULE, 4762306a36Sopenharmony_ci .close = udp_lib_close, 4862306a36Sopenharmony_ci .connect = ip6_datagram_connect, 4962306a36Sopenharmony_ci .disconnect = udp_disconnect, 5062306a36Sopenharmony_ci .ioctl = udp_ioctl, 5162306a36Sopenharmony_ci .init = udplitev6_sk_init, 5262306a36Sopenharmony_ci .destroy = udpv6_destroy_sock, 5362306a36Sopenharmony_ci .setsockopt = udpv6_setsockopt, 5462306a36Sopenharmony_ci .getsockopt = udpv6_getsockopt, 5562306a36Sopenharmony_ci .sendmsg = udpv6_sendmsg, 5662306a36Sopenharmony_ci .recvmsg = udpv6_recvmsg, 5762306a36Sopenharmony_ci .hash = udp_lib_hash, 5862306a36Sopenharmony_ci .unhash = udp_lib_unhash, 5962306a36Sopenharmony_ci .rehash = udp_v6_rehash, 6062306a36Sopenharmony_ci .get_port = udp_v6_get_port, 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci .memory_allocated = &udp_memory_allocated, 6362306a36Sopenharmony_ci .per_cpu_fw_alloc = &udp_memory_per_cpu_fw_alloc, 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci .sysctl_mem = sysctl_udp_mem, 6662306a36Sopenharmony_ci .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), 6762306a36Sopenharmony_ci .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), 6862306a36Sopenharmony_ci .obj_size = sizeof(struct udp6_sock), 6962306a36Sopenharmony_ci .ipv6_pinfo_offset = offsetof(struct udp6_sock, inet6), 7062306a36Sopenharmony_ci .h.udp_table = &udplite_table, 7162306a36Sopenharmony_ci}; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic struct inet_protosw udplite6_protosw = { 7462306a36Sopenharmony_ci .type = SOCK_DGRAM, 7562306a36Sopenharmony_ci .protocol = IPPROTO_UDPLITE, 7662306a36Sopenharmony_ci .prot = &udplitev6_prot, 7762306a36Sopenharmony_ci .ops = &inet6_dgram_ops, 7862306a36Sopenharmony_ci .flags = INET_PROTOSW_PERMANENT, 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciint __init udplitev6_init(void) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci int ret; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci ret = inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE); 8662306a36Sopenharmony_ci if (ret) 8762306a36Sopenharmony_ci goto out; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci ret = inet6_register_protosw(&udplite6_protosw); 9062306a36Sopenharmony_ci if (ret) 9162306a36Sopenharmony_ci goto out_udplitev6_protocol; 9262306a36Sopenharmony_ciout: 9362306a36Sopenharmony_ci return ret; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ciout_udplitev6_protocol: 9662306a36Sopenharmony_ci inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE); 9762306a36Sopenharmony_ci goto out; 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_civoid udplitev6_exit(void) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci inet6_unregister_protosw(&udplite6_protosw); 10362306a36Sopenharmony_ci inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE); 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci#ifdef CONFIG_PROC_FS 10762306a36Sopenharmony_cistatic struct udp_seq_afinfo udplite6_seq_afinfo = { 10862306a36Sopenharmony_ci .family = AF_INET6, 10962306a36Sopenharmony_ci .udp_table = &udplite_table, 11062306a36Sopenharmony_ci}; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic int __net_init udplite6_proc_init_net(struct net *net) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci if (!proc_create_net_data("udplite6", 0444, net->proc_net, 11562306a36Sopenharmony_ci &udp6_seq_ops, sizeof(struct udp_iter_state), 11662306a36Sopenharmony_ci &udplite6_seq_afinfo)) 11762306a36Sopenharmony_ci return -ENOMEM; 11862306a36Sopenharmony_ci return 0; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic void __net_exit udplite6_proc_exit_net(struct net *net) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci remove_proc_entry("udplite6", net->proc_net); 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic struct pernet_operations udplite6_net_ops = { 12762306a36Sopenharmony_ci .init = udplite6_proc_init_net, 12862306a36Sopenharmony_ci .exit = udplite6_proc_exit_net, 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ciint __init udplite6_proc_init(void) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci return register_pernet_subsys(&udplite6_net_ops); 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_civoid udplite6_proc_exit(void) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci unregister_pernet_subsys(&udplite6_net_ops); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci#endif 141