| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  *  UDPLITE     An implementation of the UDP-Lite protocol (RFC 3828). | 
 | 3 |  * | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 4 |  *  Authors:    Gerrit Renker       <gerrit@erg.abdn.ac.uk> | 
 | 5 |  * | 
 | 6 |  *  Changes: | 
 | 7 |  *  Fixes: | 
 | 8 |  *		This program is free software; you can redistribute it and/or | 
 | 9 |  *		modify it under the terms of the GNU General Public License | 
 | 10 |  *		as published by the Free Software Foundation; either version | 
 | 11 |  *		2 of the License, or (at your option) any later version. | 
 | 12 |  */ | 
| Joe Perches | afd46503 | 2012-03-12 07:03:32 +0000 | [diff] [blame] | 13 |  | 
 | 14 | #define pr_fmt(fmt) "UDPLite: " fmt | 
 | 15 |  | 
| Paul Gortmaker | bc3b2d7 | 2011-07-15 11:47:34 -0400 | [diff] [blame] | 16 | #include <linux/export.h> | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 17 | #include "udp_impl.h" | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 18 |  | 
| Eric Dumazet | f86dcc5 | 2009-10-07 00:37:59 +0000 | [diff] [blame] | 19 | struct udp_table 	udplite_table __read_mostly; | 
| Eric Dumazet | 645ca70 | 2008-10-29 01:41:45 -0700 | [diff] [blame] | 20 | EXPORT_SYMBOL(udplite_table); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 21 |  | 
| Adrian Bunk | f5b99bc | 2006-11-30 17:22:29 -0800 | [diff] [blame] | 22 | static int udplite_rcv(struct sk_buff *skb) | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 23 | { | 
| Eric Dumazet | 645ca70 | 2008-10-29 01:41:45 -0700 | [diff] [blame] | 24 | 	return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 25 | } | 
 | 26 |  | 
| Adrian Bunk | f5b99bc | 2006-11-30 17:22:29 -0800 | [diff] [blame] | 27 | static void udplite_err(struct sk_buff *skb, u32 info) | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 28 | { | 
| Eric Dumazet | 645ca70 | 2008-10-29 01:41:45 -0700 | [diff] [blame] | 29 | 	__udp4_lib_err(skb, info, &udplite_table); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 30 | } | 
 | 31 |  | 
| Alexey Dobriyan | 3261309 | 2009-09-14 12:21:47 +0000 | [diff] [blame] | 32 | static const struct net_protocol udplite_protocol = { | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 33 | 	.handler	= udplite_rcv, | 
 | 34 | 	.err_handler	= udplite_err, | 
 | 35 | 	.no_policy	= 1, | 
| Denis V. Lunev | 92f1fec | 2008-03-24 15:34:06 -0700 | [diff] [blame] | 36 | 	.netns_ok	= 1, | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 37 | }; | 
 | 38 |  | 
 | 39 | struct proto 	udplite_prot = { | 
 | 40 | 	.name		   = "UDP-Lite", | 
 | 41 | 	.owner		   = THIS_MODULE, | 
 | 42 | 	.close		   = udp_lib_close, | 
 | 43 | 	.connect	   = ip4_datagram_connect, | 
 | 44 | 	.disconnect	   = udp_disconnect, | 
 | 45 | 	.ioctl		   = udp_ioctl, | 
 | 46 | 	.init		   = udplite_sk_init, | 
 | 47 | 	.destroy	   = udp_destroy_sock, | 
 | 48 | 	.setsockopt	   = udp_setsockopt, | 
 | 49 | 	.getsockopt	   = udp_getsockopt, | 
 | 50 | 	.sendmsg	   = udp_sendmsg, | 
 | 51 | 	.recvmsg	   = udp_recvmsg, | 
 | 52 | 	.sendpage	   = udp_sendpage, | 
 | 53 | 	.backlog_rcv	   = udp_queue_rcv_skb, | 
 | 54 | 	.hash		   = udp_lib_hash, | 
 | 55 | 	.unhash		   = udp_lib_unhash, | 
| Pavel Emelyanov | 6ba5a3c | 2008-03-22 16:51:21 -0700 | [diff] [blame] | 56 | 	.get_port	   = udp_v4_get_port, | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 57 | 	.obj_size	   = sizeof(struct udp_sock), | 
| Eric Dumazet | 271b72c | 2008-10-29 02:11:14 -0700 | [diff] [blame] | 58 | 	.slab_flags	   = SLAB_DESTROY_BY_RCU, | 
| Eric Dumazet | 645ca70 | 2008-10-29 01:41:45 -0700 | [diff] [blame] | 59 | 	.h.udp_table	   = &udplite_table, | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 60 | #ifdef CONFIG_COMPAT | 
 | 61 | 	.compat_setsockopt = compat_udp_setsockopt, | 
 | 62 | 	.compat_getsockopt = compat_udp_getsockopt, | 
 | 63 | #endif | 
| Octavian Purdila | fcbdf09 | 2010-12-16 14:26:56 -0800 | [diff] [blame] | 64 | 	.clear_sk	   = sk_prot_clear_portaddr_nulls, | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 65 | }; | 
| Eric Dumazet | 4bc2f18 | 2010-07-09 21:22:10 +0000 | [diff] [blame] | 66 | EXPORT_SYMBOL(udplite_prot); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 67 |  | 
 | 68 | static struct inet_protosw udplite4_protosw = { | 
 | 69 | 	.type		=  SOCK_DGRAM, | 
 | 70 | 	.protocol	=  IPPROTO_UDPLITE, | 
 | 71 | 	.prot		=  &udplite_prot, | 
 | 72 | 	.ops		=  &inet_dgram_ops, | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 73 | 	.no_check	=  0,		/* must checksum (RFC 3828) */ | 
 | 74 | 	.flags		=  INET_PROTOSW_PERMANENT, | 
 | 75 | }; | 
 | 76 |  | 
 | 77 | #ifdef CONFIG_PROC_FS | 
| Arjan van de Ven | 73cb88e | 2011-10-30 06:46:30 +0000 | [diff] [blame] | 78 |  | 
 | 79 | static const struct file_operations udplite_afinfo_seq_fops = { | 
 | 80 | 	.owner    = THIS_MODULE, | 
 | 81 | 	.open     = udp_seq_open, | 
 | 82 | 	.read     = seq_read, | 
 | 83 | 	.llseek   = seq_lseek, | 
 | 84 | 	.release  = seq_release_net | 
 | 85 | }; | 
 | 86 |  | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 87 | static struct udp_seq_afinfo udplite4_seq_afinfo = { | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 88 | 	.name		= "udplite", | 
 | 89 | 	.family		= AF_INET, | 
| Eric Dumazet | 645ca70 | 2008-10-29 01:41:45 -0700 | [diff] [blame] | 90 | 	.udp_table 	= &udplite_table, | 
| Arjan van de Ven | 73cb88e | 2011-10-30 06:46:30 +0000 | [diff] [blame] | 91 | 	.seq_fops	= &udplite_afinfo_seq_fops, | 
| Denis V. Lunev | dda6192 | 2008-03-28 18:24:26 -0700 | [diff] [blame] | 92 | 	.seq_ops	= { | 
 | 93 | 		.show		= udp4_seq_show, | 
 | 94 | 	}, | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 95 | }; | 
| Pavel Emelyanov | ff2bac6 | 2008-03-24 14:56:34 -0700 | [diff] [blame] | 96 |  | 
| Alexey Dobriyan | 2c8c1e7 | 2010-01-17 03:35:32 +0000 | [diff] [blame] | 97 | static int __net_init udplite4_proc_init_net(struct net *net) | 
| Pavel Emelyanov | 84c375a | 2008-03-24 14:56:57 -0700 | [diff] [blame] | 98 | { | 
 | 99 | 	return udp_proc_register(net, &udplite4_seq_afinfo); | 
 | 100 | } | 
 | 101 |  | 
| Alexey Dobriyan | 2c8c1e7 | 2010-01-17 03:35:32 +0000 | [diff] [blame] | 102 | static void __net_exit udplite4_proc_exit_net(struct net *net) | 
| Pavel Emelyanov | 84c375a | 2008-03-24 14:56:57 -0700 | [diff] [blame] | 103 | { | 
 | 104 | 	udp_proc_unregister(net, &udplite4_seq_afinfo); | 
 | 105 | } | 
 | 106 |  | 
 | 107 | static struct pernet_operations udplite4_net_ops = { | 
 | 108 | 	.init = udplite4_proc_init_net, | 
 | 109 | 	.exit = udplite4_proc_exit_net, | 
 | 110 | }; | 
 | 111 |  | 
| Pavel Emelyanov | ff2bac6 | 2008-03-24 14:56:34 -0700 | [diff] [blame] | 112 | static __init int udplite4_proc_init(void) | 
 | 113 | { | 
| Pavel Emelyanov | 84c375a | 2008-03-24 14:56:57 -0700 | [diff] [blame] | 114 | 	return register_pernet_subsys(&udplite4_net_ops); | 
| Pavel Emelyanov | ff2bac6 | 2008-03-24 14:56:34 -0700 | [diff] [blame] | 115 | } | 
 | 116 | #else | 
 | 117 | static inline int udplite4_proc_init(void) | 
 | 118 | { | 
 | 119 | 	return 0; | 
 | 120 | } | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 121 | #endif | 
 | 122 |  | 
 | 123 | void __init udplite4_register(void) | 
 | 124 | { | 
| Eric Dumazet | f86dcc5 | 2009-10-07 00:37:59 +0000 | [diff] [blame] | 125 | 	udp_table_init(&udplite_table, "UDP-Lite"); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 126 | 	if (proto_register(&udplite_prot, 1)) | 
 | 127 | 		goto out_register_err; | 
 | 128 |  | 
 | 129 | 	if (inet_add_protocol(&udplite_protocol, IPPROTO_UDPLITE) < 0) | 
 | 130 | 		goto out_unregister_proto; | 
 | 131 |  | 
 | 132 | 	inet_register_protosw(&udplite4_protosw); | 
 | 133 |  | 
| Pavel Emelyanov | ff2bac6 | 2008-03-24 14:56:34 -0700 | [diff] [blame] | 134 | 	if (udplite4_proc_init()) | 
| Joe Perches | 058bd4d | 2012-03-11 18:36:11 +0000 | [diff] [blame] | 135 | 		pr_err("%s: Cannot register /proc!\n", __func__); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 136 | 	return; | 
 | 137 |  | 
 | 138 | out_unregister_proto: | 
 | 139 | 	proto_unregister(&udplite_prot); | 
 | 140 | out_register_err: | 
| Joe Perches | 058bd4d | 2012-03-11 18:36:11 +0000 | [diff] [blame] | 141 | 	pr_crit("%s: Cannot add UDP-Lite protocol\n", __func__); | 
| Gerrit Renker | ba4e58e | 2006-11-27 11:10:57 -0800 | [diff] [blame] | 142 | } |