GNU Linux-libre 4.14.330-gnu1
[releases.git] / net / ipv6 / udplite.c
1 /*
2  *  UDPLITEv6   An implementation of the UDP-Lite protocol over IPv6.
3  *              See also net/ipv4/udplite.c
4  *
5  *  Authors:    Gerrit Renker       <gerrit@erg.abdn.ac.uk>
6  *
7  *  Changes:
8  *  Fixes:
9  *              This program is free software; you can redistribute it and/or
10  *              modify it under the terms of the GNU General Public License
11  *              as published by the Free Software Foundation; either version
12  *              2 of the License, or (at your option) any later version.
13  */
14 #include <linux/export.h>
15 #include "udp_impl.h"
16
17 static int udplitev6_sk_init(struct sock *sk)
18 {
19         udpv6_init_sock(sk);
20         udp_sk(sk)->pcflag = UDPLITE_BIT;
21         return 0;
22 }
23
24 static int udplitev6_rcv(struct sk_buff *skb)
25 {
26         return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
27 }
28
29 static void udplitev6_err(struct sk_buff *skb,
30                           struct inet6_skb_parm *opt,
31                           u8 type, u8 code, int offset, __be32 info)
32 {
33         __udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table);
34 }
35
36 static const struct inet6_protocol udplitev6_protocol = {
37         .handler        =       udplitev6_rcv,
38         .err_handler    =       udplitev6_err,
39         .flags          =       INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
40 };
41
42 struct proto udplitev6_prot = {
43         .name              = "UDPLITEv6",
44         .owner             = THIS_MODULE,
45         .close             = udp_lib_close,
46         .connect           = ip6_datagram_connect,
47         .disconnect        = udp_disconnect,
48         .ioctl             = udp_ioctl,
49         .init              = udplitev6_sk_init,
50         .destroy           = udpv6_destroy_sock,
51         .setsockopt        = udpv6_setsockopt,
52         .getsockopt        = udpv6_getsockopt,
53         .sendmsg           = udpv6_sendmsg,
54         .recvmsg           = udpv6_recvmsg,
55         .hash              = udp_lib_hash,
56         .unhash            = udp_lib_unhash,
57         .get_port          = udp_v6_get_port,
58         .memory_allocated  = &udp_memory_allocated,
59         .sysctl_mem        = sysctl_udp_mem,
60         .obj_size          = sizeof(struct udp6_sock),
61         .h.udp_table       = &udplite_table,
62 #ifdef CONFIG_COMPAT
63         .compat_setsockopt = compat_udpv6_setsockopt,
64         .compat_getsockopt = compat_udpv6_getsockopt,
65 #endif
66 };
67
68 static struct inet_protosw udplite6_protosw = {
69         .type           = SOCK_DGRAM,
70         .protocol       = IPPROTO_UDPLITE,
71         .prot           = &udplitev6_prot,
72         .ops            = &inet6_dgram_ops,
73         .flags          = INET_PROTOSW_PERMANENT,
74 };
75
76 int __init udplitev6_init(void)
77 {
78         int ret;
79
80         ret = inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
81         if (ret)
82                 goto out;
83
84         ret = inet6_register_protosw(&udplite6_protosw);
85         if (ret)
86                 goto out_udplitev6_protocol;
87 out:
88         return ret;
89
90 out_udplitev6_protocol:
91         inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
92         goto out;
93 }
94
95 void udplitev6_exit(void)
96 {
97         inet6_unregister_protosw(&udplite6_protosw);
98         inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
99 }
100
101 #ifdef CONFIG_PROC_FS
102
103 static const struct file_operations udplite6_afinfo_seq_fops = {
104         .owner    = THIS_MODULE,
105         .open     = udp_seq_open,
106         .read     = seq_read,
107         .llseek   = seq_lseek,
108         .release  = seq_release_net
109 };
110
111 static struct udp_seq_afinfo udplite6_seq_afinfo = {
112         .name           = "udplite6",
113         .family         = AF_INET6,
114         .udp_table      = &udplite_table,
115         .seq_fops       = &udplite6_afinfo_seq_fops,
116         .seq_ops        = {
117                 .show           = udp6_seq_show,
118         },
119 };
120
121 static int __net_init udplite6_proc_init_net(struct net *net)
122 {
123         return udp_proc_register(net, &udplite6_seq_afinfo);
124 }
125
126 static void __net_exit udplite6_proc_exit_net(struct net *net)
127 {
128         udp_proc_unregister(net, &udplite6_seq_afinfo);
129 }
130
131 static struct pernet_operations udplite6_net_ops = {
132         .init = udplite6_proc_init_net,
133         .exit = udplite6_proc_exit_net,
134 };
135
136 int __init udplite6_proc_init(void)
137 {
138         return register_pernet_subsys(&udplite6_net_ops);
139 }
140
141 void udplite6_proc_exit(void)
142 {
143         unregister_pernet_subsys(&udplite6_net_ops);
144 }
145 #endif