1*db8dac20SDavid S. Miller /* 2*db8dac20SDavid S. Miller * UDPLITE An implementation of the UDP-Lite protocol (RFC 3828). 3*db8dac20SDavid S. Miller * 4*db8dac20SDavid S. Miller * Version: $Id: udplite.c,v 1.25 2006/10/19 07:22:36 gerrit Exp $ 5*db8dac20SDavid S. Miller * 6*db8dac20SDavid S. Miller * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> 7*db8dac20SDavid S. Miller * 8*db8dac20SDavid S. Miller * Changes: 9*db8dac20SDavid S. Miller * Fixes: 10*db8dac20SDavid S. Miller * This program is free software; you can redistribute it and/or 11*db8dac20SDavid S. Miller * modify it under the terms of the GNU General Public License 12*db8dac20SDavid S. Miller * as published by the Free Software Foundation; either version 13*db8dac20SDavid S. Miller * 2 of the License, or (at your option) any later version. 14*db8dac20SDavid S. Miller */ 15*db8dac20SDavid S. Miller #include "udp_impl.h" 16*db8dac20SDavid S. Miller DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics) __read_mostly; 17*db8dac20SDavid S. Miller 18*db8dac20SDavid S. Miller struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; 19*db8dac20SDavid S. Miller 20*db8dac20SDavid S. Miller int udplite_get_port(struct sock *sk, unsigned short p, 21*db8dac20SDavid S. Miller int (*c)(const struct sock *, const struct sock *)) 22*db8dac20SDavid S. Miller { 23*db8dac20SDavid S. Miller return __udp_lib_get_port(sk, p, udplite_hash, c); 24*db8dac20SDavid S. Miller } 25*db8dac20SDavid S. Miller 26*db8dac20SDavid S. Miller static int udplite_v4_get_port(struct sock *sk, unsigned short snum) 27*db8dac20SDavid S. Miller { 28*db8dac20SDavid S. Miller return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal); 29*db8dac20SDavid S. Miller } 30*db8dac20SDavid S. Miller 31*db8dac20SDavid S. Miller static int udplite_rcv(struct sk_buff *skb) 32*db8dac20SDavid S. Miller { 33*db8dac20SDavid S. Miller return __udp4_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE); 34*db8dac20SDavid S. Miller } 35*db8dac20SDavid S. Miller 36*db8dac20SDavid S. Miller static void udplite_err(struct sk_buff *skb, u32 info) 37*db8dac20SDavid S. Miller { 38*db8dac20SDavid S. Miller __udp4_lib_err(skb, info, udplite_hash); 39*db8dac20SDavid S. Miller } 40*db8dac20SDavid S. Miller 41*db8dac20SDavid S. Miller static struct net_protocol udplite_protocol = { 42*db8dac20SDavid S. Miller .handler = udplite_rcv, 43*db8dac20SDavid S. Miller .err_handler = udplite_err, 44*db8dac20SDavid S. Miller .no_policy = 1, 45*db8dac20SDavid S. Miller }; 46*db8dac20SDavid S. Miller 47*db8dac20SDavid S. Miller DEFINE_PROTO_INUSE(udplite) 48*db8dac20SDavid S. Miller 49*db8dac20SDavid S. Miller struct proto udplite_prot = { 50*db8dac20SDavid S. Miller .name = "UDP-Lite", 51*db8dac20SDavid S. Miller .owner = THIS_MODULE, 52*db8dac20SDavid S. Miller .close = udp_lib_close, 53*db8dac20SDavid S. Miller .connect = ip4_datagram_connect, 54*db8dac20SDavid S. Miller .disconnect = udp_disconnect, 55*db8dac20SDavid S. Miller .ioctl = udp_ioctl, 56*db8dac20SDavid S. Miller .init = udplite_sk_init, 57*db8dac20SDavid S. Miller .destroy = udp_destroy_sock, 58*db8dac20SDavid S. Miller .setsockopt = udp_setsockopt, 59*db8dac20SDavid S. Miller .getsockopt = udp_getsockopt, 60*db8dac20SDavid S. Miller .sendmsg = udp_sendmsg, 61*db8dac20SDavid S. Miller .recvmsg = udp_recvmsg, 62*db8dac20SDavid S. Miller .sendpage = udp_sendpage, 63*db8dac20SDavid S. Miller .backlog_rcv = udp_queue_rcv_skb, 64*db8dac20SDavid S. Miller .hash = udp_lib_hash, 65*db8dac20SDavid S. Miller .unhash = udp_lib_unhash, 66*db8dac20SDavid S. Miller .get_port = udplite_v4_get_port, 67*db8dac20SDavid S. Miller .obj_size = sizeof(struct udp_sock), 68*db8dac20SDavid S. Miller #ifdef CONFIG_COMPAT 69*db8dac20SDavid S. Miller .compat_setsockopt = compat_udp_setsockopt, 70*db8dac20SDavid S. Miller .compat_getsockopt = compat_udp_getsockopt, 71*db8dac20SDavid S. Miller #endif 72*db8dac20SDavid S. Miller REF_PROTO_INUSE(udplite) 73*db8dac20SDavid S. Miller }; 74*db8dac20SDavid S. Miller 75*db8dac20SDavid S. Miller static struct inet_protosw udplite4_protosw = { 76*db8dac20SDavid S. Miller .type = SOCK_DGRAM, 77*db8dac20SDavid S. Miller .protocol = IPPROTO_UDPLITE, 78*db8dac20SDavid S. Miller .prot = &udplite_prot, 79*db8dac20SDavid S. Miller .ops = &inet_dgram_ops, 80*db8dac20SDavid S. Miller .capability = -1, 81*db8dac20SDavid S. Miller .no_check = 0, /* must checksum (RFC 3828) */ 82*db8dac20SDavid S. Miller .flags = INET_PROTOSW_PERMANENT, 83*db8dac20SDavid S. Miller }; 84*db8dac20SDavid S. Miller 85*db8dac20SDavid S. Miller #ifdef CONFIG_PROC_FS 86*db8dac20SDavid S. Miller static struct file_operations udplite4_seq_fops; 87*db8dac20SDavid S. Miller static struct udp_seq_afinfo udplite4_seq_afinfo = { 88*db8dac20SDavid S. Miller .owner = THIS_MODULE, 89*db8dac20SDavid S. Miller .name = "udplite", 90*db8dac20SDavid S. Miller .family = AF_INET, 91*db8dac20SDavid S. Miller .hashtable = udplite_hash, 92*db8dac20SDavid S. Miller .seq_show = udp4_seq_show, 93*db8dac20SDavid S. Miller .seq_fops = &udplite4_seq_fops, 94*db8dac20SDavid S. Miller }; 95*db8dac20SDavid S. Miller #endif 96*db8dac20SDavid S. Miller 97*db8dac20SDavid S. Miller void __init udplite4_register(void) 98*db8dac20SDavid S. Miller { 99*db8dac20SDavid S. Miller if (proto_register(&udplite_prot, 1)) 100*db8dac20SDavid S. Miller goto out_register_err; 101*db8dac20SDavid S. Miller 102*db8dac20SDavid S. Miller if (inet_add_protocol(&udplite_protocol, IPPROTO_UDPLITE) < 0) 103*db8dac20SDavid S. Miller goto out_unregister_proto; 104*db8dac20SDavid S. Miller 105*db8dac20SDavid S. Miller inet_register_protosw(&udplite4_protosw); 106*db8dac20SDavid S. Miller 107*db8dac20SDavid S. Miller #ifdef CONFIG_PROC_FS 108*db8dac20SDavid S. Miller if (udp_proc_register(&udplite4_seq_afinfo)) /* udplite4_proc_init() */ 109*db8dac20SDavid S. Miller printk(KERN_ERR "%s: Cannot register /proc!\n", __func__); 110*db8dac20SDavid S. Miller #endif 111*db8dac20SDavid S. Miller return; 112*db8dac20SDavid S. Miller 113*db8dac20SDavid S. Miller out_unregister_proto: 114*db8dac20SDavid S. Miller proto_unregister(&udplite_prot); 115*db8dac20SDavid S. Miller out_register_err: 116*db8dac20SDavid S. Miller printk(KERN_CRIT "%s: Cannot add UDP-Lite protocol.\n", __func__); 117*db8dac20SDavid S. Miller } 118*db8dac20SDavid S. Miller 119*db8dac20SDavid S. Miller EXPORT_SYMBOL(udplite_hash); 120*db8dac20SDavid S. Miller EXPORT_SYMBOL(udplite_prot); 121*db8dac20SDavid S. Miller EXPORT_SYMBOL(udplite_get_port); 122